mirror of
https://github.com/thrust26/6502-QR-code-generator.git
synced 2024-12-26 13:31:27 +00:00
added more QR code combinations & generator polygons
improved code organization
This commit is contained in:
parent
247629475b
commit
b8ca4e495a
@ -4,7 +4,7 @@
|
||||
|
||||
BASE_ADR = $f800
|
||||
|
||||
DEGREE = 26
|
||||
DEGREE = 28
|
||||
POLY = $11d ; GF(2^8) is based on 9 bit polynomial
|
||||
; x^8 + x^4 + x^3 + x^2 + 1 = 0x11d
|
||||
|
||||
|
130
QRCodeGen.inc
130
QRCodeGen.inc
@ -1,3 +1,72 @@
|
||||
;===============================================================================
|
||||
; Q R C O D E C O N S T A N T S
|
||||
;===============================================================================
|
||||
|
||||
IF QR_VERSION = 1 ;{
|
||||
QR_SIZE = 21 ; 21x21 QR code
|
||||
QR_CAPACITY = 26
|
||||
IF QR_LEVEL = 0
|
||||
QR_DEGREE = 7 ; for version 1, level L QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 1
|
||||
QR_DEGREE = 10 ; for version 1, level M QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 2
|
||||
QR_DEGREE = 13 ; for version 1, level Q QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 3
|
||||
QR_DEGREE = 17 ; for version 1, level H QR codes
|
||||
ENDIF
|
||||
ENDIF ;}
|
||||
|
||||
IF QR_VERSION = 2
|
||||
QR_SIZE = 25 ; 25x25 QR code
|
||||
QR_CAPACITY = 44
|
||||
IF QR_LEVEL = 0
|
||||
QR_DEGREE = 10 ; for version 2, level L QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 1
|
||||
QR_DEGREE = 16 ; for version 2, level M QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 2
|
||||
QR_DEGREE = 22 ; for version 2, level Q QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 3
|
||||
QR_DEGREE = 28 ; for version 2, level H QR codes
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IF QR_VERSION = 3 ;{
|
||||
QR_SIZE = 29 ; 29x29 QR code
|
||||
QR_CAPACITY = 70
|
||||
IF QR_LEVEL = 0
|
||||
QR_DEGREE = 15 ; for version 3, level L QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 1
|
||||
QR_DEGREE = 26 ; for version 3, level M QR codes
|
||||
ENDIF
|
||||
IF QR_LEVEL = 2 || QR_LEVEL = 3
|
||||
ECHO ""
|
||||
ECHO "ERROR: Version 3, Level", [QR_LEVEL]d, "not supported"
|
||||
ERR
|
||||
ENDIF
|
||||
ENDIF ;}
|
||||
|
||||
QR_MAX_DATA = QR_CAPACITY - QR_DEGREE
|
||||
|
||||
QR_MODE = %0100 ; byte mode
|
||||
QR_POLY = $11d ; GF(2^8) is based on 9 bit polynomial
|
||||
; x^8 + x^4 + x^3 + x^2 + 1 = 0x11d
|
||||
QR_FORMATS = 15 ; 15 type information bits
|
||||
|
||||
QR_MAX_MSG = QR_MAX_DATA - 2
|
||||
QR_TOTAL = QR_MAX_DATA + QR_DEGREE ; 44
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; Q R C O D E M A C R O S
|
||||
;===============================================================================
|
||||
|
||||
; The following code has been partially converted from the C code of the
|
||||
; QR code generator found at https://github.com/nayuki/QR-Code-generator
|
||||
|
||||
@ -9,15 +78,15 @@
|
||||
|
||||
; memset(result, 0, 16); // done in START_TEXT
|
||||
; for (int i = dataLen-1; i >= 0; i--) { // Polynomial division
|
||||
ldx #MAX_DATA-1
|
||||
ldx #QR_MAX_DATA-1
|
||||
.loopI
|
||||
stx .i
|
||||
; uint8_t factor = data[i] ^ result[degree - 1];
|
||||
lda msgData,x
|
||||
eor remainder + DEGREE - 1
|
||||
eor remainder + QR_DEGREE - 1
|
||||
sta .factor
|
||||
; memmove(&result[1], &result[0], (size_t)(16 - 1) * sizeof(result[0]));
|
||||
ldx #DEGREE-1
|
||||
ldx #QR_DEGREE-1
|
||||
.loopMove
|
||||
lda remainder-1,x
|
||||
sta remainder,x
|
||||
@ -27,7 +96,7 @@
|
||||
lda #0
|
||||
sta remainder
|
||||
; for (int j = 16-1; j >= 0; j--)
|
||||
ldx #DEGREE-1
|
||||
ldx #QR_DEGREE-1
|
||||
.loopJ
|
||||
; result[j] ^= reedSolomonMultiply(generator[j], factor);
|
||||
lda Generator,x
|
||||
@ -65,7 +134,7 @@
|
||||
; z = (uint8_t)((z << 1) ^ ((z >> 7) * 0x11D));
|
||||
asl
|
||||
bcc .skipEorPoly
|
||||
eor #<POLY
|
||||
eor #<QR_POLY
|
||||
.skipEorPoly
|
||||
; z ^= ((y >> i) & 1) * x;
|
||||
asl .y
|
||||
@ -100,7 +169,7 @@
|
||||
; ldx #0
|
||||
; 2600 code has data in reversed order
|
||||
stx .iBit
|
||||
lda #TOTAL_LEN-1
|
||||
lda #QR_TOTAL-1
|
||||
sta .iByte
|
||||
; // Do the funny zigzag scan
|
||||
; Note: 2600 code has .right1 increased by 1
|
||||
@ -356,7 +425,7 @@
|
||||
;-----------------------------------------------------------
|
||||
.idx = tmpVars
|
||||
|
||||
ldy #NUM_FORMAT-1
|
||||
ldy #QR_FORMATS-1
|
||||
.loopFormat
|
||||
sty .idx
|
||||
cpy #8
|
||||
@ -402,20 +471,20 @@
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #(MODE << 4)
|
||||
; (MODE << 4) | (MSG_LEN >> 4)
|
||||
sta msgData + MAX_DATA - 1
|
||||
ora #(QR_MODE << 4)
|
||||
; (QR_MODE << 4) | (MSG_LEN >> 4)
|
||||
sta msgData + QR_MAX_DATA - 1
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
; (MSG_LEN << 4)
|
||||
sta msgData + MAX_DATA - 2
|
||||
lda #MAX_DATA - 3
|
||||
sta msgData + QR_MAX_DATA - 2
|
||||
lda #QR_MAX_DATA - 3
|
||||
sta msgIdx
|
||||
; clear the remaining data buffer
|
||||
ldx #TOTAL_LEN-3
|
||||
ldx #QR_TOTAL-3
|
||||
lda #0
|
||||
.loopClear
|
||||
sta data,x
|
||||
@ -450,7 +519,7 @@
|
||||
IF QR_PADDING
|
||||
.msgLen = tmpVars
|
||||
; pad with optional filler bytes (QR code works without too)
|
||||
lda #MAX_MSG - 1
|
||||
lda #QR_MAX_MSG - 1
|
||||
sec
|
||||
sbc .msgLen
|
||||
bcc .noPadding
|
||||
@ -566,18 +635,22 @@ BitMask
|
||||
.byte $80, $40, $20, $10, $8, $4, $2, $1
|
||||
|
||||
Generator ; data in reversed order!
|
||||
IF DEGREE = 7
|
||||
IF QR_DEGREE = 7
|
||||
.byte $75, $44, $0b, $a4, $9a, $7a, $7f
|
||||
ENDIF
|
||||
IF DEGREE = 10
|
||||
IF QR_DEGREE = 10
|
||||
.byte $c1, $9d, $71, $5f, $5e, $c7, $6f, $9f
|
||||
.byte $c2, $d8
|
||||
ENDIF
|
||||
IF DEGREE = 15
|
||||
IF QR_DEGREE = 13
|
||||
.byte $87, $84, $53, $2b, $2e, $0d, $34, $11
|
||||
.byte $b1, $11, $e3, $49, $89
|
||||
ENDIF
|
||||
IF QR_DEGREE = 15
|
||||
.byte $1a, $86, $20, $97, $84, $8b, $69, $69
|
||||
.byte $0a, $4a, $70, $a3, $6f, $c4, $1d
|
||||
ENDIF
|
||||
IF DEGREE = 16
|
||||
IF QR_DEGREE = 16
|
||||
; Reed-Solomon ECC generator polynomial for degree 16
|
||||
; g(x)=(x+1)(x+?)(x+?^2)(x+?^3)...(x+?^15)
|
||||
; = x^16+3bx^15+0dx^14+68x^13+bdx^12+44x^11+d1x^10+1e^x9+08x^8
|
||||
@ -585,13 +658,30 @@ Generator ; data in reversed order!
|
||||
.byte $3b, $24, $32, $62, $e5, $29, $41, $a3
|
||||
.byte $08, $1e, $d1, $44, $bd, $68, $0d, $3b
|
||||
ENDIF
|
||||
IF DEGREE = 26
|
||||
IF QR_DEGREE = 17
|
||||
.byte $4f, $63, $7d, $35, $55, $86, $8f, $29
|
||||
.byte $f9, $53, $c5, $16, $77, $78, $53, $42
|
||||
.byte $77
|
||||
ENDIF
|
||||
IF QR_DEGREE = 22
|
||||
.byte $f5, $91, $1a, $e6, $da, $56, $fd, $43
|
||||
.byte $7b, $1d, $89, $1c, $28, $45, $bd, $13
|
||||
.byte $f4, $b6, $b0, $83, $b3, $59
|
||||
ENDIF
|
||||
IF QR_DEGREE = 26
|
||||
.byte $5e, $2b, $4d, $92, $90, $46, $44, $87
|
||||
.byte $2a, $e9, $75, $d1, $28, $91, $18, $ce
|
||||
.byte $38, $4d, $98, $c7, $62, $88, $04, $b7
|
||||
.byte $44, $f6
|
||||
ENDIF
|
||||
DEGREE = . - Generator ; verify data
|
||||
IF QR_DEGREE = 28
|
||||
.byte $c5, $3a, $4a, $b0, $93, $79, $64, $b5
|
||||
.byte $7f, $e9, $77, $75, $38, $f7, $0c, $a7
|
||||
.byte $29, $64, $ae, $67, $96, $d0, $fb, $12
|
||||
.byte $0d, $1c, $09, $fc
|
||||
ENDIF
|
||||
|
||||
QR_DEGREE = . - Generator ; verify data
|
||||
|
||||
ECHO "QR Code encoding data:", [. - QRCodeData]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - QRCodeData
|
||||
|
@ -34,67 +34,24 @@ BASE_ADR = $f000
|
||||
|
||||
NTSC = 1
|
||||
|
||||
; QR Switches
|
||||
; QR Code Generator Switches
|
||||
QR_VERSION = 2 ; 1, 2 or 3 (TODO 1 and 3)
|
||||
QR_LEVEL = 1 ; 0 (L) or 1 (M) (TODO Q and H)
|
||||
QR_LEVEL = 1 ; 0 (L), 1 (M), 2 (Q) and 3 (H)
|
||||
QR_OVERLAP = 1 ; overlaps input and output data to save RAM (0 not tested!)
|
||||
QR_SINGLE_MASK = 0 ; (-156) if 1 uses only 1 of the 8 mask pattern
|
||||
QR_PADDING = 1 ; (+22) add padding bytes
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; C O N S T A N T S
|
||||
;===============================================================================
|
||||
|
||||
; QR code constants
|
||||
IF QR_VERSION = 1 ;{
|
||||
QR_SIZE = 21 ; 21x21 QR code
|
||||
IF QR_LEVEL = 0
|
||||
DEGREE = 7 ; for version 1, level L QR codes
|
||||
MAX_DATA = 17+2
|
||||
ELSE
|
||||
DEGREE = 10 ; for version 1, level M QR codes
|
||||
MAX_DATA = 14+2
|
||||
ENDIF
|
||||
ENDIF ;}
|
||||
IF QR_VERSION = 2
|
||||
QR_SIZE = 25 ; 25x25 QR code
|
||||
IF QR_LEVEL = 0
|
||||
DEGREE = 10 ; for version 2, level L QR codes
|
||||
MAX_DATA = 32+2
|
||||
ELSE
|
||||
DEGREE = 16 ; for version 2, level M QR codes
|
||||
MAX_DATA = 26+2
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF QR_VERSION = 3 ;{
|
||||
QR_SIZE = 29 ; 29x29 QR code
|
||||
IF QR_LEVEL = 0
|
||||
DEGREE = 15 ; for version 3, level L QR codes
|
||||
MAX_DATA = 53+2
|
||||
ELSE
|
||||
DEGREE = 26 ; for version 3, level M QR codes
|
||||
MAX_DATA = 42+2
|
||||
ENDIF
|
||||
ENDIF ;}
|
||||
|
||||
IF QR_VERSION = 1 || QR_VERSION = 3
|
||||
ECHO ""
|
||||
ECHO "ERROR: Version", [QR_VERSION]d, "unsupported by demo code"
|
||||
ERR
|
||||
ENDIF
|
||||
|
||||
MODE = %0100 ; byte mode
|
||||
POLY = $11d ; GF(2^8) is based on 9 bit polynomial
|
||||
; x^8 + x^4 + x^3 + x^2 + 1 = 0x11d
|
||||
NUM_FORMAT = 15 ; 15 type information bits
|
||||
|
||||
MAX_MSG = MAX_DATA - 2
|
||||
TOTAL_LEN = MAX_DATA + DEGREE ; 44
|
||||
;===============================================================================
|
||||
; C O N S T A N T S
|
||||
;===============================================================================
|
||||
|
||||
NUM_FIRST = 1 ; left top 9 and bottom 8 bits are fixed!
|
||||
|
||||
; other constants
|
||||
RND_EOR_VAL = $b4
|
||||
|
||||
_QR_TOTAL SET 0
|
||||
@ -119,14 +76,14 @@ msgIdx = tmpVars + 3
|
||||
qrPattern .byte
|
||||
ENDIF
|
||||
;---------------------------------------
|
||||
data ds TOTAL_LEN ; 44 bytes
|
||||
remainder = data ; (DEGREE = 16 bytes)
|
||||
msgData = data + DEGREE ; (MAX_DATA = 28 bytes)
|
||||
data ds QR_TOTAL ; 44 bytes
|
||||
remainder = data ; (QR_DEGREE = 16 bytes)
|
||||
msgData = data + QR_DEGREE ; (QR_MAX_DATA = 28 bytes)
|
||||
;- - - - - - - - - - - - - - - - - - - -
|
||||
; The QR code overlaps the data! It overwrites the data while being drawn.
|
||||
IF QR_OVERLAP
|
||||
qrCodeLst = data + 6 ; all but 6 bytes overlap (version 2 only!)
|
||||
ds NUM_FIRST + QR_SIZE*3 - TOTAL_LEN + 6 ; 38 bytes
|
||||
ds NUM_FIRST + QR_SIZE*3 - QR_TOTAL + 6 ; 38 bytes
|
||||
ELSE
|
||||
qrCodeLst ds NUM_FIRST + QR_SIZE*3 ; 76 bytes
|
||||
ENDIF
|
||||
@ -134,7 +91,7 @@ grp0LLst = qrCodeLst + QR_SIZE * 0
|
||||
firstMsl = qrCodeLst + QR_SIZE * 1
|
||||
grp1Lst = qrCodeLst + NUM_FIRST + QR_SIZE * 1
|
||||
grp0RLst = qrCodeLst + NUM_FIRST + QR_SIZE * 2
|
||||
QR_LST_SIZE = . - qrCodeLst
|
||||
CODE_LST_SIZE = . - qrCodeLst
|
||||
;---------------------------------------
|
||||
; QR code total = 89/127 bytes
|
||||
|
||||
@ -188,7 +145,7 @@ QR_LST_SIZE = . - qrCodeLst
|
||||
;-----------------------------------------------------------
|
||||
MAC _BLACK_FUNC
|
||||
;-----------------------------------------------------------
|
||||
ldx #QR_LST_SIZE-1
|
||||
ldx #CODE_LST_SIZE-1
|
||||
.loopBlack
|
||||
lda BlackGfx,x
|
||||
sta qrCodeLst,x
|
||||
@ -235,7 +192,7 @@ QR_LST_SIZE = . - qrCodeLst
|
||||
;-----------------------------------------------------------
|
||||
MAC _DRAW_FUNC
|
||||
;-----------------------------------------------------------
|
||||
ldx #QR_LST_SIZE-1
|
||||
ldx #CODE_LST_SIZE-1
|
||||
.loopBlack
|
||||
lda qrCodeLst,x
|
||||
ora BlackGfx,x
|
||||
|
Loading…
Reference in New Issue
Block a user