Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Context:
- ; - CRCs are stored little-endian starting at $0150
- ; - One CRC is computed per ROM bank
- ; - Assumes at most 256 ROM banks
- ; - Switches to an invalid ROM bank at the end, but it's harmless since the ROM is not accessed
- ; - Uses `rst bankswitch` to switch ROM banks, but that can be replaced with whatever you want
- ; - Uses $D000 - $D1FF as precomputation tables, but you can move this anywhere (storing it in ROM is probably a bad idea)
- ; - Stores results at $C000 - $C0XX; for ROM bank $RR, the byte at $C0RR will be set to 0 if the CRC check succeeded, or be set to $AF if the check failed
- ; - Clobbers every register known to mankind
- wCRCSuccess equ $C000
- wCRCLowTable equ $D000
- wCRCHighTable equ $D100
- CRCs equ $0150
- CRCsEnd equ $0150 + 2 * NB_ROM_BANKS
- ; Perform CRC verification
- CRC_POLYNOM equ $1021
- ; Compute CRC table to speed up later calculations
- ld de, wCRCHighTable
- .computeCRCTable
- ld h, e
- ld l, 0
- ld c, 8
- .bitLoop
- add hl, hl
- jr nc, .bitClear
- ld a, l
- xor LOW(CRC_POLYNOM)
- ld l, a
- ld a, h
- xor HIGH(CRC_POLYNOM)
- ld h, a
- .bitClear
- dec c
- jr nz, .bitLoop
- dec d
- ld a, l
- ld [de], a
- inc d
- ld a, h
- ld [de], a
- inc e
- jr nz, .computeCRCTable
- ld hl, $0000
- ld c, l ; ld c, 0 ; Low byte of pointer to result
- .CRCLoop
- ld b, $FF ; CRC low
- ld e, b ; lb de, HIGH(wCRCHighTable), $FF ; CRC high & pointer to table
- jr .feedByte ; Skip "skip hack"
- .skipBytes
- ld l, LOW(CRCsEnd)
- .feedByte
- ; Update CRC in `eb`
- ld a, [hli]
- xor e ; XOR with high byte
- ld e, a ; Store back
- dec d ; Switch to low byte table
- ld a, [de] ; Get low byte mask
- xor b ; XOR with low byte
- ld b, a ; Store back
- inc d ; Switch to high byte table
- ld a, [de] ; Get high byte mask
- xor e ; XOR with high byte
- ld e, a ; Store back
- ; Check if we should skip
- ld a, h
- dec a
- ld a, l
- jr nz, .dontSkipBytes
- cp LOW($014E)
- jr z, .skipBytes
- .dontSkipBytes
- ; Check if reached end of a bank
- and a
- jr nz, .feedByte
- ld a, h
- and %111111
- jr nz, .feedByte
- ; Now check if the CRC matches
- ; Get pointer to current
- ld a, c
- add a, LOW(CRCs) >> 1
- add a, a
- ld l, a
- adc a, HIGH(CRCs)
- sub l
- ld h, a
- ld a, [hli]
- cp b
- jr nz, .CRCFail
- ld a, [hli]
- cp e
- jr z, .CRCSuccess
- .CRCFail
- db $3E ; ld a, $AF
- .CRCSuccess
- xor a
- ld b, HIGH(wCRCSuccess)
- ld [bc], a
- ; Prepare next bank
- ld hl, $4000
- inc c
- ld a, c
- rst bankswitch ; Will switch to a bad bank on last iter, but that's not a problem.
- ; ld a, c
- cp NB_ROM_BANKS
- jr nz, .CRCLoop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement