119 lines
1.6 KiB
ArmAsm
119 lines
1.6 KiB
ArmAsm
; CRC-32 checksum calculation
|
|
|
|
zp_res checksum,4
|
|
zp_byte checksum_temp
|
|
zp_byte checksum_off_
|
|
|
|
; Turns CRC updating on/off. Allows nesting.
|
|
; Preserved: A, X, Y
|
|
crc_off:
|
|
dec checksum_off_
|
|
rts
|
|
|
|
crc_on: inc checksum_off_
|
|
beq :+
|
|
jpl internal_error ; catch unbalanced crc calls
|
|
: rts
|
|
|
|
|
|
; Initializes checksum module. Might initialize tables
|
|
; in the future.
|
|
init_crc:
|
|
jmp reset_crc
|
|
|
|
|
|
; Clears checksum and turns it on
|
|
; Preserved: X, Y
|
|
reset_crc:
|
|
lda #0
|
|
sta checksum_off_
|
|
lda #$FF
|
|
sta checksum
|
|
sta checksum + 1
|
|
sta checksum + 2
|
|
sta checksum + 3
|
|
rts
|
|
|
|
|
|
; Updates checksum with byte in A (unless disabled via crc_off)
|
|
; Preserved: A, X, Y
|
|
; Time: 357 clocks average
|
|
update_crc:
|
|
bit checksum_off_
|
|
bmi update_crc_off
|
|
update_crc_:
|
|
pha
|
|
stx checksum_temp
|
|
eor checksum
|
|
ldx #8
|
|
@bit: lsr checksum+3
|
|
ror checksum+2
|
|
ror checksum+1
|
|
ror a
|
|
bcc :+
|
|
sta checksum
|
|
lda checksum+3
|
|
eor #$ED
|
|
sta checksum+3
|
|
lda checksum+2
|
|
eor #$B8
|
|
sta checksum+2
|
|
lda checksum+1
|
|
eor #$83
|
|
sta checksum+1
|
|
lda checksum
|
|
eor #$20
|
|
: dex
|
|
bne @bit
|
|
sta checksum
|
|
ldx checksum_temp
|
|
pla
|
|
update_crc_off:
|
|
rts
|
|
|
|
|
|
; Prints checksum as 8-character hex value
|
|
print_crc:
|
|
jsr crc_off
|
|
|
|
; Print complement
|
|
ldx #3
|
|
: lda checksum,x
|
|
eor #$FF
|
|
jsr print_hex
|
|
dex
|
|
bpl :-
|
|
|
|
jmp crc_on
|
|
|
|
|
|
; EQ if checksum matches CRC
|
|
; Out: A=0 and EQ if match, A>0 and NE if different
|
|
; Preserved: X, Y
|
|
.macro is_crc crc
|
|
jsr_with_addr is_crc_,{.dword crc}
|
|
.endmacro
|
|
|
|
is_crc_:
|
|
tya
|
|
pha
|
|
|
|
; Compare with complemented checksum
|
|
ldy #3
|
|
: lda (ptr),y
|
|
sec
|
|
adc checksum,y
|
|
bne @wrong
|
|
dey
|
|
bpl :-
|
|
pla
|
|
tay
|
|
lda #0
|
|
rts
|
|
|
|
@wrong:
|
|
pla
|
|
tay
|
|
lda #1
|
|
rts
|