mirror of
https://github.com/thrust26/6502-QR-code-generator.git
synced 2024-09-18 19:03:19 +00:00
Add files via upload
This commit is contained in:
parent
0bbab8727d
commit
3be452938c
136
GenPoly.asm
Normal file
136
GenPoly.asm
Normal file
@ -0,0 +1,136 @@
|
||||
processor 6502
|
||||
|
||||
BASE_ADR = $f800
|
||||
|
||||
DEGREE = 26
|
||||
POLY = $11d ; GF(2^8) is based on 9 bit polynomial
|
||||
; x^8 + x^4 + x^3 + x^2 + 1 = 0x11d
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; Z P - V A R I A B L E S
|
||||
;===============================================================================
|
||||
|
||||
SEG.U variables
|
||||
ORG $80
|
||||
|
||||
tmpVars ds 4
|
||||
|
||||
ALIGN 16
|
||||
|
||||
result ds DEGREE
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; R O M - C O D E
|
||||
;===============================================================================
|
||||
SEG Bank0
|
||||
ORG BASE_ADR
|
||||
|
||||
;---------------------------------------------------------------
|
||||
Start SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
cld ; Clear BCD math bit.
|
||||
lda #0
|
||||
tax
|
||||
dex
|
||||
txs
|
||||
.clearLoop:
|
||||
tsx
|
||||
pha
|
||||
bne .clearLoop
|
||||
|
||||
RS_DIVISOR
|
||||
.wait
|
||||
jmp .wait
|
||||
|
||||
|
||||
; Computes a Reed-Solomon ECC generator polynomial for degree 16, storing in result[0 : 16-1].
|
||||
; This is now implemented as a lookup table (Generator)
|
||||
; 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
|
||||
MAC RS_DIVISOR
|
||||
.root = tmpVars+2
|
||||
.i = tmpVars+3
|
||||
|
||||
; memset(result, 0, 16);
|
||||
ldx #DEGREE-2
|
||||
ldy #0
|
||||
.loopClear
|
||||
sty result,x
|
||||
dex
|
||||
bpl .loopClear
|
||||
; result[16 - 1] = 1; // Start off with the monomial x^0
|
||||
iny
|
||||
sty result + DEGREE - 1
|
||||
; uint8_t root = 1;
|
||||
sty .root
|
||||
; for (int i = 0; i < 16; i++) {
|
||||
lda #DEGREE-1 ; just loop 16 times
|
||||
sta .i
|
||||
.loopI
|
||||
; // Multiply the current product by (x - r^i)
|
||||
; for (int j = 0; j < 16; j++) {
|
||||
ldx #0
|
||||
.loopJ
|
||||
; result[j] = reedSolomonMultiply(result[j], root);
|
||||
lda result,x
|
||||
ldy .root
|
||||
; RS_MULT
|
||||
jsr RSMult
|
||||
; if (j != 16 - 1)
|
||||
cpx #DEGREE - 1
|
||||
bcs .skipEor
|
||||
; result[j] ^= result[j + 1];
|
||||
eor result+1,x
|
||||
.skipEor
|
||||
sta result,x
|
||||
inx
|
||||
cpx #DEGREE
|
||||
bcc .loopJ
|
||||
; root = reedSolomonMultiply(root, 0x02);
|
||||
lda .root
|
||||
ldy #$02
|
||||
; RS_MULT
|
||||
jsr RSMult
|
||||
sta .root
|
||||
dec .i
|
||||
bpl .loopI
|
||||
ENDM
|
||||
|
||||
; Returns the product of the two given field elements modulo GF(2^8/0x11D).
|
||||
; All inputs are valid.
|
||||
RSMult SUBROUTINE
|
||||
; Russian peasant multiplication (x * y)
|
||||
; Input: A = x, Y = y
|
||||
; Result: A
|
||||
.x = tmpVars
|
||||
.y = tmpVars+1
|
||||
|
||||
sta .x
|
||||
sty .y
|
||||
; uint8_t z = 0;
|
||||
lda #0
|
||||
; for (int i = 7; i >= 0; i--) {
|
||||
ldy #7
|
||||
.loopI
|
||||
; z = (uint8_t)((z << 1) ^ ((z >> 7) * 0x11D));
|
||||
asl
|
||||
bcc .skipEorPoly
|
||||
eor #<POLY
|
||||
.skipEorPoly
|
||||
; z ^= ((y >> i) & 1) * x;
|
||||
asl .y
|
||||
bcc .skipEorX
|
||||
eor .x
|
||||
.skipEorX
|
||||
dey
|
||||
bpl .loopI
|
||||
rts
|
||||
|
||||
.byte "JTZ"
|
||||
|
||||
org BASE_ADR + $7fc
|
||||
.word Start
|
||||
.word Start
|
600
QRCodeGen.inc
Normal file
600
QRCodeGen.inc
Normal file
@ -0,0 +1,600 @@
|
||||
; 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 #MAX_DATA-1
|
||||
.loopI
|
||||
stx .i
|
||||
; uint8_t factor = data[i] ^ result[degree - 1];
|
||||
lda msgData,x
|
||||
eor remainder + DEGREE - 1
|
||||
sta .factor
|
||||
; memmove(&result[1], &result[0], (size_t)(16 - 1) * sizeof(result[0]));
|
||||
ldx #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 #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.
|
||||
MAC _RS_MULT
|
||||
;-----------------------------------------------------------
|
||||
; Russian peasant multiplication (x * y)
|
||||
; Input: A = x, Y = y
|
||||
; Result: A
|
||||
.x = tmpVars
|
||||
.y = tmpVars+1
|
||||
|
||||
sta .x
|
||||
sty .y
|
||||
; uint8_t z = 0;
|
||||
lda #0
|
||||
; for (int i = 7; i >= 0; i--) {
|
||||
ldy #7
|
||||
.loopI
|
||||
; z = (uint8_t)((z << 1) ^ ((z >> 7) * 0x11D));
|
||||
asl
|
||||
bcc .skipEorPoly
|
||||
eor #<POLY
|
||||
.skipEorPoly
|
||||
; z ^= ((y >> i) & 1) * x;
|
||||
asl .y
|
||||
bcc .skipEorX
|
||||
eor .x
|
||||
.skipEorX
|
||||
; }
|
||||
dey
|
||||
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).
|
||||
MAC _DRAW_CODEWORDS
|
||||
;-----------------------------------------------------------
|
||||
; Note: This part has the maximum RAM usage
|
||||
.right = tmpVars+0
|
||||
.vert = tmpVars+1
|
||||
.j = tmpVars+2
|
||||
.y = tmpVars+3
|
||||
.iBit = tmpVars+4
|
||||
.iByte = tmpVars+5
|
||||
|
||||
; blacken the (right) function modules in the bitmap
|
||||
IF QR_OVERLAP
|
||||
_BLACK_RIGHT ; returns with X = 0
|
||||
ELSE
|
||||
_BLACK_FUNC ; returns with X = 0
|
||||
ENDIF
|
||||
; int i = 0; // Bit index into the data
|
||||
; 2600 code has data in reversed order
|
||||
stx .iBit
|
||||
lda #TOTAL_LEN-1
|
||||
sta .iByte
|
||||
; // Do the funny zigzag scan
|
||||
; for (int right = qrsize - 1; right >= 1; right -= 2) { // Index of right column in each column pair
|
||||
ldy #QR_SIZE - 1
|
||||
.loopRight
|
||||
; if (right == 6)
|
||||
cpy #6
|
||||
bne .not6
|
||||
; right = 5;
|
||||
dey ; skip the timing column
|
||||
.not6
|
||||
sty .right
|
||||
IF QR_OVERLAP
|
||||
; overwrite shared data
|
||||
cpy #16
|
||||
bne .skipBlackMiddle
|
||||
; blacken the middle function modules in the bitmap
|
||||
_BLACK_MIDDLE
|
||||
.skipBlackMiddle
|
||||
cpy #8
|
||||
bne .skipBlackLeft
|
||||
; blacken the left function modules in the bitmap
|
||||
_BLACK_LEFT
|
||||
.skipBlackLeft
|
||||
ENDIF
|
||||
; for (int vert = 0; vert < qrsize; vert++) { // Vertical counter
|
||||
ldy #QR_SIZE-1
|
||||
.loopVert
|
||||
sty .vert
|
||||
; for (int j = 0; j < 2; j++) {
|
||||
ldy #-1
|
||||
.loopJ
|
||||
iny
|
||||
sty .j
|
||||
; bool upward = ((right + 1) & 2) != 0; // 2600 code works in reverse
|
||||
ldx .vert
|
||||
lda .right
|
||||
clc
|
||||
adc #1
|
||||
and #$2
|
||||
bne .notUp
|
||||
; int y = upward ? qrsize - 1 - vert : vert; // Actual y coordinate
|
||||
lda #QR_SIZE-1
|
||||
sec
|
||||
sbc .vert
|
||||
tax
|
||||
.notUp
|
||||
stx .y
|
||||
; int x = right - j; // Actual x coordinate
|
||||
lda .right
|
||||
sec
|
||||
sbc .j
|
||||
; sta .x
|
||||
tay
|
||||
; if (!getModule(qrcode, x, y) && i < dataLen * 8) {
|
||||
; ldy .x
|
||||
; ldx .y
|
||||
jsr CheckPixel
|
||||
bne .skipPixel
|
||||
ldx .iByte
|
||||
bmi .skipPixel
|
||||
; bool black = getBit(data[i >> 3], 7 - (i & 7));
|
||||
lda data,x
|
||||
ldx .iBit
|
||||
and BitMask,x
|
||||
beq .skipInv
|
||||
; setModule(qrcode, x, y, black);
|
||||
; ldy .x
|
||||
ldx .y
|
||||
jsr InvertPixel
|
||||
.skipInv
|
||||
; i++;
|
||||
ldy .iBit
|
||||
iny
|
||||
tya
|
||||
and #$07
|
||||
sta .iBit
|
||||
bne .skipByte
|
||||
dec .iByte
|
||||
.skipByte
|
||||
; }
|
||||
.skipPixel
|
||||
ldy .j
|
||||
beq .loopJ
|
||||
; } // for j
|
||||
ldy .vert
|
||||
dey
|
||||
bpl .loopVert
|
||||
; } // for vert
|
||||
ldy .right
|
||||
dey
|
||||
dey
|
||||
bpl .loopRight
|
||||
; } // for right
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _APPLY_MASK
|
||||
;-----------------------------------------------------------
|
||||
IF QR_SINGLE_MASK
|
||||
.y = tmpVars
|
||||
ldx #QR_SIZE - 1
|
||||
.loopY
|
||||
stx .y
|
||||
ldy #QR_SIZE - 1
|
||||
.loopX
|
||||
; 0: (x + y) % 2 == 0
|
||||
tya
|
||||
eor .y
|
||||
lsr
|
||||
bcs .skipInvert
|
||||
jsr InvertPixel
|
||||
.skipInvert
|
||||
dey
|
||||
bpl .loopX
|
||||
dex
|
||||
bpl .loopY
|
||||
ELSE
|
||||
.y = tmpVars
|
||||
;.x = tmpVars+2
|
||||
.xMod3 = tmpVars+1
|
||||
.yMod3 = tmpVars+2
|
||||
.xDiv3 = tmpVars+3
|
||||
.tmp = tmpVars+4
|
||||
|
||||
lda #0
|
||||
sta .yMod3
|
||||
ldx #QR_SIZE - 1
|
||||
.loopY
|
||||
stx .y
|
||||
lda #0
|
||||
sta .xMod3
|
||||
sta .xDiv3
|
||||
ldy #QR_SIZE - 1
|
||||
.loopX
|
||||
; sty .x
|
||||
lda qrPattern
|
||||
bne .not0
|
||||
; 0: (x + y) % 2 == 0
|
||||
tya
|
||||
eor .y
|
||||
bpl .checkMod2
|
||||
|
||||
.not0
|
||||
cmp #4
|
||||
bne .not4
|
||||
; 4: (x / 3 + y / 2) % 2 == 0
|
||||
lda .y
|
||||
lsr
|
||||
adc .xDiv3
|
||||
bpl .checkMod2
|
||||
|
||||
.not4
|
||||
bcs .above4
|
||||
|
||||
lsr
|
||||
bcs .not2
|
||||
; 2: x % 3 == 0
|
||||
lda .xMod3
|
||||
beq .invert
|
||||
bne .skipInvert
|
||||
|
||||
.not2
|
||||
bne .is3
|
||||
; 1: y % 2 == 0
|
||||
txa
|
||||
bpl .checkMod2
|
||||
|
||||
.is3
|
||||
; 3: (x + y) % 3 == 0
|
||||
lda .xMod3
|
||||
; sec
|
||||
sbc .yMod3
|
||||
beq .invert
|
||||
bne .skipInvert
|
||||
|
||||
.above4
|
||||
cmp #6
|
||||
beq .is6
|
||||
bcs .is7
|
||||
.is6
|
||||
php
|
||||
; 5: x * y % 2 + x * y % 3 == 0
|
||||
; 6: (x * y % 2 + x * y % 3) % 2 == 0
|
||||
lda .xMod3
|
||||
beq .modEven56
|
||||
lda .yMod3
|
||||
beq .modEven56
|
||||
clc
|
||||
adc .xMod3
|
||||
BIT_W
|
||||
.modEven56
|
||||
lda #0
|
||||
sta .tmp
|
||||
tya
|
||||
lsr
|
||||
bcc .even56
|
||||
txa
|
||||
lsr
|
||||
bcc .even56
|
||||
inc .tmp
|
||||
.even56
|
||||
plp
|
||||
lda .tmp
|
||||
bcs .checkMod2
|
||||
beq .invert
|
||||
bne .skipInvert
|
||||
|
||||
.is7
|
||||
; 7: ((x + y) % 2 + x * y % 3) % 2 == 0
|
||||
tya
|
||||
eor .y
|
||||
sta .tmp
|
||||
lda .xMod3
|
||||
beq .modEven7
|
||||
lda .yMod3
|
||||
beq .modEven7
|
||||
clc
|
||||
adc .xMod3
|
||||
adc .tmp
|
||||
sta .tmp
|
||||
.modEven7
|
||||
lda .tmp
|
||||
.checkMod2
|
||||
lsr
|
||||
bcs .skipInvert
|
||||
.invert
|
||||
jsr InvertPixel
|
||||
.skipInvert
|
||||
; next X
|
||||
dec .xMod3
|
||||
bpl .xMod3OK
|
||||
lda #2
|
||||
sta .xMod3
|
||||
inc .xDiv3
|
||||
.xMod3OK
|
||||
dey
|
||||
bpl .loopX
|
||||
; next Y
|
||||
dec .yMod3
|
||||
bpl .yMod3OK
|
||||
lda #2
|
||||
sta .yMod3
|
||||
.yMod3OK
|
||||
dex
|
||||
bmi .exitLoopY
|
||||
jmp .loopY
|
||||
|
||||
.exitLoopY
|
||||
ENDIF ; !QR_SINGLE_MASK
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _DRAW_FORMAT
|
||||
;-----------------------------------------------------------
|
||||
.idx = tmpVars
|
||||
|
||||
ldy #NUM_FORMAT-1
|
||||
.loopFormat
|
||||
sty .idx
|
||||
cpy #8
|
||||
IF QR_SINGLE_MASK
|
||||
lda #%10101000
|
||||
and BitMask,y
|
||||
bcc .lowFormat
|
||||
lda #%00100100
|
||||
ELSE
|
||||
ldx qrPattern
|
||||
lda FormatLo,x
|
||||
and BitMask,y
|
||||
bcc .lowFormat
|
||||
lda FormatHi,x
|
||||
ENDIF
|
||||
and BitMask-8,y
|
||||
.lowFormat
|
||||
beq .skipFormat
|
||||
ldx FormatY1,y
|
||||
lda FormatX1,y
|
||||
tay
|
||||
jsr InvertPixel
|
||||
ldy .idx
|
||||
ldx FormatY2,y
|
||||
lda FormatX2,y
|
||||
tay
|
||||
jsr InvertPixel
|
||||
ldy .idx
|
||||
.skipFormat
|
||||
dey
|
||||
bpl .loopFormat
|
||||
ENDM
|
||||
|
||||
; ********** The user macros start here: **********
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC START_MSG
|
||||
;-----------------------------------------------------------
|
||||
; A = message length
|
||||
; add mode and length to message data
|
||||
tax
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #(MODE << 4)
|
||||
; (MODE << 4) | (MSG_LEN >> 4)
|
||||
sta msgData + MAX_DATA - 1
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
; (MSG_LEN << 4)
|
||||
sta msgData + MAX_DATA - 2
|
||||
lda #MAX_DATA - 3
|
||||
sta msgIdx
|
||||
; clear the remaining data buffer
|
||||
ldx #TOTAL_LEN-3
|
||||
lda #0
|
||||
.loopClear
|
||||
sta data,x
|
||||
dex
|
||||
bpl .loopClear
|
||||
ENDM
|
||||
|
||||
;---------------------------------------------------------------
|
||||
MAC ADD_MSG_BYTE
|
||||
;---------------------------------------------------------------
|
||||
; A = byte to add
|
||||
ldx msgIdx
|
||||
pha
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora msgData + 1,x
|
||||
sta msgData + 1,x
|
||||
pla
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta msgData,x
|
||||
dec msgIdx
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC STOP_MSG
|
||||
;-----------------------------------------------------------
|
||||
IF QR_PADDING
|
||||
.msgLen = tmpVars
|
||||
; pad with optional filler bytes (QR code works without too)
|
||||
lda #MAX_MSG - 1
|
||||
sec
|
||||
sbc .msgLen
|
||||
bcc .noPadding
|
||||
tax
|
||||
.loopPadding
|
||||
lda #$ec ; defined by QR standard
|
||||
sta msgData,x
|
||||
dex
|
||||
bmi .noPadding
|
||||
lda #$11 ; defined by QR standard
|
||||
sta msgData,x
|
||||
dex
|
||||
bpl .loopPadding
|
||||
.noPadding
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC GEN_QR_CODE
|
||||
;-----------------------------------------------------------
|
||||
; This is the main macro to use!
|
||||
QRCodeCode
|
||||
|
||||
; calculate the ECC
|
||||
RSRemainder
|
||||
_RS_REMAINDER
|
||||
; draw the code words onto the bitmap
|
||||
DrawCodes
|
||||
_DRAW_CODEWORDS
|
||||
; apply the pattern mask
|
||||
ApplyMask
|
||||
_APPLY_MASK
|
||||
; blacken the function modules in the bitmap again
|
||||
; and draw the function modules in the bitmap
|
||||
DrawFunc
|
||||
_DRAW_FUNC
|
||||
; draw the format bits
|
||||
DrawFormat
|
||||
_DRAW_FORMAT
|
||||
|
||||
ECHO "QR Code encoding code:", [. - QRCodeCode]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - QRCodeCode
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC QR_CODE_DATA
|
||||
;-----------------------------------------------------------
|
||||
; Add this to your code's data area
|
||||
QRCodeData
|
||||
|
||||
; Format Information Strings
|
||||
IF QR_SINGLE_MASK = 0
|
||||
IF QR_LEVEL = 0 ; L
|
||||
FormatLo
|
||||
.byte %11101111
|
||||
.byte %11100101
|
||||
.byte %11111011
|
||||
.byte %11110001
|
||||
.byte %11001100
|
||||
.byte %11000110
|
||||
.byte %11011000
|
||||
.byte %11010010
|
||||
FormatHi
|
||||
.byte %10001000
|
||||
.byte %11100110
|
||||
.byte %01010100
|
||||
.byte %00111010
|
||||
.byte %01011110
|
||||
.byte %00110000
|
||||
.byte %10000010
|
||||
.byte %11101100
|
||||
ENDIF
|
||||
IF QR_LEVEL = 1 ; M
|
||||
FormatLo
|
||||
.byte %10101000
|
||||
.byte %10100010
|
||||
.byte %10111100
|
||||
.byte %10110110
|
||||
.byte %10001011
|
||||
.byte %10000001
|
||||
.byte %10011111
|
||||
.byte %10010101
|
||||
FormatHi
|
||||
.byte %00100100
|
||||
.byte %01001010
|
||||
.byte %11111000
|
||||
.byte %10010110
|
||||
.byte %11110010
|
||||
.byte %10011100
|
||||
.byte %00101110
|
||||
.byte %01000000
|
||||
ENDIF
|
||||
; TODO: levels Q and H
|
||||
ENDIF
|
||||
|
||||
; position of the 15 type information bits
|
||||
FormatX1
|
||||
.byte 0, 1, 2, 3, 4, 5, 7, 8
|
||||
.byte 8, 8, 8, 8, 8, 8, 8
|
||||
FormatY2
|
||||
.byte 0, 1, 2, 3, 4, 5, 6
|
||||
; ds 8, QR_SIZE-9 ; shared
|
||||
FormatY1
|
||||
ds 8, QR_SIZE-9
|
||||
.byte QR_SIZE-8, QR_SIZE-6, QR_SIZE-5, QR_SIZE-4
|
||||
.byte QR_SIZE-3, QR_SIZE-2, QR_SIZE-1
|
||||
FormatX2
|
||||
ds 7, 8
|
||||
.byte QR_SIZE-8, QR_SIZE-7, QR_SIZE-6, QR_SIZE-5
|
||||
.byte QR_SIZE-4, QR_SIZE-3, QR_SIZE-2, QR_SIZE-1
|
||||
|
||||
BitMask
|
||||
.byte $80, $40, $20, $10, $8, $4, $2, $1
|
||||
|
||||
Generator ; data in reversed order!
|
||||
IF DEGREE = 7
|
||||
.byte $75, $44, $0b, $a4, $9a, $7a, $7f
|
||||
ENDIF
|
||||
IF DEGREE = 10
|
||||
.byte $c1, $9d, $71, $5f, $5e, $c7, $6f, $9f
|
||||
.byte $c2, $d8
|
||||
ENDIF
|
||||
IF DEGREE = 15
|
||||
.byte $1a, $86, $20, $97, $84, $8b, $69, $69
|
||||
.byte $0a, $4a, $70, $a3, $6f, $c4, $1d
|
||||
ENDIF
|
||||
IF 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
|
||||
; +a3x^7+41x^6+29x^5+e5x^4+62x^3+32x^2+24x+3b
|
||||
.byte $3b, $24, $32, $62, $e5, $29, $41, $a3
|
||||
.byte $08, $1e, $d1, $44, $bd, $68, $0d, $3b
|
||||
ENDIF
|
||||
IF 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
|
||||
|
||||
ECHO "QR Code encoding data:", [. - QRCodeData]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - QRCodeData
|
||||
|
||||
ENDM
|
817
QRCodeGenDemo.asm
Normal file
817
QRCodeGenDemo.asm
Normal file
@ -0,0 +1,817 @@
|
||||
; QR Code generator demo V0.3
|
||||
; (C) 2021 Thomas Jentzsch
|
||||
|
||||
; TODOs
|
||||
; + get it working!
|
||||
; + reduce RAM usage
|
||||
; + reverse data
|
||||
; + overlap data with QR code
|
||||
; + multiple pattern formats
|
||||
; + apply pattern
|
||||
; x evaluate pattern (very slow!)
|
||||
; - support multiple QR code versions
|
||||
; o support multiple QR code levels
|
||||
; - try to optimize function pattern (SetPixel)
|
||||
; x add logo (does NOT work for such small sizes)
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; QR code data bytes (version 2):
|
||||
; - 13 into right sprite column
|
||||
; - 17 until horizontal timer line
|
||||
; - 36 into right and middle sprite column
|
||||
; - 8 in left sprite column
|
||||
|
||||
processor 6502
|
||||
LIST OFF
|
||||
include vcs.h
|
||||
LIST ON
|
||||
|
||||
;===============================================================================
|
||||
; A S S E M B L E R - S W I T C H E S
|
||||
;===============================================================================
|
||||
|
||||
BASE_ADR = $f000
|
||||
|
||||
NTSC = 1
|
||||
|
||||
; QR 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_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
|
||||
|
||||
NUM_FIRST = 1 ; left top 9 and bottom 8 bits are fixed!
|
||||
|
||||
; other constants
|
||||
RND_EOR_VAL = $b4
|
||||
|
||||
_QR_TOTAL SET 0
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; Z P - V A R I A B L E S
|
||||
;===============================================================================
|
||||
|
||||
SEG.U variables
|
||||
ORG $80
|
||||
|
||||
random .byte
|
||||
|
||||
;---------------------------------------
|
||||
; QR code variables
|
||||
; all byte counts based on version 2, level M QR code
|
||||
tmpVars ds 6
|
||||
|
||||
msgIdx = tmpVars + 3
|
||||
IF QR_SINGLE_MASK = 0
|
||||
qrPattern .byte
|
||||
ENDIF
|
||||
;---------------------------------------
|
||||
data ds TOTAL_LEN ; 44 bytes
|
||||
remainder = data ; (DEGREE = 16 bytes)
|
||||
msgData = data + DEGREE ; (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
|
||||
ELSE
|
||||
qrCodeLst ds NUM_FIRST + QR_SIZE*3 ; 76 bytes
|
||||
ENDIF
|
||||
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
|
||||
;---------------------------------------
|
||||
; QR code total = 89/127 bytes
|
||||
|
||||
ECHO "RAM:", [$100 - .]d, "bytes free"
|
||||
ECHO ""
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; M A C R O S
|
||||
;===============================================================================
|
||||
|
||||
MAC BIT_W
|
||||
.byte $2c
|
||||
ENDM
|
||||
|
||||
MAC SLEEP
|
||||
IF {1} = 1
|
||||
ECHO "ERROR: SLEEP 1 not allowed !"
|
||||
END
|
||||
ENDIF
|
||||
IF {1} & 1
|
||||
nop $00
|
||||
REPEAT ({1}-3)/2
|
||||
nop
|
||||
REPEND
|
||||
ELSE
|
||||
REPEAT ({1})/2
|
||||
nop
|
||||
REPEND
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC NEXT_RANDOM
|
||||
;-----------------------------------------------------------
|
||||
; update random value:
|
||||
lda random ; 3
|
||||
lsr ; 2
|
||||
bcc .skipEOR ; 2/3
|
||||
eor #RND_EOR_VAL ; 2
|
||||
.skipEOR
|
||||
sta random ; 3 = 14/19
|
||||
ENDM
|
||||
|
||||
; Platform specific macros
|
||||
IF QR_OVERLAP = 0
|
||||
;-----------------------------------------------------------
|
||||
MAC _BLACK_FUNC
|
||||
;-----------------------------------------------------------
|
||||
ldx #QR_LST_SIZE-1
|
||||
.loopBlack
|
||||
lda BlackGfx,x
|
||||
sta qrCodeLst,x
|
||||
dex
|
||||
bpl .loopBlack
|
||||
ENDM
|
||||
|
||||
ELSE
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _BLACK_LEFT
|
||||
;-----------------------------------------------------------
|
||||
ldx #NUM_FIRST + QR_SIZE-1-8
|
||||
.loopBlackLeft
|
||||
lda LeftBlack+8,x
|
||||
sta qrCodeLst+8,x
|
||||
dex
|
||||
bpl .loopBlackLeft
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _BLACK_MIDDLE
|
||||
;-----------------------------------------------------------
|
||||
ldx #QR_SIZE-1
|
||||
.loopBlackMiddle
|
||||
lda GRP1Black,x
|
||||
sta grp1Lst,x
|
||||
dex
|
||||
bpl .loopBlackMiddle
|
||||
ENDM
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _BLACK_RIGHT
|
||||
;-----------------------------------------------------------
|
||||
ldx #QR_SIZE
|
||||
.loopBlackRight
|
||||
lda GRP0RBlack-1,x
|
||||
sta grp0RLst-1,x
|
||||
dex
|
||||
bne .loopBlackRight
|
||||
ENDM
|
||||
ENDIF ; /QR_OVERLAP
|
||||
|
||||
;-----------------------------------------------------------
|
||||
MAC _DRAW_FUNC
|
||||
;-----------------------------------------------------------
|
||||
ldx #QR_LST_SIZE-1
|
||||
.loopBlack
|
||||
lda qrCodeLst,x
|
||||
ora BlackGfx,x
|
||||
eor EorGfx,x
|
||||
sta qrCodeLst,x
|
||||
dex
|
||||
bpl .loopBlack
|
||||
ENDM
|
||||
|
||||
include QRCodeGen.inc
|
||||
|
||||
|
||||
;===============================================================================
|
||||
; R O M - C O D E
|
||||
;===============================================================================
|
||||
SEG Bank0
|
||||
ORG BASE_ADR
|
||||
|
||||
;---------------------------------------------------------------
|
||||
DrawScreen SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
ldx #227
|
||||
.waitTim:
|
||||
lda INTIM
|
||||
bne .waitTim
|
||||
sta WSYNC
|
||||
sta VBLANK
|
||||
stx TIM64T
|
||||
;---------------------------------------------------------------
|
||||
ldx #3
|
||||
bit SWCHB
|
||||
bvs .skipCentering
|
||||
; some vertical centering
|
||||
ldx #(192-QR_SIZE*2)/2
|
||||
.skipCentering
|
||||
.waitTop
|
||||
sta WSYNC
|
||||
dex
|
||||
bne .waitTop
|
||||
|
||||
ldx #QR_SIZE-1
|
||||
lda #%1 ; 1st top left fixed pixel
|
||||
bne .enterLoop
|
||||
|
||||
.tmpFirst = tmpVars
|
||||
|
||||
; the QR code kernel
|
||||
.loopKernel ; @55
|
||||
lda FirstIdxTbl,x ; 4*
|
||||
bne .newFirst ; 2/3
|
||||
lsr .tmpFirst ; 5
|
||||
bpl .endFirst ; 3 = 14 unconditional
|
||||
|
||||
.newFirst ; @62
|
||||
; $bf | $01 | $fe
|
||||
bmi .enterLoop ; 2/3
|
||||
lda firstMsl ; 3
|
||||
.enterLoop
|
||||
sta .tmpFirst ; 3 = 7
|
||||
.endFirst ; @69
|
||||
ldy #2 ; 2
|
||||
.loopBlock
|
||||
sta WSYNC ; 3 @74
|
||||
;---------------------------------------
|
||||
;M1-P0-P1-P0
|
||||
lda .tmpFirst ; 3
|
||||
asl ; 2
|
||||
sta ENAM1 ; 3 = 8
|
||||
lda grp1Lst,x ; 4
|
||||
sta GRP1 ; 3
|
||||
lda grp0LLst,x ; 4
|
||||
sta GRP0 ; 3
|
||||
SLEEP 17 ;17
|
||||
lda grp0RLst,x ; 4
|
||||
dey ; 2
|
||||
sta GRP0 ; 3 = 40 @48
|
||||
bne .loopBlock ; 3/2
|
||||
dex ; 2
|
||||
bpl .loopKernel ; 3/2=7/6
|
||||
sta WSYNC
|
||||
;---------------------------------------------------------------
|
||||
sty ENAM1
|
||||
sty GRP1
|
||||
sty GRP0
|
||||
|
||||
ldx #2
|
||||
.waitScreen:
|
||||
lda INTIM
|
||||
bne .waitScreen
|
||||
sta WSYNC
|
||||
stx VBLANK
|
||||
rts
|
||||
; DrawScreen
|
||||
|
||||
;---------------------------------------------------------------
|
||||
Start SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
cld ; Clear BCD math bit.
|
||||
lda #0
|
||||
tax
|
||||
dex
|
||||
txs
|
||||
.clearLoop:
|
||||
tsx
|
||||
pha
|
||||
bne .clearLoop
|
||||
|
||||
lda INTIM
|
||||
ora #$10
|
||||
sta random
|
||||
|
||||
jsr InitDemo
|
||||
|
||||
.mainLoop:
|
||||
jsr VerticalBlank
|
||||
jsr DrawScreen
|
||||
jsr OverScan
|
||||
jmp .mainLoop
|
||||
|
||||
;---------------------------------------------------------------
|
||||
InitDemo SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
sta WSYNC
|
||||
;---------------------------------------
|
||||
lda #$0e
|
||||
sta COLUBK
|
||||
lda #$00
|
||||
sta COLUP0
|
||||
sta COLUP1
|
||||
|
||||
lda #%001
|
||||
sta NUSIZ0
|
||||
sta VDELP1
|
||||
|
||||
ldx #$3f
|
||||
stx HMP0
|
||||
inx
|
||||
stx HMP1
|
||||
lda #$a0
|
||||
sta HMM1
|
||||
|
||||
SLEEP 3
|
||||
|
||||
sta RESM1
|
||||
sta RESP0
|
||||
sta RESP1
|
||||
|
||||
sta WSYNC
|
||||
;---------------------------------------
|
||||
sta HMOVE
|
||||
|
||||
jmp GenerateQR
|
||||
; GameInit
|
||||
|
||||
;---------------------------------------------------------------
|
||||
VerticalBlank SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
lda #%00001110
|
||||
.loopVSync:
|
||||
sta WSYNC
|
||||
sta VSYNC
|
||||
lsr
|
||||
bne .loopVSync
|
||||
|
||||
IF NTSC
|
||||
lda #44
|
||||
ELSE
|
||||
lda #77
|
||||
ENDIF
|
||||
sta TIM64T
|
||||
|
||||
bit INPT4
|
||||
bmi .skipRegen
|
||||
|
||||
jsr GenerateQR
|
||||
.skipRegen
|
||||
NEXT_RANDOM
|
||||
rts
|
||||
; VerticalBlank
|
||||
|
||||
;---------------------------------------------------------------
|
||||
OverScan SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
IF NTSC
|
||||
lda #36
|
||||
ELSE
|
||||
lda #63
|
||||
ENDIF
|
||||
sta TIM64T
|
||||
|
||||
.waitTim:
|
||||
lda INTIM
|
||||
bne .waitTim
|
||||
rts
|
||||
; OverScan
|
||||
|
||||
;---------------------------------------------------------------
|
||||
GenerateQR SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
; *** Generate QR code from message ***
|
||||
IF QR_SINGLE_MASK = 0
|
||||
lda random
|
||||
and #$07
|
||||
; lda #0
|
||||
sta qrPattern
|
||||
ENDIF
|
||||
|
||||
MessageCode
|
||||
; convert the message into a data stream
|
||||
.msgLen = tmpVars
|
||||
.msgPtr = tmpVars+1
|
||||
lda random
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
and #$0f
|
||||
tay
|
||||
; ldy #0
|
||||
lda MessagePtrLo,y
|
||||
sta .msgPtr
|
||||
lda MessagePtrHi,y
|
||||
sta .msgPtr+1
|
||||
lda MessagePtrLo+1,y
|
||||
sec
|
||||
sbc .msgPtr
|
||||
sta .msgLen
|
||||
START_MSG
|
||||
ldy #0
|
||||
.loopMsg
|
||||
lda (.msgPtr),y
|
||||
ADD_MSG_BYTE
|
||||
iny
|
||||
cpy .msgLen
|
||||
bcc .loopMsg
|
||||
STOP_MSG
|
||||
|
||||
ECHO "QR Code message code:", [. - MessageCode]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - MessageCode
|
||||
|
||||
GEN_QR_CODE
|
||||
rts
|
||||
|
||||
BitMapCode
|
||||
;---------------------------------------------------------------
|
||||
CheckPixel SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
; Platform specific code. Must NOT change X and Y registers!
|
||||
; X = y; Y = x
|
||||
; determine 8 bit column (0..2) or missile columns
|
||||
tya
|
||||
bne .notMissile
|
||||
; check if single missile byte is affected
|
||||
cpx #8
|
||||
bcc .alwaysSet
|
||||
cpx #8*2
|
||||
bcs .alwaysSet
|
||||
lda firstMsl
|
||||
and BitMask-8,x
|
||||
rts
|
||||
|
||||
.alwaysSet
|
||||
lda #1
|
||||
rts
|
||||
|
||||
.notMissile
|
||||
cpy #1+8
|
||||
bcs .notGRP0L
|
||||
IF QR_OVERLAP
|
||||
cpx #8 ; bottom left eye (partially) shared with data!
|
||||
bcc .alwaysSet
|
||||
ENDIF
|
||||
lda grp0LLst,x
|
||||
and BitMask-1,y
|
||||
rts
|
||||
|
||||
.notGRP0L
|
||||
cpy #1+8*2
|
||||
bcs .notGRP1
|
||||
lda grp1Lst,x
|
||||
and BitMask-1-8,y
|
||||
rts
|
||||
|
||||
.notGRP1
|
||||
; must be GRP0R then
|
||||
lda grp0RLst,x
|
||||
and BitMask-1-8*2,y
|
||||
rts
|
||||
|
||||
;---------------------------------------------------------------
|
||||
InvertPixel SUBROUTINE
|
||||
;---------------------------------------------------------------
|
||||
; Platform specific code. Must NOT change X and Y registers!
|
||||
; X = y; Y = x
|
||||
; determine 8 bit column (0..2) or missile column
|
||||
tya
|
||||
bne .notMissile
|
||||
; check if single missile byte is affected
|
||||
cpx #8
|
||||
bcc .ignore
|
||||
cpx #8*2
|
||||
bcs .ignore
|
||||
lda BitMask-8,x
|
||||
eor firstMsl
|
||||
sta firstMsl
|
||||
.ignore
|
||||
rts
|
||||
|
||||
.notMissile
|
||||
cpy #1+8
|
||||
bcs .notGRP0L
|
||||
lda grp0LLst,x
|
||||
eor BitMask-1,y
|
||||
sta grp0LLst,x
|
||||
rts
|
||||
|
||||
.notGRP0L
|
||||
cpy #1+8*2
|
||||
bcs .notGRP1
|
||||
lda grp1Lst,x
|
||||
eor BitMask-1-8,y
|
||||
sta grp1Lst,x
|
||||
rts
|
||||
|
||||
.notGRP1
|
||||
; must be GRP0R then
|
||||
lda grp0RLst,x
|
||||
eor BitMask-1-8*2,y
|
||||
sta grp0RLst,x
|
||||
rts
|
||||
|
||||
ECHO "QR Code bitmap code:", [. - BitMapCode]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - BitMapCode
|
||||
|
||||
;===============================================================================
|
||||
; R O M - T A B L E S (Bank 0)
|
||||
;===============================================================================
|
||||
org BASE_ADR + $600
|
||||
|
||||
FunctionModulesData
|
||||
|
||||
; Platform and version specific function module data definition
|
||||
BlackGfx
|
||||
LeftBlack
|
||||
GRP0LBlack
|
||||
.byte %11111111 ; constant, bit 0 of 2nd format copy, level
|
||||
.byte %11111111 ; constant, bit 1 of 2nd format copy, level
|
||||
.byte %11111111 ; constant, bit 2 of 2nd format copy, pattern
|
||||
.byte %11111111 ; constant, bit 3 of 2nd format copy, pattern
|
||||
.byte %11111111 ; constant, bit 4 of 2nd format copy, pattern
|
||||
.byte %11111111 ; constant, bit 5 of 2nd format copy, ECC
|
||||
.byte %11111111 ; constant, bit 6 of 2nd format copy, ECC
|
||||
.byte %11111111 ; constant, 1 (dark module)
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %00000100
|
||||
.byte %11111111 ; constant, bits 1..7 of 1st format copy
|
||||
.byte %11111111 ; constant, bit 8 of 1st format copy, ECC
|
||||
.byte %11111111 ; constant, 1 (timing bit)
|
||||
.byte %11111111 ; constant, bit 9 of 1st format copy, ECC
|
||||
.byte %11111111 ; constant, bit 10 of 1st format copy, ECC
|
||||
.byte %11111111 ; constant, bit 11 of 1st format copy, ECC
|
||||
.byte %11111111 ; constant, bit 12 of 1st format copy, ECC
|
||||
.byte %11111111 ; constant, bit 13 of 1st format copy, ECC
|
||||
.byte %11111111 ; constant, bit 14 of 1st format copy, ECC
|
||||
;FirstBlack
|
||||
.byte %00000000
|
||||
GRP1Black
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000001
|
||||
.byte %00000001
|
||||
.byte %00000001
|
||||
.byte %00000001
|
||||
.byte %00000001
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %11111111
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
GRP0RBlack
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %11110000
|
||||
.byte %11110000
|
||||
.byte %11110000
|
||||
.byte %11110000
|
||||
.byte %11110000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %11111111 ; constant, bits 7..14 of 2nd format copy
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
.byte %11111111 ; constant
|
||||
|
||||
EorGfx
|
||||
;GRP0LEor
|
||||
.byte %00000011 ; constant, bit 0 of 2nd format copy, level
|
||||
.byte %11111011 ; constant, bit 1 of 2nd format copy, level
|
||||
.byte %10001011 ; constant, bit 2 of 2nd format copy, pattern
|
||||
.byte %10001011 ; constant, bit 3 of 2nd format copy, pattern
|
||||
.byte %10001011 ; constant, bit 4 of 2nd format copy, pattern
|
||||
.byte %11111011 ; constant, bit 5 of 2nd format copy, ECC
|
||||
.byte %00000011 ; constant, bit 6 of 2nd format copy, ECC
|
||||
.byte %11111110 ; constant, 1 (dark module)
|
||||
.byte %00000000
|
||||
.byte %00000100
|
||||
.byte %00000000
|
||||
.byte %00000100
|
||||
.byte %00000000
|
||||
.byte %00000100
|
||||
.byte %00000000
|
||||
.byte %00000100
|
||||
.byte %11111011 ; constant, bits 1..7 of 1st format copy
|
||||
.byte %11111111 ; constant, bit 8 of 1st format copy, ECC
|
||||
.byte %00000010 ; constant, 1 (timing bit)
|
||||
.byte %11111011 ; constant, bit 9 of 1st format copy, ECC
|
||||
.byte %10001011 ; constant, bit 10 of 1st format copy, ECC
|
||||
.byte %10001011 ; constant, bit 11 of 1st format copy, ECC
|
||||
.byte %10001011 ; constant, bit 12 of 1st format copy, ECC
|
||||
.byte %11111011 ; constant, bit 13 of 1st format copy, ECC
|
||||
.byte %00000011 ; constant, bit 14 of 1st format copy, ECC
|
||||
;FirstEor
|
||||
.byte %00000000
|
||||
;GRP1Eor
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %10101010
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
;GRP0REor
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %11100000
|
||||
.byte %10100000
|
||||
.byte %11100000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %11111111 ; constant, bits 7..14 of 2nd format copy
|
||||
.byte %11111111 ; constant
|
||||
.byte %10000000 ; constant
|
||||
.byte %10111110 ; constant
|
||||
.byte %10100010 ; constant
|
||||
.byte %10100010 ; constant
|
||||
.byte %10100010 ; constant
|
||||
.byte %10111110 ; constant
|
||||
.byte %10000000 ; constant
|
||||
|
||||
FirstIdxTbl ; for 25 pixel
|
||||
ds 7, 0
|
||||
.byte $fe
|
||||
ds 7, 0
|
||||
.byte $01
|
||||
ds 7, 0
|
||||
.byte $bf
|
||||
|
||||
ECHO "QR Code function modules data:", [. - FunctionModulesData]d, "bytes"
|
||||
_QR_TOTAL SET _QR_TOTAL + . - FunctionModulesData
|
||||
|
||||
QR_CODE_DATA
|
||||
|
||||
.byte " QR Code Generator Demo V0.3 - (C)2021 Thomas Jentzsch "
|
||||
|
||||
; messages MUST not be longer than 26 bytes for version 2, level M!
|
||||
; Galadriel:
|
||||
MessageTbl
|
||||
Message0
|
||||
.byte "It began with the forging"
|
||||
; .byte "AtariAge/?s=_1X<|>[]*#"
|
||||
Message1
|
||||
.byte "of the Great Rings. Three"
|
||||
Message2
|
||||
.byte "were given to the Elves,"
|
||||
Message3
|
||||
.byte "immortal, wisest and"
|
||||
Message4
|
||||
.byte "fairest of all beings."
|
||||
Message5
|
||||
.byte "Seven to the Dwarf lords,"
|
||||
Message6
|
||||
.byte "great miners and craftsmen"
|
||||
Message7
|
||||
.byte "of the mountain halls. And"
|
||||
Message8
|
||||
.byte "nine, nine rings were"
|
||||
Message9
|
||||
.byte "gifted to the race of men,"
|
||||
Message10
|
||||
.byte "who, above all else,"
|
||||
Message11
|
||||
.byte "desire power. But they"
|
||||
Message12
|
||||
.byte "were, all of them,"
|
||||
Message13
|
||||
.byte "deceived, for another Ring"
|
||||
Message14
|
||||
.byte "was made. In the land of"
|
||||
Message15
|
||||
.byte "Mordor, in the fires of..."
|
||||
MessageEnd
|
||||
|
||||
; .byte "..the single hardest thing"
|
||||
|
||||
MessagePtrLo
|
||||
.byte <Message0, <Message1, <Message2, <Message3
|
||||
.byte <Message4, <Message5, <Message6, <Message7
|
||||
.byte <Message8, <Message9, <Message10, <Message11
|
||||
.byte <Message12, <Message13, <Message14, <Message15
|
||||
.byte <MessageEnd
|
||||
MessagePtrHi
|
||||
.byte >Message0, >Message1, >Message2, >Message3
|
||||
.byte >Message4, >Message5, >Message6, >Message7
|
||||
.byte >Message8, >Message9, >Message10, >Message11
|
||||
.byte >Message12, >Message13, >Message14, >Message15
|
||||
|
||||
.byte "JTZ"
|
||||
|
||||
org BASE_ADR + $ffc
|
||||
.word Start
|
||||
.word Start
|
||||
|
||||
ECHO "----------------------------------------"
|
||||
ECHO "QR Code total:", [_QR_TOTAL]d, "bytes"
|
||||
ECHO ""
|
||||
ECHO "QR Code Version, Level (Degree): ", [QR_VERSION]d, ",", [QR_LEVEL]d, "(", [DEGREE]d, ")"
|
Loading…
Reference in New Issue
Block a user