mirror of
https://github.com/thrust26/6502-QR-code-generator.git
synced 2024-06-04 21:29:30 +00:00
added function module drawing
This commit is contained in:
parent
d150cbc5af
commit
77263c915c
|
@ -162,16 +162,3 @@ EorGfx
|
||||||
.byte %10100010 ; constant
|
.byte %10100010 ; constant
|
||||||
.byte %10111110 ; constant
|
.byte %10111110 ; constant
|
||||||
.byte %10000000 ; constant
|
.byte %10000000 ; constant
|
||||||
|
|
||||||
FirstIdxTbl ; for 25 pixel
|
|
||||||
ds 7, 0
|
|
||||||
.byte $fe
|
|
||||||
ds 7, 0
|
|
||||||
.byte $01
|
|
||||||
ds 7, 0
|
|
||||||
IF QR_LEVEL = 0 || QR_LEVEL = 1
|
|
||||||
.byte $bf ; 1st format bit is 1
|
|
||||||
ELSE
|
|
||||||
.byte $3f ; 1st format bit is 0
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
|
|
|
@ -171,15 +171,3 @@ GRP0RBlack
|
||||||
IF QR_LEVEL = 1
|
IF QR_LEVEL = 1
|
||||||
EOR_GFX ~%10101000, ~%00100100
|
EOR_GFX ~%10101000, ~%00100100
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
FirstIdxTbl ; for 25 pixel
|
|
||||||
ds 7, 0
|
|
||||||
.byte $fe
|
|
||||||
ds 7, 0
|
|
||||||
.byte $01
|
|
||||||
ds 7, 0
|
|
||||||
IF QR_LEVEL = 0 || QR_LEVEL = 1
|
|
||||||
.byte $bf ; 1st format bit is 1
|
|
||||||
ELSE
|
|
||||||
.byte $3f ; 1st format bit is 0
|
|
||||||
ENDIF
|
|
||||||
|
|
244
QRCodeGen.inc
244
QRCodeGen.inc
|
@ -2,8 +2,20 @@
|
||||||
; Q R C O D E C O N S T A N T S
|
; Q R C O D E C O N S T A N T S
|
||||||
;===============================================================================
|
;===============================================================================
|
||||||
|
|
||||||
|
; Do NOT change these constants!
|
||||||
|
|
||||||
|
IFNCONST QR_OVERLAP
|
||||||
|
QR_OVERLAP = 0
|
||||||
|
ENDIF
|
||||||
|
IFNCONST QR_SINGLE_MASK
|
||||||
|
QR_SINGLE_MASK = 0
|
||||||
|
ENDIF
|
||||||
|
IFNCONST QR_DIRECT_DRAW
|
||||||
|
QR_DIRECT_DRAW = 0
|
||||||
|
ENDIF
|
||||||
|
|
||||||
IF QR_VERSION = 1 ;{
|
IF QR_VERSION = 1 ;{
|
||||||
QR_SIZE = 21 ; 21x21 QR code
|
; 21x21 QR code
|
||||||
IF QR_LEVEL = 0
|
IF QR_LEVEL = 0
|
||||||
QR_DEGREE = 7 ; for version 1, level L QR codes
|
QR_DEGREE = 7 ; for version 1, level L QR codes
|
||||||
ENDIF
|
ENDIF
|
||||||
|
@ -19,7 +31,7 @@ QR_DEGREE = 17 ; for version 1, level H QR codes
|
||||||
ENDIF ;}
|
ENDIF ;}
|
||||||
|
|
||||||
IF QR_VERSION = 2
|
IF QR_VERSION = 2
|
||||||
QR_SIZE = 25 ; 25x25 QR code
|
; 25x25 QR code
|
||||||
IF QR_LEVEL = 0
|
IF QR_LEVEL = 0
|
||||||
QR_DEGREE = 10 ; for version 2, level L QR codes
|
QR_DEGREE = 10 ; for version 2, level L QR codes
|
||||||
ENDIF
|
ENDIF
|
||||||
|
@ -35,7 +47,7 @@ QR_DEGREE = 28 ; for version 2, level H QR codes
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
IF QR_VERSION = 3 ;{
|
IF QR_VERSION = 3 ;{
|
||||||
QR_SIZE = 29 ; 29x29 QR code
|
; 29x29 QR code
|
||||||
IF QR_LEVEL = 0
|
IF QR_LEVEL = 0
|
||||||
QR_DEGREE = 15 ; for version 3, level L QR codes
|
QR_DEGREE = 15 ; for version 3, level L QR codes
|
||||||
ENDIF
|
ENDIF
|
||||||
|
@ -49,6 +61,8 @@ QR_DEGREE = 26 ; for version 3, level M QR codes
|
||||||
ENDIF
|
ENDIF
|
||||||
ENDIF ;}
|
ENDIF ;}
|
||||||
|
|
||||||
|
QR_SIZE = 17 + QR_VERSION * 4
|
||||||
|
|
||||||
; Calculate capacity based on version
|
; Calculate capacity based on version
|
||||||
_QR_VAL SET (QR_VERSION * 16 + 128) * QR_VERSION + 64
|
_QR_VAL SET (QR_VERSION * 16 + 128) * QR_VERSION + 64
|
||||||
IF QR_VERSION >= 2
|
IF QR_VERSION >= 2
|
||||||
|
@ -219,24 +233,150 @@ RSMult SUBROUTINE
|
||||||
bpl .loopI
|
bpl .loopI
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
|
IF QR_DIRECT_DRAW = 0
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
MAC _BLACK_FUNC
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
; Blacks all function/alignment and timing pattern areas
|
||||||
|
|
||||||
|
; assume bitmap is clear, only draw the pattern
|
||||||
|
ldy #4+2 ; pattern + timing lines
|
||||||
|
.loopPattern
|
||||||
|
lda #$ff ; fill pattern
|
||||||
|
jsr DrawPattern
|
||||||
|
bpl .loopPattern
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
BlackFunc SUBROUTINE
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
_BLACK_FUNC
|
||||||
|
rts
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
MAC _DRAW_FUNC
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
; Draws all function/alignment and timing pattern over existing codewords
|
||||||
|
|
||||||
|
; blacken functions pattern first
|
||||||
|
jsr BlackFunc
|
||||||
|
|
||||||
|
; draw function pattern
|
||||||
|
ldy #4
|
||||||
|
.loopPattern
|
||||||
|
lda #$00 ; draw pattern
|
||||||
|
jsr DrawPattern
|
||||||
|
bne .loopPattern
|
||||||
|
|
||||||
|
; draw horizontal timing pattern
|
||||||
|
ldy #QR_SIZE-1 - 9
|
||||||
|
ldx #QR_SIZE-1 - 6
|
||||||
|
.loopTimingH
|
||||||
|
jsr InvertPixel
|
||||||
|
dey
|
||||||
|
dey
|
||||||
|
cpy #9
|
||||||
|
bcs .loopTimingH
|
||||||
|
|
||||||
|
; draw vertical timing pattern
|
||||||
|
ldy #6
|
||||||
|
ldx #QR_SIZE-1 - 9
|
||||||
|
.loopTimingV
|
||||||
|
jsr InvertPixel
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
cpx #9
|
||||||
|
bcs .loopTimingV
|
||||||
|
ENDM ;
|
||||||
|
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
DrawPattern SUBROUTINE
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; Y = index, A = fill
|
||||||
|
.index = tmpVars
|
||||||
|
.width = tmpVars+1
|
||||||
|
.height = tmpVars+2
|
||||||
|
.offset = tmpVars+3
|
||||||
|
.tmpPat = tmpVars+4
|
||||||
|
.fill = tmpVars+5
|
||||||
|
|
||||||
|
sty .index
|
||||||
|
sta .fill
|
||||||
|
ldx PatternY,y
|
||||||
|
lda PatternHeight,y
|
||||||
|
sta .height
|
||||||
|
lda PatternOffset,y
|
||||||
|
tay
|
||||||
|
.loopRow
|
||||||
|
sty .offset
|
||||||
|
lda PatternStart,y
|
||||||
|
ora .fill
|
||||||
|
sta .tmpPat
|
||||||
|
ldy .index
|
||||||
|
lda PatternWidth,y
|
||||||
|
sta .width
|
||||||
|
lda PatternX,y
|
||||||
|
tay
|
||||||
|
; draw one row
|
||||||
|
.loopBit
|
||||||
|
sec ; allows for >8 black pixel
|
||||||
|
ror .tmpPat
|
||||||
|
bcc .clear
|
||||||
|
;.set
|
||||||
|
jsr CheckPixel
|
||||||
|
bne .skipInvert
|
||||||
|
.invert
|
||||||
|
jsr InvertPixel
|
||||||
|
.skipInvert
|
||||||
|
iny
|
||||||
|
dec .width
|
||||||
|
bne .loopBit
|
||||||
|
dex
|
||||||
|
ldy .offset
|
||||||
|
iny
|
||||||
|
dec .height
|
||||||
|
bne .loopRow
|
||||||
|
.exit
|
||||||
|
ldy .index
|
||||||
|
dey
|
||||||
|
rts
|
||||||
|
|
||||||
|
.clear
|
||||||
|
jsr CheckPixel
|
||||||
|
bne .invert
|
||||||
|
beq .skipInvert
|
||||||
|
ENDIF ; /QR_DIRECT_DRAW = 0
|
||||||
|
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
; Draws the raw codewords (including data and ECC) onto the given QR Code. This requires the initial state of
|
; 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).
|
; the QR Code to be black at function modules and white at codeword modules (including unused remainder bits).
|
||||||
MAC _DRAW_CODEWORDS
|
MAC _DRAW_CODEWORDS
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
; Note: This part has the maximum RAM usage
|
; Note: This part has the maximum RAM usage
|
||||||
.right1 = tmpVars+0
|
.vert = tmpVars+0
|
||||||
.vert = tmpVars+1
|
.j = tmpVars+1
|
||||||
.j = tmpVars+2
|
.y = tmpVars+2
|
||||||
.y = tmpVars+3
|
IF QR_DIRECT_DRAW
|
||||||
.iBit = tmpVars+4
|
.iBit = tmpVars+3
|
||||||
.iByte = tmpVars+5
|
.iByte = tmpVars+4
|
||||||
|
.right1 = tmpVars+5
|
||||||
|
ELSE
|
||||||
|
; must not overlap with DrawPattern space
|
||||||
|
.iBit = tmpVars+6
|
||||||
|
.iByte = tmpVars+7
|
||||||
|
.right1 = tmpVars+8
|
||||||
|
ENDIF
|
||||||
|
|
||||||
; blacken the (right) function modules in the bitmap
|
; blacken the (right) function modules in the bitmap
|
||||||
IF QR_OVERLAP
|
IF QR_OVERLAP
|
||||||
_BLACK_RIGHT ; returns with X = 0
|
_BLACK_RIGHT ; returns with X = 0
|
||||||
ELSE
|
ELSE
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
_BLACK_FUNC ; returns with X = 0
|
_BLACK_FUNC ; returns with X = 0
|
||||||
|
ELSE
|
||||||
|
jsr BlackFunc
|
||||||
|
ldx #0
|
||||||
|
ENDIF
|
||||||
ENDIF
|
ENDIF
|
||||||
; int i = 0; // Bit index into the data
|
; int i = 0; // Bit index into the data
|
||||||
; ldx #0
|
; ldx #0
|
||||||
|
@ -262,6 +402,9 @@ RSMult SUBROUTINE
|
||||||
bne .skipBlackMiddle
|
bne .skipBlackMiddle
|
||||||
; blacken the middle function modules in the bitmap
|
; blacken the middle function modules in the bitmap
|
||||||
_BLACK_MIDDLE
|
_BLACK_MIDDLE
|
||||||
|
IF QR_DIRECT_DRAW = 0
|
||||||
|
ldy .right1 ; DrawPattern overwrites Y
|
||||||
|
ENDIF
|
||||||
.skipBlackMiddle
|
.skipBlackMiddle
|
||||||
cpy #8+1
|
cpy #8+1
|
||||||
bne .skipBlackLeft
|
bne .skipBlackLeft
|
||||||
|
@ -332,7 +475,8 @@ RSMult SUBROUTINE
|
||||||
ldy .right1
|
ldy .right1
|
||||||
dey
|
dey
|
||||||
dey
|
dey
|
||||||
bpl .loopRight ; unconditional!
|
; bpl .loopRight ; unconditional!
|
||||||
|
jmp .loopRight ; unconditional!
|
||||||
; } // for right
|
; } // for right
|
||||||
.exitDraw
|
.exitDraw
|
||||||
ENDM
|
ENDM
|
||||||
|
@ -496,7 +640,7 @@ RSMult SUBROUTINE
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
MAC _DRAW_FORMAT
|
MAC _DRAW_FORMAT
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
IF QR_SINGLE_MASK = 0
|
IF QR_SINGLE_MASK = 0 || QR_DIRECT_DRAW = 0
|
||||||
.idx = tmpVars
|
.idx = tmpVars
|
||||||
|
|
||||||
ldy #QR_FORMATS-1
|
ldy #QR_FORMATS-1
|
||||||
|
@ -510,7 +654,11 @@ RSMult SUBROUTINE
|
||||||
lda FormatHi,x
|
lda FormatHi,x
|
||||||
and BitMask-8,y
|
and BitMask-8,y
|
||||||
.lowFormat
|
.lowFormat
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
beq .skipFormat
|
beq .skipFormat
|
||||||
|
ELSE
|
||||||
|
bne .skipFormat
|
||||||
|
ENDIF
|
||||||
ldx FormatY1,y
|
ldx FormatY1,y
|
||||||
lda FormatX1,y
|
lda FormatX1,y
|
||||||
tay
|
tay
|
||||||
|
@ -643,8 +791,77 @@ _QR_TOTAL SET _QR_TOTAL + . - QRCodeCode
|
||||||
; Add this to your code's data area
|
; Add this to your code's data area
|
||||||
QRCodeData
|
QRCodeData
|
||||||
|
|
||||||
|
IF QR_DIRECT_DRAW = 0
|
||||||
|
; Function pattern parameters
|
||||||
|
PatternX ; left
|
||||||
|
.byte 6 ; left, vertical timing line
|
||||||
|
.byte 0, 0, QR_SIZE-8 ; eye pattern
|
||||||
|
.byte QR_SIZE-8, QR_SIZE-9 ; alignment pattern (right/middle part)
|
||||||
|
.byte 9 ; top, horizontal timing line
|
||||||
|
PatternY ; top
|
||||||
|
.byte QR_SIZE - 10 ; left, vertical timing line
|
||||||
|
.byte QR_SIZE-1, 7, QR_SIZE-1 ; eye pattern
|
||||||
|
.byte 8, 8 ; alignment pattern (right/middle part)
|
||||||
|
.byte QR_SIZE - 7 ; top, horizontal timing line
|
||||||
|
PatternOffset = . - 1
|
||||||
|
.byte EyeLeftTop-PatternStart ; 1
|
||||||
|
.byte EyeLeftBottom-PatternStart ; 2
|
||||||
|
.byte EyeRightTop-PatternStart ; 3
|
||||||
|
.byte AlignRightBottom-PatternStart
|
||||||
|
.byte AlignRightBottom-PatternStart
|
||||||
|
; timing lines need no pattern, always drawn filled here
|
||||||
|
PatternWidth
|
||||||
|
.byte 1 ; left, vertical timing line
|
||||||
|
.byte 9, 9, 8 ; eye pattern
|
||||||
|
.byte 4, 1 ; alignment pattern (right/middle part)
|
||||||
|
.byte QR_SIZE - 9 - 8 ; top, horizontal timing line
|
||||||
|
PatternHeight
|
||||||
|
.byte QR_SIZE - 9 - 8 ; left, vertical timing line
|
||||||
|
.byte 9, 8, 9 ; eye pattern
|
||||||
|
.byte 5, 5 ; alignment pattern (right/middle part)
|
||||||
|
.byte 1 ; top, horizontal timing line
|
||||||
|
|
||||||
|
PatternStart
|
||||||
|
EyeRightTop
|
||||||
|
.byte %11111110
|
||||||
|
.byte %10000010
|
||||||
|
.byte %10111010
|
||||||
|
.byte %10111010
|
||||||
|
.byte %10111010
|
||||||
|
.byte %10000010
|
||||||
|
.byte %11111110
|
||||||
|
.byte %00000000
|
||||||
|
.byte %11111111
|
||||||
|
AlignRightBottom = . - 1
|
||||||
|
; .byte %1111
|
||||||
|
.byte %1000
|
||||||
|
.byte %1010
|
||||||
|
.byte %1000
|
||||||
|
.byte %1111
|
||||||
|
|
||||||
|
EyeLeftBottom
|
||||||
|
.byte %00000000
|
||||||
|
; .byte %01111111
|
||||||
|
; .byte %01000001
|
||||||
|
; .byte %01011101
|
||||||
|
; .byte %01011101
|
||||||
|
; .byte %01011101
|
||||||
|
; .byte %01000001
|
||||||
|
; .byte %01111111
|
||||||
|
EyeLeftTop
|
||||||
|
.byte %01111111
|
||||||
|
.byte %01000001
|
||||||
|
.byte %01011101
|
||||||
|
.byte %01011101
|
||||||
|
.byte %01011101
|
||||||
|
.byte %01000001
|
||||||
|
.byte %01111111
|
||||||
|
.byte %00000000
|
||||||
|
.byte %11111111
|
||||||
|
ENDIF ; /QR_DIRECT_DRAW
|
||||||
|
|
||||||
; Format Information Strings
|
; Format Information Strings
|
||||||
IF QR_SINGLE_MASK = 0
|
IF QR_SINGLE_MASK = 0 || QR_DIRECT_DRAW = 0
|
||||||
IF QR_LEVEL = 0 ; L
|
IF QR_LEVEL = 0 ; L
|
||||||
FormatLo
|
FormatLo
|
||||||
.byte %11101111
|
.byte %11101111
|
||||||
|
@ -725,7 +942,6 @@ FormatHi
|
||||||
.byte %00011000
|
.byte %00011000
|
||||||
.byte %01110110
|
.byte %01110110
|
||||||
ENDIF
|
ENDIF
|
||||||
ENDIF ; /QR_SINGLE_MASK = 0
|
|
||||||
|
|
||||||
; positions of the 15 type information bits
|
; positions of the 15 type information bits
|
||||||
FormatX1
|
FormatX1
|
||||||
|
@ -742,7 +958,7 @@ FormatX2
|
||||||
ds 7, 8
|
ds 7, 8
|
||||||
.byte QR_SIZE-8, QR_SIZE-7, QR_SIZE-6, QR_SIZE-5
|
.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
|
.byte QR_SIZE-4, QR_SIZE-3, QR_SIZE-2, QR_SIZE-1
|
||||||
ENDIF ; QR_SINGLE_MASK = 0
|
ENDIF ; /QR_SINGLE_MASK = 0 || QR_DIRECT_DRAW = 0
|
||||||
|
|
||||||
BitMask
|
BitMask
|
||||||
.byte $80, $40, $20, $10, $8, $4, $2, $1
|
.byte $80, $40, $20, $10, $8, $4, $2, $1
|
||||||
|
|
|
@ -35,21 +35,31 @@
|
||||||
BASE_ADR = $f000
|
BASE_ADR = $f000
|
||||||
|
|
||||||
NTSC = 1 ; 0 = PAL50
|
NTSC = 1 ; 0 = PAL50
|
||||||
|
ATARI_2600 = 1 ; enable for Atari 2600 specific code
|
||||||
|
|
||||||
; QR Code Generator Switches
|
; QR Code Generator Switches
|
||||||
QR_VERSION = 2 ; 1, 2 or 3 (TODO 1 and 3)
|
QR_VERSION = 2 ; 1, 2 or 3 (TODO 1 and 3)
|
||||||
QR_LEVEL = 1 ; 0 (L), 1 (M), 2 (Q) and 3 (H))
|
QR_LEVEL = 1 ; 0 (L), 1 (M), 2 (Q) and 3 (H))
|
||||||
QR_PADDING = 1 ; (+22 bytes) add padding bytes (optional)
|
QR_PADDING = 1 ; (+ 22 bytes) add padding bytes (optional)
|
||||||
QR_GENERATE = 1 ; (+~12 bytes) generates Reed-Solomon ECC generator polynomial on-the-fly
|
QR_GENERATE = 0 ; (+~12 bytes) generates Reed-Solomon ECC generator polynomial on-the-fly
|
||||||
; else uses built-in table
|
; else uses built-in table
|
||||||
|
|
||||||
; Atari 2600 specific QR settings (set to 0 for other platforms)
|
; Atari 2600 specific QR settings (keep set to 0 for other platforms!)
|
||||||
|
IFCONST ATARI_2600
|
||||||
QR_OVERLAP = 1 ; overlaps input and output data to save RAM (defined for version 2 only!)
|
QR_OVERLAP = 1 ; overlaps input and output data to save RAM (defined for version 2 only!)
|
||||||
QR_SINGLE_MASK = 0 ; (-255 bytes) 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
|
||||||
|
QR_DIRECT_DRAW = 0 ; (+ 45 bytes) draw byte columns instead of individual pixel
|
||||||
|
ENDIF
|
||||||
|
|
||||||
IF QR_VERSION = 1 || QR_VERSION = 3
|
IF QR_VERSION != 2
|
||||||
ECHO ""
|
ECHO ""
|
||||||
ECHO "ERROR: Version", [QR_VERSION]d, "unsupported by demo code"
|
ECHO "*** ERROR: Version", [QR_VERSION]d, "unsupported by demo code! ***"
|
||||||
|
ERR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF QR_SINGLE_MASK = 1 && QR_DIRECT_DRAW = 0
|
||||||
|
ECHO ""
|
||||||
|
ECHO "*** ERROR: Unsupported assembler switches combination! ***"
|
||||||
ERR
|
ERR
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
|
@ -76,7 +86,11 @@ random .byte
|
||||||
;---------------------------------------
|
;---------------------------------------
|
||||||
; QR code variables
|
; QR code variables
|
||||||
; all byte counts based on version 2, level M QR code
|
; all byte counts based on version 2, level M QR code
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
tmpVars ds 6
|
tmpVars ds 6
|
||||||
|
ELSE
|
||||||
|
tmpVars ds 9
|
||||||
|
ENDIF
|
||||||
|
|
||||||
msgIdx = tmpVars + 3
|
msgIdx = tmpVars + 3
|
||||||
IF QR_SINGLE_MASK = 0
|
IF QR_SINGLE_MASK = 0
|
||||||
|
@ -89,11 +103,16 @@ msgData = data + QR_DEGREE ; (QR_MAX_DATA = 28 bytes)
|
||||||
;- - - - - - - - - - - - - - - - - - - -
|
;- - - - - - - - - - - - - - - - - - - -
|
||||||
; The QR code overlaps the data! It overwrites the data while being drawn.
|
; The QR code overlaps the data! It overwrites the data while being drawn.
|
||||||
IF QR_OVERLAP
|
IF QR_OVERLAP
|
||||||
qrCodeLst = data + 6 ; all but 6 bytes overlap (version 2 only!)
|
IF QR_DIRECT_DRAW
|
||||||
ds NUM_FIRST + QR_SIZE*3 - QR_TOTAL + 6 ; 38 bytes
|
QR_NON_OVER = 6
|
||||||
|
ELSE
|
||||||
|
QR_NON_OVER = 8
|
||||||
|
ENDIF
|
||||||
|
qrCodeLst = data + QR_NON_OVER ; all but 6/8 bytes overlap (version 2 only!)
|
||||||
|
ds NUM_FIRST + QR_SIZE*3 - QR_TOTAL + QR_NON_OVER ; 38/40 bytes
|
||||||
ELSE
|
ELSE
|
||||||
qrCodeLst ds NUM_FIRST + QR_SIZE*3 ; 76 bytes
|
qrCodeLst ds NUM_FIRST + QR_SIZE*3 ; 76 bytes
|
||||||
ENDIF
|
ENDIF ; /QR_OVERLAP
|
||||||
grp0LLst = qrCodeLst + QR_SIZE * 0
|
grp0LLst = qrCodeLst + QR_SIZE * 0
|
||||||
firstMsl = qrCodeLst + QR_SIZE * 1
|
firstMsl = qrCodeLst + QR_SIZE * 1
|
||||||
grp1Lst = qrCodeLst + NUM_FIRST + QR_SIZE * 1
|
grp1Lst = qrCodeLst + NUM_FIRST + QR_SIZE * 1
|
||||||
|
@ -150,62 +169,124 @@ qrGenerator ds QR_DEGREE
|
||||||
sta random ; 3 = 14/19
|
sta random ; 3 = 14/19
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
; Platform specific macros
|
; Atari 2600 specific macros
|
||||||
IF QR_OVERLAP = 0
|
IF QR_OVERLAP = 0
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
MAC _BLACK_FUNC
|
MAC _BLACK_FUNC
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
; blacks all function/alignment and timing pattern
|
; blacks all function/alignment and timing pattern
|
||||||
ldx #CODE_LST_SIZE-1
|
ldx #CODE_LST_SIZE
|
||||||
.loopBlack
|
.loopBlack
|
||||||
lda BlackGfx,x
|
lda BlackGfx-1,x
|
||||||
sta qrCodeLst,x
|
sta qrCodeLst-1,x
|
||||||
dex
|
dex
|
||||||
bpl .loopBlack
|
bne .loopBlack
|
||||||
|
; X = 0!
|
||||||
ENDM
|
ENDM
|
||||||
|
ENDIF
|
||||||
|
|
||||||
ELSE
|
ELSE ; QR_OVERLAP
|
||||||
|
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
MAC _BLACK_LEFT
|
MAC _BLACK_LEFT
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
; blacks all function/alignment and timing pattern of the left column
|
; Blacks all function/alignment and timing pattern areas of the left sprite column
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
ldx #NUM_FIRST + QR_SIZE-1-8
|
ldx #NUM_FIRST + QR_SIZE-1-8
|
||||||
.loopBlackLeft
|
.loopBlackLeft
|
||||||
lda LeftBlack+8,x
|
lda LeftBlack+8,x
|
||||||
sta qrCodeLst+8,x
|
sta qrCodeLst+8,x
|
||||||
dex
|
dex
|
||||||
bpl .loopBlackLeft
|
bpl .loopBlackLeft
|
||||||
|
ELSE
|
||||||
|
; clear the bitmap column first...
|
||||||
|
ldx #NUM_FIRST + QR_SIZE-1-8
|
||||||
|
lda #0
|
||||||
|
.loopBlackLeft
|
||||||
|
sta qrCodeLst+8,x
|
||||||
|
dex
|
||||||
|
bpl .loopBlackLeft
|
||||||
|
; ...then draw the pattern
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
|
ldy #1 ; left top pattern/vertical timing line
|
||||||
|
ELSE
|
||||||
|
ldy #2
|
||||||
|
ENDIF
|
||||||
|
.loopPattern
|
||||||
|
lda #$ff ; fill pattern
|
||||||
|
jsr DrawPattern
|
||||||
|
bpl .loopPattern
|
||||||
|
ENDIF
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
MAC _BLACK_MIDDLE
|
MAC _BLACK_MIDDLE
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
; blacks all function/alignment and timing pattern of the middle column
|
; Blacks all function/alignment and timing pattern areas of the middle sprite column
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
ldx #QR_SIZE-1
|
ldx #QR_SIZE-1
|
||||||
.loopBlackMiddle
|
.loopBlackMiddle
|
||||||
lda GRP1Black,x
|
lda GRP1Black,x
|
||||||
sta grp1Lst,x
|
sta grp1Lst,x
|
||||||
dex
|
dex
|
||||||
bpl .loopBlackMiddle
|
bpl .loopBlackMiddle
|
||||||
|
ELSE
|
||||||
|
; clear the bitmap column first...
|
||||||
|
ldx #QR_SIZE-1
|
||||||
|
lda #0
|
||||||
|
.loopBlackMiddle
|
||||||
|
sta grp1Lst,x
|
||||||
|
dex
|
||||||
|
bpl .loopBlackMiddle
|
||||||
|
; ...then draw the pattern
|
||||||
|
ldy #6 ; align pattern
|
||||||
|
.loopPattern
|
||||||
|
lda #$ff ; fill pattern
|
||||||
|
jsr DrawPattern
|
||||||
|
cpy #5
|
||||||
|
bcs .loopPattern
|
||||||
|
ENDIF
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
MAC _BLACK_RIGHT
|
MAC _BLACK_RIGHT
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
; blacks all function/alignment and timing pattern of the right column
|
; Blacks all function/alignment and timing pattern areas of the right sprite column
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
ldx #QR_SIZE
|
ldx #QR_SIZE
|
||||||
.loopBlackRight
|
.loopBlackRight
|
||||||
lda GRP0RBlack-1,x
|
lda GRP0RBlack-1,x
|
||||||
sta grp0RLst-1,x
|
sta grp0RLst-1,x
|
||||||
dex
|
dex
|
||||||
bne .loopBlackRight
|
bne .loopBlackRight
|
||||||
|
ELSE
|
||||||
|
; clear the bitmap column first...
|
||||||
|
ldx #QR_SIZE-1
|
||||||
|
lda #$00
|
||||||
|
.loopBlackRight
|
||||||
|
sta grp0RLst,x
|
||||||
|
dex
|
||||||
|
bpl .loopBlackRight
|
||||||
|
; ...then draw the pattern
|
||||||
|
ldy #4 ; right pattern
|
||||||
|
.loopPattern
|
||||||
|
lda #$ff ; fill pattern
|
||||||
|
jsr DrawPattern
|
||||||
|
cpy #3
|
||||||
|
bcs .loopPattern
|
||||||
|
ldx #0
|
||||||
|
ENDIF
|
||||||
|
; X = 0!
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
ENDIF ; /QR_OVERLAP
|
ENDIF ; /QR_OVERLAP
|
||||||
|
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
MAC _DRAW_FUNC
|
MAC _DRAW_FUNC
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
|
; Draws all function/alignment and timing pattern over existing codewords
|
||||||
ldx #CODE_LST_SIZE-1
|
ldx #CODE_LST_SIZE-1
|
||||||
.loopBlack
|
.loopBlack
|
||||||
lda qrCodeLst,x
|
lda qrCodeLst,x
|
||||||
|
@ -222,6 +303,7 @@ qrGenerator ds QR_DEGREE
|
||||||
jsr InvertPixel
|
jsr InvertPixel
|
||||||
ENDIF
|
ENDIF
|
||||||
ENDM
|
ENDM
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
;===============================================================================
|
;===============================================================================
|
||||||
|
@ -436,7 +518,7 @@ MessageCode
|
||||||
lsr
|
lsr
|
||||||
and #$0f
|
and #$0f
|
||||||
tay
|
tay
|
||||||
; ldy #0
|
; ldy #3
|
||||||
lda MessagePtrLo,y
|
lda MessagePtrLo,y
|
||||||
sta .msgPtr
|
sta .msgPtr
|
||||||
lda MessagePtrHi,y
|
lda MessagePtrHi,y
|
||||||
|
@ -486,7 +568,7 @@ CheckPixel SUBROUTINE
|
||||||
.notMissile
|
.notMissile
|
||||||
cpy #1+8
|
cpy #1+8
|
||||||
bcs .notGRP0L
|
bcs .notGRP0L
|
||||||
IF QR_OVERLAP
|
IF QR_OVERLAP & QR_DIRECT_DRAW
|
||||||
cpx #8 ; bottom left eye (partially) shared with data!
|
cpx #8 ; bottom left eye (partially) shared with data!
|
||||||
bcc .alwaysSet
|
bcc .alwaysSet
|
||||||
ENDIF
|
ENDIF
|
||||||
|
@ -560,13 +642,14 @@ _QR_TOTAL SET _QR_TOTAL + . - BitMapCode
|
||||||
FunctionModulesData
|
FunctionModulesData
|
||||||
; Platform and version specific function module data definition
|
; Platform and version specific function module data definition
|
||||||
|
|
||||||
|
IF QR_DIRECT_DRAW
|
||||||
IF QR_VERSION = 1
|
IF QR_VERSION = 1
|
||||||
ERR ; TODO
|
ERR ; TODO
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
IF QR_VERSION = 2
|
IF QR_VERSION = 2
|
||||||
IF QR_SINGLE_MASK
|
IF QR_SINGLE_MASK
|
||||||
include FuncDataV2S.inc ; TODO: special pattern
|
include FuncDataV2S.inc ; special pattern
|
||||||
ELSE
|
ELSE
|
||||||
include FuncDataV2.inc
|
include FuncDataV2.inc
|
||||||
ENDIF
|
ENDIF
|
||||||
|
@ -574,6 +657,19 @@ FunctionModulesData
|
||||||
|
|
||||||
IF QR_VERSION = 3
|
IF QR_VERSION = 3
|
||||||
ERR ; TODO
|
ERR ; TODO
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
FirstIdxTbl ; for 25 pixel
|
||||||
|
ds 7, 0
|
||||||
|
.byte $fe
|
||||||
|
ds 7, 0
|
||||||
|
.byte $01
|
||||||
|
ds 7, 0
|
||||||
|
IF QR_LEVEL = 0 || QR_LEVEL = 1
|
||||||
|
.byte $bf ; 1st format bit is 1
|
||||||
|
ELSE
|
||||||
|
.byte $3f ; 1st format bit is 0
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
ECHO "QR Code function modules data:", [. - FunctionModulesData]d, "bytes"
|
ECHO "QR Code function modules data:", [. - FunctionModulesData]d, "bytes"
|
||||||
|
@ -584,12 +680,11 @@ _QR_TOTAL SET _QR_TOTAL + . - FunctionModulesData
|
||||||
.byte " QR Code Generator Demo V0.3 - (C)2021 Thomas Jentzsch "
|
.byte " QR Code Generator Demo V0.3 - (C)2021 Thomas Jentzsch "
|
||||||
|
|
||||||
; messages MUST NOT be longer than 26 bytes for version 2, level M!
|
; messages MUST NOT be longer than 26 bytes for version 2, level M!
|
||||||
; Galadriel:
|
|
||||||
MessageTbl
|
MessageTbl
|
||||||
Message0
|
Message0
|
||||||
.byte "2002 - Thrust+ Platinum"
|
.byte "2002 - Thrust+ Platinum"
|
||||||
Message1
|
Message1
|
||||||
.byte "2001 - Jammed "
|
.byte "2001 - Jammed"
|
||||||
Message2
|
Message2
|
||||||
.byte "2005 - SWOOPS!"
|
.byte "2005 - SWOOPS!"
|
||||||
Message3
|
Message3
|
||||||
|
|
|
@ -15,14 +15,14 @@ If you make use of my code or have questions, please let me know.
|
||||||
- code size optimized for minimal RAM and ROM space
|
- code size optimized for minimal RAM and ROM space
|
||||||
- all eight mask pattern supported
|
- all eight mask pattern supported
|
||||||
- Atari 2600 demo code (randomly generates some Atari 2600 related messages)
|
- Atari 2600 demo code (randomly generates some Atari 2600 related messages)
|
||||||
- generator code for Reed-Solomon ECC generator polygons accompanied (can be integrated to compute on-the-fly)
|
- generator code for Reed-Solomon ECC generator polygons accompanied (can also be integrated to compute on-the-fly)
|
||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
- only small, single block QR codes supported
|
- only small (versions 1, 2 and 3), single block QR codes supported
|
||||||
- only byte mode supported
|
- only byte mode supported
|
||||||
- no automatic mask pattern evaluation
|
- no automatic mask pattern evaluation
|
||||||
- tested only for version 2 QR codes (25x25)
|
- tested only for version 2 QR codes (25x25)
|
||||||
- memory organization and pixel checking/drawing has to be implemented platform specific; this includes the finder, alignment and timing pattern
|
- memory organization has to be implemented platform specific
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Copyright © 2021 Thomas Jentzsch. (GPLV3 License)
|
Copyright © 2021 Thomas Jentzsch. (GPLV3 License)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user