diff options
Diffstat (limited to 'src/extract.c')
| -rw-r--r-- | src/extract.c | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/src/extract.c b/src/extract.c new file mode 100644 index 0000000..079fe7f --- /dev/null +++ b/src/extract.c @@ -0,0 +1,732 @@ +#include <stdio.h> +#include <stdlib.h> +#include <f65.h> +#include "unalf.h" +#include "addrs.h" + +void dpoke(int addr, u16 value) { + mem[addr] = value & 0xff; + mem[addr + 1] = value >> 8; +} + +u16 dpeek(int addr) { + return mem[addr] | (mem[addr + 1] << 8); +} + +void extract_alf(void) { + char *filename; + + /* get ready to call fake 6502 stuff. set up memory like the Atari. */ + dpoke(MEMTOP, 0xbc1f); + + while(read_alf_header()) { + filename = (char *)(mem + alf_hdr_filename); + printf("Uncrunching %s\n", filename); + + if(!(out_file = fopen(filename, "wb"))) { + fprintf(stderr, "%s: ", self); + perror(filename); + exit(1); + } + + uncrunch_file(); + fclose(out_file); + } +} + +static void chksum_err(void) { + fprintf(stderr, "%s: checksum error on file %s\n", self, in_filename); +} + +void uncrunch_file(void) { + lda_i(0x00); + sta(L71AF); + sta(L71B0); + sta(outbuf_len_l); + sta(outbuf_len_h); + sta(L71B6); + sta(L71B7); + sta(L718C); + sta(cksum_l); + sta(cksum_h); + lda_i(0x09); + sta(shift_counter); + lda_i(0x00); + sta(L71AD); + lda_i(0x02); + sta(L71AE); + lda_i(0x00); + sta(stackptr_l); + lda_i(0x60); + sta(stackptr_h); + jsr(setup_io_bufs); + ldx_i(0x10); + lda(inbuf_adr_l); + sta(buf_adr_l); + lda(inbuf_adr_h); + sta(buf_adr_h); + lda(inbuf_len_l); + sta(buf_len_l); + lda(inbuf_len_h); + sta(buf_len_h); + jsr(L7A19); + sty(L718C); + jsr(L79E7); + lda(buf_len_l); + ora(buf_len_h); + bne(L75B1); + rts(); + +L75B1: + jsr(L76D0); + lda(acc16_h); + cmp_i(0x01); + bne(uncrunch_blk); + lda(acc16_l); + cmp_i(0x01); + bne(uncrunch_blk); + jsr(write_output); + lda(alf_hdr_cksum_l); + cmp(cksum_l); + bne(print_emsg_checksum); + lda(alf_hdr_cksum_h); + cmp(cksum_h); + beq(cksum_ok); +print_emsg_checksum: + chksum_err(); +cksum_ok: + rts(); + +uncrunch_blk: + lda(acc16_l); + cmp_i(0x00); + bne(L760B); + lda(acc16_h); + cmp_i(0x01); + bne(L760B); + jsr(init_counters); + jsr(L76D0); + lda(acc16_l); + sta(L717D); + sta(L7179); + lda(acc16_h); + sta(L717E); + sta(L717A); + lda(acc16_l); + sta(L7177); + sta(L7178); + jsr(store_outbyte); + jmp(L75B1); + +L760B: + lda(acc16_l); + sta(L717D); + sta(L7175); + lda(acc16_h); + sta(L717E); + sta(L7176); + lda(acc16_h); + cmp(L717C); + bcc(L7641); + lda(acc16_l); + cmp(L717B); + bcc(L7641); + lda(L7179); + sta(acc16_l); + sta(L717D); + lda(L717A); + sta(acc16_h); + sta(L717E); + lda(L7178); + sta(acc16_l); + jsr(push_acc16); + +L7641: + lda(L717E); + beq(L7670); + lda(L717D); + sta(zp_b4); + lda(L717E); + sta(zp_b5); + jsr(L7899); + ldy_i(0x02); + lda_ind_y(zp_b0); + sta(acc16_l); + jsr(push_acc16); + ldy_i(0x00); + lda_ind_y(zp_b0); + sta(acc16_l); + sta(L717D); + iny(); + lda_ind_y(zp_b0); + sta(acc16_h); + sta(L717E); + jmp(L7641); + +L7670: + lda(L717D); + sta(acc16_l); + sta(L7178); + sta(L7177); + lda(L717E); + sta(acc16_h); + jsr(push_acc16); +L7683: + lda(L71AF); + ora(L71B0); + beq(L7694); + jsr(pop_acc16); + jsr(store_outbyte); + jmp(L7683); + +L7694: + jsr(L78C2); + lda(L7175); + sta(acc16_l); + sta(L7179); + lda(L7176); + sta(acc16_h); + sta(L717A); + lda(L717B); + sta(zp_b4); + lda(L717C); + sta(zp_b5); + cmp(L71AE); + bcc(L76CD); + lda(zp_b4); + cmp(L71AD); + bcc(L76CD); + lda(shift_counter); + cmp_i(0x0C); + beq(L76CD); + inc(shift_counter); + asl(L71AD); + rol(L71AE); +L76CD: + jmp(L75B1); +} + +void L76D0(void) { +L76D0: + lda(L71B6); + sta(zp_b8); + lda(L71B7); + sta(zp_b9); + ldx_i(0x02); +L76DC: + lsr(zp_b9); + ror(zp_b8); + dex(); + bpl(L76DC); + lda(zp_b8); + sta(L71AA); + lda(zp_b9); + sta(L71AB); + lda(inbuf_len_l); + sec(); + sbc(zp_b8); + sta(zp_bc); + lda(inbuf_len_h); + sbc(zp_b9); + sta(zp_bd); + lda(zp_bd); + bne(L770F); + lda(zp_bc); + cmp_i(0x03); + bcs(L770F); + ldx(L718C); + bpl(L771C); + cmp_i(0x02); + bcc(L7712); +L770F: + jmp(L779B); +/* ---------------------------------------------------------------------------- */ +L7712: + #if 0 + ldx_i(0x0A); + ldy_i(0x0A); + jsr(printstr); + jmp(cleanup_and_exit); + #endif + fprintf(stderr, "%s: unknown error (L7712)\n", self); + exit(1); +/* ---------------------------------------------------------------------------- */ +L771C: + tay(); + dey(); + ldx(inbuf_adr_l); + stx(zp_be); + ldx(inbuf_adr_h); + stx(zp_bf); + lda(inbuf_adr_l); + clc(); + adc(zp_b8); + sta(zp_b8); + lda(inbuf_adr_h); + adc(zp_b9); + sta(zp_b9); +L7737: + lda_ind_y(zp_b8); + sta_ind_y(zp_be); + dey(); + bpl(L7737); + lda(inbuf_len_l); + sec(); + sbc(zp_bc); + sta(buf_len_l); + lda(inbuf_len_h); + sbc_i(0x00); + sta(buf_len_h); + lda(inbuf_adr_l); + clc(); + adc(zp_bc); + sta(buf_adr_l); + lda(inbuf_adr_h); + adc_i(0x00); + sta(buf_adr_h); + ldx_i(0x10); + jsr(L7A19); + sty(L718C); + bpl(L7771); + cpy_i(0x88); + beq(L7771); + // jmp(cleanup_and_exit); + exit(0); +/* ---------------------------------------------------------------------------- */ +L7771: + jsr(L79E7); + lda(L71AA); + sta(zp_b8); + lda(L71AB); + sta(zp_b9); + ldx_i(0x02); +L7780: + asl(zp_b8); + rol(zp_b9); + dex(); + bpl(L7780); + lda(L71B6); + sec(); + sbc(zp_b8); + sta(L71B6); + lda(L71B7); + sbc(zp_b9); + sta(L71B7); + jmp(L76D0); +/* ---------------------------------------------------------------------------- */ +L779B: + lda(zp_b8); + sta(zp_bc); + clc(); + adc(inbuf_adr_l); + sta(zp_b8); + lda(zp_b9); + sta(zp_bd); + adc(inbuf_adr_h); + sta(zp_b9); + ldy_i(0x00); + lda(L71B6); + and_i(0x07); + bne(L77E1); + lda_ind_y(zp_b8); + sta(acc16_h); + iny(); + lda_ind_y(zp_b8); + sta(acc16_l); +L77C0: + lda_i(0x0F); + sec(); + sbc(shift_counter); + tax(); +L77C7: + lsr(acc16_h); + ror(acc16_l); + dex(); + bpl(L77C7); + lda(shift_counter); + clc(); + adc(L71B6); + sta(L71B6); + lda_i(0x00); + adc(L71B7); + sta(L71B7); + rts(); + +/* ---------------------------------------------------------------------------- */ +L77E1: + ldx_i(0x02); +L77E3: + lda_ind_y(zp_b8); + sta_abs_x(L7189); + iny(); + dex(); + bpl(L77E3); + lda(L71B6); + and_i(0x07); + tax(); + dex(); +L77F3: + asl(L7189); + rol(L718A); + rol(L718B); + dex(); + bpl(L77F3); + lda(L718A); + sta(acc16_l); + lda(L718B); + sta(acc16_h); + jmp(L77C0); +} + +void L7A19(void) { +L7A19: + lda(alf_hdr_compsize2); + ora(alf_hdr_compsize3); + beq(L7A28); +L7A21: + jsr(readblock); + Y = 1; /* CIO would set this */ + jsr(L7A5D); + rts(); +L7A28: + lda(alf_hdr_compsize1); + cmp(buf_len_h); + bcc(L7A40); + beq(L7A34); + bcs(L7A21); +L7A34: + lda(alf_hdr_compsize0); + cmp(buf_len_l); + bcc(L7A40); + beq(L7A40); + bcs(L7A21); +L7A40: + lda(alf_hdr_compsize0); + sta(buf_len_l); + lda(alf_hdr_compsize1); + sta(buf_len_h); + lda(buf_len_l); + ora(buf_len_h); + beq(L7A57); + jsr(readblock); + Y = 1; /* CIO would set this */ +L7A57: + ldy_i(0x88); + jsr(L7A5D); + rts(); +} + +void L7A5D(void) { +L7A5D: + lda(alf_hdr_compsize0); + sec(); + sbc(buf_len_l); + sta(alf_hdr_compsize0); + lda(alf_hdr_compsize1); + sbc(buf_len_h); + sta(alf_hdr_compsize1); + lda(alf_hdr_compsize2); + sbc_i(0x00); + sta(alf_hdr_compsize2); + rts(); +} + +void setup_io_bufs(void) { +setup_io_bufs: + lda(MEMTOP_lo); + sec(); + sbc_i(0xDC); + sta(inbuf_len_l); + lda(MEMTOP_hi); + sbc_i(0x7F); + sta(inbuf_len_h); + lsr(inbuf_len_h); + ror(inbuf_len_l); + lda(inbuf_len_h); + cmp_i(0x1F); + bcc(L79A0); + lda_i(0x00); + sta(inbuf_len_l); + lda_i(0x1F); + sta(inbuf_len_h); +L79A0: + lda_i(0xDC); + sta(inbuf_adr_l); + lda_i(0x7F); + sta(inbuf_adr_h); + lda_i(0xDC); + clc(); + adc(inbuf_len_l); + sta(outbuf_adr_l); + sta(outbuf_ptr_l); + lda_i(0x7F); + adc(inbuf_len_h); + sta(outbuf_adr_h); + sta(outbuf_ptr_h); + rts(); +} + +void init_counters(void) { +init_counters: + lda_i(0x09); + sta(shift_counter); + lda_i(0x00); + sta(L71AD); + lda_i(0x02); + sta(L71AE); + lda_i(0x02); + sta(L717B); + lda_i(0x01); + sta(L717C); + rts(); +} + +/* save decrunched byte in outbuf, update checksum, write outbuf if full */ +void store_outbyte(void) { + ldy_i(0x00); + lda(acc16_l); + sta_ind_y(outbuf_ptr_l); + clc(); + adc(cksum_l); + sta(cksum_l); + lda_i(0x00); + adc(cksum_h); + sta(cksum_h); + inc(outbuf_ptr_l); + bne(out_ptr_hi_ok); + inc(outbuf_ptr_h); +out_ptr_hi_ok: + inc(outbuf_len_l); + bne(out_len_hi_ok); + inc(outbuf_len_h); +out_len_hi_ok: + lda(outbuf_len_h); + cmp(inbuf_len_h); + bcc(outbuf_not_full); + lda(outbuf_len_l); + cmp(inbuf_len_l); + bcc(outbuf_not_full); + lda(outbuf_adr_l); + sta(buf_adr_l); + lda(outbuf_adr_h); + sta(buf_adr_h); + lda(outbuf_len_l); + sta(buf_len_l); + lda(outbuf_len_h); + sta(buf_len_h); + /* TODO: call C writeblock() */ + ldx_i(0x30); + jsr(writeblock); + bpl(init_outbuf); + #if 0 +/* ldx #<emsg_checksum : ldy #>emsg_checksum */ +print_emsg_write_output_2: + ldx_i(0xD5); + ldy_i(0x72); + jsr(printstr); +cleanup_and_exit: + pla(); + pla(); + pla(); + pla(); + jmp(exit); + #endif + chksum_err(); + exit(1); +/* ---------------------------------------------------------------------------- */ +init_outbuf: + lda(outbuf_adr_l); + sta(outbuf_ptr_l); + lda(outbuf_adr_h); + sta(outbuf_ptr_h); + lda_i(0x00); + sta(outbuf_len_l); + sta(outbuf_len_h); +outbuf_not_full: + rts(); +} + + +/* ---------------------------------------------------------------------------- */ +/* push 2 byte 'register' to software stack */ +void push_acc16(void) { +push_acc16: + ldy_i(0x00); + lda(acc16_l); + sta_ind_y(stackptr_l); + iny(); + lda(acc16_h); + sta_ind_y(stackptr_l); + lda(stackptr_l); + clc(); + adc_i(0x02); + sta(stackptr_l); + bcc(L790C); + inc(stackptr_h); +L790C: + lda(stackptr_h); + cmp_i(0x70); + bcc(L791C); + #if 0 +/* ldx #<emsg_stk_overrun : ldy #>emsg_stk_overrun */ +print_emsg_stk_overrun: + ldx_i(0x25); + ldy_i(0x79); + jsr(printstr); + jmp(cleanup_and_exit); + #endif + fprintf(stderr, "%s: stack overrun\n", self); + exit(1); +/* ---------------------------------------------------------------------------- */ +L791C: + inc(L71AF); + bne(L7924); + inc(L71B0); +L7924: + rts(); +} + +void pop_acc16(void) { +/* pop 2 byte 'register' from software stack */ +pop_acc16: + lda(stackptr_l); + sec(); + sbc_i(0x02); + sta(stackptr_l); + lda(stackptr_h); + sbc_i(0x00); + sta(stackptr_h); + ldy_i(0x00); + lda_ind_y(stackptr_l); + sta(acc16_l); + iny(); + lda_ind_y(stackptr_l); + sta(acc16_h); + lda(stackptr_h); + cmp_i(0x60); + bcs(L796C); + #if 0 +/* ldx #<emsg_stk_underrun : ldy #>emsg_stk_underrun */ +print_emsg_stk_underrun: + ldx_i(0x34); + ldy_i(0x79); + jsr(printstr); + jmp(cleanup_and_exit); + #endif + fprintf(stderr, "%s: stack underrun\n", self); + exit(1); +/* ---------------------------------------------------------------------------- */ +L796C: + lda(L71AF); + bne(L7974); + dec(L71B0); +L7974: + dec(L71AF); + rts(); +} + +void L79E7(void) { +L79E7: + lda(buf_adr_l); + clc(); + adc(buf_len_l); + sta(zp_be); + lda(buf_adr_h); + adc(buf_len_h); + sta(zp_bf); + ldx_i(0x02); + bne(L7A0A); +L79FC: + ldy_i(0x00); + tya(); + sta_ind_y(zp_be); + inc(zp_be); + bne(L7A07); + inc(zp_bf); +L7A07: + dex(); + bmi(L7A18); +L7A0A: + lda(zp_bf); + cmp(outbuf_adr_h); + bcc(L79FC); + lda(zp_be); + cmp(outbuf_adr_l); + bcc(L79FC); +L7A18: + rts(); +} + +void L7899(void) { +L7899: + lda(zp_b4); + sta(zp_b0); + lda(zp_b5); + sta(zp_b1); + asl(zp_b0); + rol(zp_b1); + lda(zp_b0); + clc(); + adc(zp_b4); + sta(zp_b0); + lda(zp_b1); + adc(zp_b5); + sta(zp_b1); + lda(zp_b0); + clc(); + adc(L7181); + sta(zp_b0); + lda(zp_b1); + adc(L7182); + sta(zp_b1); + rts(); +} + +void L78C2(void) { +L78C2: + lda(L717B); + sta(zp_b4); + lda(L717C); + sta(zp_b5); + jsr(L7899); + lda(L7177); + sta(acc16_l); + ldy_i(0x02); + sta_ind_y(zp_b0); + lda(L7179); + sta(acc16_l); + lda(L717A); + sta(acc16_h); + ldy_i(0x00); + lda(acc16_l); + sta_ind_y(zp_b0); + iny(); + lda(acc16_h); + sta_ind_y(zp_b0); + inc(L717B); + bne(L78F5); + inc(L717C); +L78F5: + rts(); +} + +void write_output(void) { +write_output: + lda(outbuf_len_l); + ora(outbuf_len_h); + bne(have_output); + rts(); +/* ---------------------------------------------------------------------------- */ +have_output: + lda(outbuf_adr_l); + sta(buf_adr_l); + lda(outbuf_adr_h); + sta(buf_adr_h); + lda(outbuf_len_l); + sta(buf_len_l); + lda(outbuf_len_h); + sta(buf_len_h); + ldx_i(0x30); + jsr(writeblock); + rts(); +} |
