aboutsummaryrefslogtreecommitdiff
path: root/src/extract.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-11-13 05:39:38 -0500
committerB. Watson <urchlay@slackware.uk>2025-11-13 05:39:38 -0500
commite2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6 (patch)
tree5195b221457842d781fadcb94331c93058046744 /src/extract.c
downloadunalf-e2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6.tar.gz
initial commit
Diffstat (limited to 'src/extract.c')
-rw-r--r--src/extract.c732
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();
+}