backyard/6502_name_codec/decode_v6.asm

147 lines
2.7 KiB
NASM

// included by decode.asm
// stats on extra-padded "Elizabeth Mary Patricia James Robert":
// exiting after 2456 instructions and 6714 cycles. 0x84
// with a bunch of optimization: (yeah i forgot)
// exiting after 2483 instructions and 6599 cycles. 0x74
// cycles: 6599-55=6544
// instrs: 2483-17=2466
// program size: 0x74 (116, 22 of which are the end-of-string comparisons)
// with decode_read4_after moved further down:
// exiting after 2459 instructions and 6527 cycles. 0x74
// cycles: 6527-55=6472
// instrs: 2459-17=2442
// program size: 0x74 (116, 22 of which are the end-of-string comparisons)
constant decode_internalize(1)
if decode_internalize {
decode_ilut:
db "ETAOINSHRDLU????CMFPGWYBVKXJQZ. "
}
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
decode_xx:
// NOTE: Y is always 0 here, if that helps at all.
tax // stash for after branch
and #%11000000
lsr
lsr
lsr
cmp #%00011000
ror
//bcc decode_read_either // always branch
decode_read_either:
sta $05
dec $04 // decrement pairs remaining
bne +
jsr decode_advance
bpl decode_read_again // always branch
// we have at least one pair left to read from X
+;
txa
asl
asl
decode_read_again:
tax
rol
rol
rol
and #%00000011
ora $05
bmi decode_read4_after
//cmp #%00011100
//bcs decode_read4_after
// read2, nothing left to do, so just write it
//bpl decode_write // always branch
decode_write:
// decode_common stuff:
tay
if decode_internalize {
lda decode_ilut,y
} else {
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
beq + // branch if we need more pairs
txa
asl
asl
bvc decode_xx // always branch (FIXME: might depend on output address)
+;
if 1 {
jsr decode_advance
bpl decode_xx // always branch
} else {
// 1 cycle(?) slower and 1 byte larger
lda #(decode_xx - 1) >> 8
pha
lda #(decode_xx - 1) & 0xFF
pha
// fallthru to decode_advance
}
decode_read4_after:
and #%00000011
asl
asl
ora #%00010000
bpl decode_read_either // always branch
decode_advance:
inc $02 // advance input
beq die // never branch (unless page boundary)
when_to_stop()
ldy #0
lda ($02),y // load from input
ldx #4 // pairs remaining
stx $04 // write pairs remaining
rts // A = *input; X = 4; Y = 0
decode_exit:
if 1 {
// 4+4=8 cycles, 2 bytes:
pla
pla
} else {
// 3+2=5 cycles, 3 bytes, also penalty for having to set up $06 in the first place:
ldx $06
txs
}
rts
die:
db $F2
done:
db $D2
// vim:ft=snes_bass