backyard/6502_name_codec/decode_v3.asm

211 lines
3.7 KiB
NASM

// included by decode.asm
// cycles on extra-padded "Elizabeth Mary Patricia James Robert":
// with double-dec: (dec per bit)
// 7359-55=7304 (includes jsr and rts)
// program size: 0xE0
// with single-dec: (dec per pair)
// 6759-55=6704 (includes jsr and rts)
// program size: 0xDA
// with tax reduction:
// program size: 0xD4
// with single death:
// program size: 0xD3
// with TYA instead of LDA #0:
// program size: 0xD2
// with reduced ORA:
// 6612-55=6557 (includes jsr and rts)
// program size: 0xD0
// with stuff crammed into decode_advance:
// program size: 0xBE
// without a shim to jump back to decode_xx from decode_nextbytew:
// program size: 0xBD
// without any JMPs:
// 6564-55=6509 (includes jsr and rts)
// program size: 0xBC
// without any extraneous DBs:
// program size: 0xBB
// instructions: 2359-17=2342 (includes jsr and rts)
// with sty instead of tya + sta:
// cycles: 6466-55=6411
// instrs: 2310-17=2293
// program size: 0xBA (186, 22 of which are the end-of-string comparisons)
decode_advance:
inc $02
beq die // never branch (unless page boundary)
when_to_stop()
ldy #0
lda ($02),y // load from input
tax // stash for after branch
lda #4 // pairs remaining
sta $04 // write pairs remaining
rts
decode_exit:
pla
pla
rts
decode_begin_next:
pla
pla
decode:
// NOTE: output/input pointers cannot cross page boundaries.
// that means the effective longest lengths of output/input are 256/192 bytes.
lda #4 // pairs remaining
sta $04 // write pairs remaining
ldy #0
lda ($02),y // load from input
tax // stash for after branch
decode_xx: // decode from offset 0, unknown code length
//tya // lda #0
sty $05 // write data so far (nothing)
txa
asl
bcs decode_1x
decode_0x:
asl
tax
bcs decode_01
// fallthru to decode_00
decode_00:
lda #%00000000
bpl decode_read2 // always branch
decode_01:
lda #%00000100
bpl decode_read2 // always branch
decode_1x:
asl
tax
bcs decode_11
// fallthru to decode_10
decode_10:
lda #%00001000
bpl decode_read2 // always branch
decode_11:
lda #%00010000
bpl decode_read4 // always branch
die:
db $F2
decode_nextbytew:
jsr decode_advance
bpl decode_xx // always branch
decode_write:
ora $05
// decode_common stuff:
tay
lda decode_lut0xxx,y
ldy #0
sta ($00),y // write to output
inc $00 // advance output
beq die // never branch (unless page boundary)
dec $04 // decrement pairs remaining
bne decode_xx // branch if we're good, otherwise...
beq decode_nextbytew // (always) branch if we need more pairs
decode_read2_and_ora:
ora $05
decode_read2:
sta $05
dec $04 // decrement pairs remaining
beq decode_nextbyte2
decode_read2_again:
// we have at least one pair left to read from X
txa
asl
bcs decode_read2_1x
decode_read2_0x:
asl
tax
bcs decode_read2_01
decode_read2_00:
lda #%00000000
bpl decode_write // always branch
decode_read2_01:
lda #%00000001
bpl decode_write // always branch
decode_read2_1x:
asl
tax
bcs decode_read2_11
decode_read2_10:
lda #%00000010
bpl decode_write // always branch
decode_read2_11:
lda #%00000011
bpl decode_write // always branch
decode_read4:
sta $05
dec $04 // decrement pairs remaining
beq decode_nextbyte4
decode_read4_again:
// we have at least one pair left to read from X
txa
asl
bcs decode_read4_1x
decode_read4_0x:
asl
tax
bcs decode_read4_01
decode_read4_00:
lda #%00000000
bpl decode_read2_and_ora // always branch
decode_read4_01:
lda #%00000100
bpl decode_read2_and_ora // always branch
decode_read4_1x:
asl
tax
bcs decode_read4_11
decode_read4_10:
lda #%00001000
bpl decode_read2_and_ora // always branch
decode_read4_11:
lda #%00001100
bpl decode_read2_and_ora // always branch
decode_nextbyte2:
jsr decode_advance
bpl decode_read2_again // always branch
decode_nextbyte4:
jsr decode_advance
bpl decode_read4_again // always branch
done:
db $F2
// vim:ft=snes_bass