mirror of
https://github.com/thrust26/6502-QR-code-generator.git
synced 2024-12-27 19:29:35 +00:00
added option to generate RS polynomial on-the-fly
This commit is contained in:
parent
731550443b
commit
d150cbc5af
159
QRCodeGen.inc
159
QRCodeGen.inc
@ -78,49 +78,6 @@ QR_TOTAL = QR_MAX_DATA + QR_DEGREE ; 44
|
||||
; 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
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _RS_REMAINDER
|
||||
;-----------------------------------------------------------
|
||||
.i = tmpVars+2
|
||||
.factor = tmpVars+3
|
||||
|
||||
; memset(result, 0, 16); // done in START_TEXT
|
||||
; for (int i = dataLen-1; i >= 0; i--) { // Polynomial division
|
||||
ldx #QR_MAX_DATA-1
|
||||
.loopI
|
||||
stx .i
|
||||
; uint8_t factor = data[i] ^ result[degree - 1];
|
||||
lda msgData,x
|
||||
eor remainder + QR_DEGREE - 1
|
||||
sta .factor
|
||||
; memmove(&result[1], &result[0], (size_t)(16 - 1) * sizeof(result[0]));
|
||||
ldx #QR_DEGREE-1
|
||||
.loopMove
|
||||
lda remainder-1,x
|
||||
sta remainder,x
|
||||
dex
|
||||
bne .loopMove
|
||||
; result[0] = 0;
|
||||
lda #0
|
||||
sta remainder
|
||||
; for (int j = 16-1; j >= 0; j--)
|
||||
ldx #QR_DEGREE-1
|
||||
.loopJ
|
||||
; result[j] ^= reedSolomonMultiply(generator[j], factor);
|
||||
lda Generator,x
|
||||
ldy .factor
|
||||
_RS_MULT
|
||||
eor remainder,x
|
||||
sta remainder,x
|
||||
; }
|
||||
dex
|
||||
bpl .loopJ
|
||||
; }
|
||||
ldx .i
|
||||
dex
|
||||
bpl .loopI
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
; Returns the product of the two given field elements modulo GF(2^8/0x11D).
|
||||
; All inputs are valid.
|
||||
@ -154,6 +111,114 @@ QR_TOTAL = QR_MAX_DATA + QR_DEGREE ; 44
|
||||
bpl .loopI
|
||||
ENDM
|
||||
|
||||
IF QR_GENERATE
|
||||
; Computes a Reed-Solomon ECC generator polynomial for degree 16, storing in result[0 : 16-1].
|
||||
; This is implemented as a lookup table too (Generator)
|
||||
;-----------------------------------------------------------
|
||||
MAC _RS_DIVISOR
|
||||
;-----------------------------------------------------------
|
||||
; E.g. 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
|
||||
; +A3x^7+41x^6+29x^5+E5x^4+62x^3+32x^2+24x+3B
|
||||
.root = tmpVars+2
|
||||
.i = tmpVars+3
|
||||
|
||||
; memset(qrGenerator, 1, 16);
|
||||
ldx #QR_DEGREE-1
|
||||
stx .i
|
||||
ldy #0
|
||||
.loopClear
|
||||
sty qrGenerator,x
|
||||
dex
|
||||
bne .loopClear
|
||||
; qrGenerator[0] = 1; // Start off with the monomial x^0
|
||||
iny
|
||||
sty qrGenerator
|
||||
; uint8_t root = 1;
|
||||
sty .root
|
||||
; for (int i = 0; i < degree; i++) {
|
||||
.loopI
|
||||
; // Multiply the current product by (x - r^i)
|
||||
; for (int j = degree-1; j >= 0; j--) {
|
||||
ldx #QR_DEGREE-1
|
||||
.loopJ
|
||||
; qrGenerator[j] = reedSolomonMultiply(qrGenerator[j], root);
|
||||
lda qrGenerator,x
|
||||
ldy .root
|
||||
jsr RSMult
|
||||
; if (j)
|
||||
dex
|
||||
bmi .skipEor
|
||||
; qrGenerator[j] ^= qrGenerator[j - 1];
|
||||
eor qrGenerator,x
|
||||
.skipEor
|
||||
sta qrGenerator+1,x
|
||||
txa
|
||||
bpl .loopJ
|
||||
; root = reedSolomonMultiply(root, 0x02);
|
||||
lda .root
|
||||
ldy #$02
|
||||
jsr RSMult
|
||||
sta .root
|
||||
dec .i
|
||||
bpl .loopI
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
RSMult SUBROUTINE
|
||||
_RS_MULT
|
||||
rts
|
||||
;-----------------------------------------------------------
|
||||
ENDIF ; /QR_GENERATE
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _RS_REMAINDER
|
||||
;-----------------------------------------------------------
|
||||
.i = tmpVars+2
|
||||
.factor = tmpVars+3
|
||||
|
||||
; memset(result, 0, 16); // done in START_TEXT
|
||||
; for (int i = dataLen-1; i >= 0; i--) { // Polynomial division
|
||||
ldx #QR_MAX_DATA-1
|
||||
.loopI
|
||||
stx .i
|
||||
; uint8_t factor = data[i] ^ result[degree - 1];
|
||||
lda msgData,x
|
||||
eor remainder + QR_DEGREE - 1
|
||||
sta .factor
|
||||
; memmove(&result[1], &result[0], (size_t)(16 - 1) * sizeof(result[0]));
|
||||
ldx #QR_DEGREE-1
|
||||
.loopMove
|
||||
lda remainder-1,x
|
||||
sta remainder,x
|
||||
dex
|
||||
bne .loopMove
|
||||
; result[0] = 0;
|
||||
lda #0
|
||||
sta remainder
|
||||
; for (int j = 16-1; j >= 0; j--)
|
||||
ldx #QR_DEGREE-1
|
||||
.loopJ
|
||||
; result[j] ^= reedSolomonMultiply(generator[j], factor);
|
||||
ldy .factor
|
||||
IF QR_GENERATE
|
||||
lda qrGenerator,x
|
||||
jsr RSMult
|
||||
ELSE
|
||||
lda Generator,x
|
||||
_RS_MULT
|
||||
ENDIF
|
||||
eor remainder,x
|
||||
sta remainder,x
|
||||
; }
|
||||
dex
|
||||
bpl .loopJ
|
||||
; }
|
||||
ldx .i
|
||||
dex
|
||||
bpl .loopI
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
; Draws the raw codewords (including data and ECC) onto the given QR Code. This requires the initial state of
|
||||
; the QR Code to be black at function modules and white at codeword modules (including unused remainder bits).
|
||||
@ -546,6 +611,11 @@ QR_TOTAL = QR_MAX_DATA + QR_DEGREE ; 44
|
||||
; This is the main macro to use!
|
||||
QRCodeCode
|
||||
|
||||
IF QR_GENERATE
|
||||
; generate the Reed-Solomon ECC generator polynomial
|
||||
RSDevisor
|
||||
_RS_DIVISOR
|
||||
ENDIF
|
||||
; calculate the ECC
|
||||
RSRemainder
|
||||
_RS_REMAINDER
|
||||
@ -677,6 +747,7 @@ FormatX2
|
||||
BitMask
|
||||
.byte $80, $40, $20, $10, $8, $4, $2, $1
|
||||
|
||||
IF QR_GENERATE = 0
|
||||
Generator ; data in reversed order!
|
||||
IF QR_DEGREE = 7
|
||||
.byte $75, $44, $0b, $a4, $9a, $7a, $7f
|
||||
@ -726,6 +797,8 @@ Generator ; data in reversed order!
|
||||
|
||||
QR_DEGREE = . - Generator ; verify data size
|
||||
|
||||
ENDIF ; /QR_GENERATE
|
||||
|
||||
ECHO "QR Code encoding data:", [. - QRCodeData]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - QRCodeData
|
||||
|
||||
|
@ -39,11 +39,13 @@ NTSC = 1 ; 0 = PAL50
|
||||
; QR Code Generator Switches
|
||||
QR_VERSION = 2 ; 1, 2 or 3 (TODO 1 and 3)
|
||||
QR_LEVEL = 1 ; 0 (L), 1 (M), 2 (Q) and 3 (H))
|
||||
QR_PADDING = 1 ; (+22) add padding bytes
|
||||
QR_PADDING = 1 ; (+22 bytes) add padding bytes (optional)
|
||||
QR_GENERATE = 1 ; (+~12 bytes) generates Reed-Solomon ECC generator polynomial on-the-fly
|
||||
; else uses built-in table
|
||||
|
||||
; Atari 2600 specific QR settings (set to 0 for other platforms)
|
||||
QR_OVERLAP = 1 ; overlaps input and output data to save RAM (defined for version 2 only!)
|
||||
QR_SINGLE_MASK = 0 ; (-255) if 1 uses only 1 of the 8 mask pattern
|
||||
QR_SINGLE_MASK = 0 ; (-255 bytes) if 1 uses only 1 of the 8 mask pattern
|
||||
|
||||
IF QR_VERSION = 1 || QR_VERSION = 3
|
||||
ECHO ""
|
||||
@ -97,6 +99,9 @@ firstMsl = qrCodeLst + QR_SIZE * 1
|
||||
grp1Lst = qrCodeLst + NUM_FIRST + QR_SIZE * 1
|
||||
grp0RLst = qrCodeLst + NUM_FIRST + QR_SIZE * 2
|
||||
CODE_LST_SIZE = . - qrCodeLst
|
||||
IF QR_GENERATE
|
||||
qrGenerator ds QR_DEGREE
|
||||
ENDIF
|
||||
;---------------------------------------
|
||||
; QR code total = 89/127 bytes
|
||||
|
||||
@ -218,8 +223,6 @@ CODE_LST_SIZE = . - qrCodeLst
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
include QRCodeGen.inc
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; R O M - C O D E
|
||||
@ -308,6 +311,8 @@ DrawScreen SUBROUTINE
|
||||
rts
|
||||
; DrawScreen
|
||||
|
||||
include QRCodeGen.inc
|
||||
|
||||
;---------------------------------------------------------------
|
||||
Start SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user