In /emu_65c02 implement a chice of *.bin, *.a2bin or *.ihx load format, in /loader...
authorNick Downing <nick@ndcode.org>
Mon, 20 Jun 2022 08:29:19 +0000 (18:29 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 20 Jun 2022 08:29:19 +0000 (18:29 +1000)
17 files changed:
.gitignore
disasm/Makefile
disasm/a2_hex2bin.py
disasm/star_blazer.asm.patch
emu_65c02/Makefile
emu_65c02/emu_65c02.c
emu_65c02/rom2hex.py [new file with mode: 0755]
loader/Makefile
loader/a2_load.py [new file with mode: 0755]
loader/dejunk.py
loader/lzss_decode.py
loader/lzss_encode.py
loader/recrack.py
test/Makefile
test/dhgr.asm
test/dhgr_viewer.asm [new file with mode: 0644]
test/dhr2hex.py [new file with mode: 0755]

index 9742e4f..ef98ff3 100644 (file)
@@ -1,3 +1,4 @@
+*.a2bin
 *.bin
 *.hdr
 *.hlr
index 9f32605..9564fba 100644 (file)
@@ -19,22 +19,22 @@ shape4.png \
 shape5.png \
 shape6.png
 
-star_blazer.dsk: ../util/bootable.dsk star_blazer_lzss.bin
+star_blazer.dsk: ../util/bootable.dsk star_blazer_lzss.a2bin
        cp ../util/bootable.dsk $@
-       ${DOS33} $@ SAVE B star_blazer_lzss.bin "STAR BLAZER LZSS"
+       ${DOS33} $@ SAVE B star_blazer_lzss.a2bin "STAR BLAZER LZSS"
 
-star_blazer_lzss.bin: \
-star_blazer.bin \
+star_blazer_lzss.a2bin: \
+star_blazer.a2bin \
 ../loader/lzss_loader.bin \
-../loader/star_blazer_recrack_lzss.bin
+../loader/star_blazer_recrack_lzss.a2bin
        ../loader/lzss_encode.py ${LZSS_LOADER} ../loader/lzss_loader.bin $< $@
-       -diff -q ../loader/star_blazer_recrack_lzss.bin $@
+       -diff -q ../loader/star_blazer_recrack_lzss.a2bin $@
 
-star_blazer.bin: \
+star_blazer.a2bin: \
 star_blazer.ihx \
-../loader/star_blazer_recrack.bin
+../loader/star_blazer_recrack.a2bin
        ./a2_hex2bin.py $< $@
-       -diff -q ../loader/star_blazer_recrack.bin $@
+       -diff -q ../loader/star_blazer_recrack.a2bin $@
 
 star_blazer.ihx: star_blazer.rel
        # add for DHGR: -b data1=0xd000
@@ -59,9 +59,9 @@ shape_data.inc
 star_blazer.asm: \
 trace.txt \
 star_blazer.txt \
-../loader/star_blazer_recrack.bin \
+../loader/star_blazer_recrack.a2bin \
 star_blazer.asm.patch
-       ./disasm.py star_blazer.txt ../loader/star_blazer_recrack.bin $@ <trace.txt
+       ./disasm.py star_blazer.txt ../loader/star_blazer_recrack.a2bin $@ <trace.txt
        cp $@ $@0
        patch $@ <$@.patch
 
@@ -91,7 +91,7 @@ shape_index.inc: shape.txt shape0.png
 shape_data.inc: shape.txt shape0.png
        ./shape_compile.py --data shape0.png <$< >$@
 
-shape0.png: ../loader/star_blazer_recrack.bin
+shape0.png: ../loader/star_blazer_recrack.a2bin
        ./shape_extract.py $< $@
 
 shape1.png: shape0.png
@@ -124,6 +124,7 @@ shape0c.png: shape_dhgr.png
 .PHONY: clean
 clean:
        rm -f \
+*.a2bin \
 *.bin \
 *.hlr \
 *.ihx \
index b885d7f..e951112 100755 (executable)
@@ -8,10 +8,10 @@ EXIT_SUCCESS = 0
 EXIT_FAILURE = 1
 
 if len(sys.argv) < 3:
-  print(f'usage: {sys.argv[0]:s} in.ihx out.bin')
+  print(f'usage: {sys.argv[0]:s} in.ihx out.a2bin')
   sys.exit(EXIT_FAILURE)
 in_ihx = sys.argv[1]
-out_bin = sys.argv[2]
+out_a2bin = sys.argv[2]
 
 intelhex = IntelHex(in_ihx)
 segments = [j for i in intelhex.segments() for j in i]
@@ -25,5 +25,5 @@ intelhex.padding = 0
 bin = list(intelhex.tobinstr(load_addr, load_addr + load_size - 1))
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-with open(out_bin, 'wb') as fout:
+with open(out_a2bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index e408121..e514d05 100644 (file)
@@ -1,15 +1,15 @@
---- star_blazer.asm0   2022-06-15 00:26:36.295842665 +1000
-+++ star_blazer.asm    2022-06-16 16:12:05.836083121 +1000
+--- star_blazer.asm0   2022-06-20 17:46:09.264188937 +1000
++++ star_blazer.asm    2022-06-20 17:49:28.980190983 +1000
 @@ -1,3 +1,8 @@
 +ALIGN = 1
 +DHGR = 0
 +PIXEL_SHAPE = 0
 +SHAPE = 1
 +
+ hires_screen = 0x2000                 ; 2000
  hw_kbd = 0xc000                               ; c000
  hw_kbdstrb = 0xc010                   ; c010
- hw_spkr = 0xc030                      ; c030
-@@ -11,6 +16,34 @@
+@@ -12,6 +17,34 @@
  hw_ptrig = 0xc070                     ; c070
  rom_pread = 0xfb1e                    ; fb1e
  
@@ -43,8 +43,8 @@
 +
        .area   zpage
  
-       .ds     0x20                    ; 0000
-@@ -49,6 +82,14 @@
+       .ds     0x22                    ; 0000
+@@ -48,6 +81,14 @@
  draw_y:       .ds     1                       ; 008a rw
  video_line_ptr:
        .ds     2                       ; 008b rw
  draw_misc_mask:
        .ds     1                       ; 008d rw
  draw_misc_mask_temp:
-@@ -189,6 +230,7 @@
+@@ -188,6 +229,7 @@
        .ds     0x70                    ; 0780 rw
  
        .area   text
 +text_start:
  
-       jmp     loc_2000                ; -> 09fd -> 2000 r
+       jmp     recrack_loader          ; -> 09fd -> 9ded r
  sign_extend_a_to_ya:
-@@ -1073,7 +1115,7 @@
+@@ -1072,7 +1114,7 @@
        tsx                             ; 1095 -> 1097 -> 1098 r
        stx     *microcode_sp           ; 1097 -> 1098 -> 109a r
        ldx     *microcode_object_c9    ; 1098 -> 109a -> 109c r
@@ -76,7 +76,7 @@
        sta     *microcode_object_cc    ; 109c -> 109f -> 10a1 r
  loc_10a1:
        ldy     #0x00                   ; 1090,109f -> 10a1 -> 10a3 r
-@@ -1100,7 +1142,7 @@
+@@ -1099,7 +1141,7 @@
        jsr     do_microcode_test1      ; 10c6 -> 10c8 -> 106a r s=f7..f9,02
        bne     3$                      ; 107b -> 10cb -> 10c0 r z=0
  loc_10cd:
@@ -85,7 +85,7 @@
        rts                             ; 10cd -> 10d0 -> 123e,143a,1615,1629,1633,1649,165b,1759 r s=f7..fd,02
  sub_10d1:
        beq     rts_10ec                ; 1216,123b,1260,1285 -> 10d1 -> 10d3,10ec r z=0..1
-@@ -1986,6 +2028,9 @@
+@@ -1985,6 +2027,9 @@
        bit     *vec_draw_misc_from_table ; 17d1 -> 17d4 -> 17d6 r
        ora     hw_pb1                  ; 17d4 -> 17d6 -> 17d9 r
        bpl     1$                      ; 17d6 -> 17d9 -> 17f2 r n=0
@@ -95,7 +95,7 @@
        ldx     #0x01                   ; 17db r
  0$:   jsr     rom_pread               ; 17dd r
        cpy     #0xff                   ; 17e0 r
-@@ -1996,18 +2041,14 @@
+@@ -1995,18 +2040,14 @@
        sta     bvar_179e               ; 17e9 r
        sta     bvar_17a3               ; 17ec r
        sta     bvar_1e0e               ; 17ef r
  divide_a_by_y:
        sta     *accumulator + 1        ; 0a90,0aa0,0ab5,0ad5 -> 1800 -> 1802 r
        lda     #0x00                   ; 1800 -> 1802 -> 1804 r
-@@ -2072,10 +2113,12 @@
+@@ -2071,10 +2112,12 @@
        lda     *result + 1             ; 186e r
        ldy     *result + 2             ; 1870 r
        rts                             ; 1872 r
  random_init:
        lda     *random_seed            ; 16ae -> 187a -> 187c r
        ora     #0x01                   ; 187a -> 187c -> 187e r
-@@ -2234,16 +2277,31 @@
-       ldx     #>loc_2000              ; 199b -> 199d -> 199f r
+@@ -2233,16 +2276,31 @@
+       ldx     #>hires_screen          ; 199b -> 199d -> 199f r
        stx     *video_line_ptr + 1     ; 199d -> 199f -> 19a1 r
        tay                             ; 199f -> 19a1 -> 19a2 r
 -0$:   sta     [*video_line_ptr],y     ; 19a1,19a5,19aa -> 19a2 -> 19a4 r y=00..ff
        rts                             ; 19b5 -> 19b8 -> 1713 r s=fd
  video_clear_rectangle:
        ldx     *clip_y0                ; 1064 -> 19b9 -> 19bb r
-@@ -2253,7 +2311,13 @@
+@@ -2252,7 +2310,13 @@
        sta     *video_line_ptr + 1     ; 19c0 -> 19c3 -> 19c5 r
        ldy     *clip_x0                ; 19c3 -> 19c5 -> 19c7 r
        lda     #0x00                   ; 19c5 -> 19c7 -> 19c9 r
        iny                             ; 19c9 -> 19cb -> 19cc r
        cpy     *clip_x1                ; 19cb -> 19cc -> 19ce r y=6d..94
        bcc     1$                      ; 19cc -> 19ce -> 19c9,19d0 r c=0..1
-@@ -2301,6 +2365,7 @@
+@@ -2300,6 +2364,7 @@
        sta     object1080_y0 - 0x10,x  ; 1a1b -> 1a1e -> 1a21 r x=10..7f
        adc     #0x01                   ; 1a1e -> 1a21 -> 1a23 r c=0..1 d=0
        sta     object1080_y1 - 0x10,x  ; 1a21 -> 1a23 -> 1a26 r x=10..7f
        rts                             ; 1a23 -> 1a26 -> 1076,1179,1602 r s=f1..f9,02
  pixel_data_table_left:
        .db     0x83                    ; 1a27 r
-@@ -2383,14 +2448,17 @@
+@@ -2382,14 +2447,17 @@
        lda     object1080_onscreen_shape_ptr_hi - 0x10,x ; 1aa5 -> 1aa7 -> 1aaa r x=20..4f
        ora     [*video_line_ptr],y     ; 1aa7 -> 1aaa -> 1aac r y=6d..93,02
        sta     [*video_line_ptr],y     ; 1aaa -> 1aac -> 1aae r y=6d..93,02
        lda     object1080_y0 - 0x10,x  ; 1ab9 -> 1abb -> 1abe r x=14..77
        cmp     object1080_y1 - 0x10,x  ; 1abb -> 1abe -> 1ac1 r a=11..d4 x=14..77
        bcs     rts_1aae                ; 1abe -> 1ac1 -> 1ac3 r c=0
-@@ -2454,8 +2522,14 @@
+@@ -2453,8 +2521,14 @@
        cmp     *draw_x1                ; 1b49 -> 1b4b -> 1b4d r a=94
        bcc     8$                      ; 1b4b -> 1b4d -> 1b4f,1b83 r c=0..1
        lda     object1080_onscreen_shape_ptr_lo - 0x10,x ; 1b4d -> 1b4f -> 1b52 r x=14..77
        sta     7$ + 1                  ; 1b55 -> 1b58 -> 1b5b r
        ldx     #0x00                   ; 1b58 -> 1b5b -> 1b5d r
        ldy     *draw_y                 ; 1b5b -> 1b5d -> 1b5f r
-@@ -2464,7 +2538,17 @@
+@@ -2463,7 +2537,17 @@
        lda     video_line_table_hi - 0x20,y ; 1b62 -> 1b64 -> 1b67 r y=28..cf
        sta     *video_line_ptr + 1     ; 1b64 -> 1b67 -> 1b69 r
        ldy     *draw_x0                ; 1b67 -> 1b69 -> 1b6b r
  7$:   .dw     shape_12_exhaust0 + 0x12 ; 1b6c rw
        ora     [*video_line_ptr],y     ; 1b6b -> 1b6e -> 1b70 r y=6c..93
        sta     [*video_line_ptr],y     ; 1b6e -> 1b70 -> 1b72 r y=6c..93
-@@ -2480,14 +2564,23 @@
+@@ -2479,14 +2563,23 @@
        rts                             ; 1b80 -> 1b82 -> 15cd r s=fb
  8$:   inc     object1080_onscreen_clipped - 0x10,x ; 1b3b,1b41,1b47,1b4d -> 1b83 -> 1b86 r x=14..77
        lda     object1080_onscreen_shape_ptr_lo - 0x10,x ; 1b83 -> 1b86 -> 1b89 r x=14..77
        sta     *video_line_ptr + 1     ; 1b9b -> 1b9e -> 1ba0 r
        ldy     *draw_x0                ; 1b9e -> 1ba0 -> 1ba2 r
  10$:  lda     *draw_y                 ; 1ba0,1bbf -> 1ba2 -> 1ba4 r
-@@ -2499,11 +2592,23 @@
+@@ -2498,11 +2591,23 @@
        bcc     12$                     ; 1bac -> 1bae -> 1bb0,1bbb r c=0..1
        cpy     *clip_x1                ; 1bae -> 1bb0 -> 1bb2 r y=6c..a4
        bcs     12$                     ; 1bb0 -> 1bb2 -> 1bb4,1bbb r c=0..1
        iny                             ; 1bbb -> 1bbc -> 1bbd r
        cpy     *draw_x1                ; 1bbc -> 1bbd -> 1bbf r y=5c..a5
        bcc     10$                     ; 1bbd -> 1bbf -> 1ba2,1bc1 r c=0..1
-@@ -2512,6 +2617,7 @@
+@@ -2511,6 +2616,7 @@
        cpy     *draw_y1                ; 1bc3 -> 1bc5 -> 1bc7 r y=12..d9
        bcc     9$                      ; 1bc5 -> 1bc7 -> 1b96,1bc9 r c=0..1
        ldx     *x_save                 ; 1bc7 -> 1bc9 -> 1bcb r
        rts                             ; 1bc9 -> 1bcb -> 15cd r s=fb
  erase_pixel_object:
        lda     #0x00                   ; 1c12 -> 1bcc -> 1bce r
-@@ -2543,12 +2649,15 @@
+@@ -2542,12 +2648,15 @@
        eor     #0xff                   ; 1c03 -> 1c06 -> 1c08 r
        and     [*video_line_ptr],y     ; 1c06 -> 1c08 -> 1c0a r y=6d..93,02
        sta     [*video_line_ptr],y     ; 1c08 -> 1c0a -> 1c0c r y=6d..93,02
        lda     #0x00                   ; 1c12 -> 1c14 -> 1c16 r
        sta     object1080_onscreen - 0x10,x ; 1c14 -> 1c16 -> 1c19 r x=14..77
        lda     object1080_onscreen_x0 - 0x10,x ; 1c16 -> 1c19 -> 1c1c r x=14..77
-@@ -2563,8 +2672,14 @@
+@@ -2562,8 +2671,14 @@
        stx     *x_save                 ; 1c2d -> 1c30 -> 1c32 r
        bne     3$                      ; 1c30 -> 1c32 -> 1c34,1c6a r z=0..1
        lda     object1080_onscreen_shape_ptr_lo - 0x10,x ; 1c32 -> 1c34 -> 1c37 r x=14..77
        sta     2$ + 1                  ; 1c3a -> 1c3d -> 1c40 r
        ldx     #0x00                   ; 1c3d -> 1c40 -> 1c42 r
        ldy     *draw_y                 ; 1c40 -> 1c42 -> 1c44 r
-@@ -2573,7 +2688,18 @@
+@@ -2572,7 +2687,18 @@
        lda     video_line_table_hi - 0x20,y ; 1c47 -> 1c49 -> 1c4c r y=28..cf
        sta     *video_line_ptr + 1     ; 1c49 -> 1c4c -> 1c4e r
        ldy     *draw_x0                ; 1c4c -> 1c4e -> 1c50 r
  2$:   .dw     shape_12_exhaust0 + 6   ; 1c51 rw
        eor     #0xff                   ; 1c50 -> 1c53 -> 1c55 r
        and     [*video_line_ptr],y     ; 1c53 -> 1c55 -> 1c57 r y=6c..93
-@@ -2589,14 +2715,23 @@
+@@ -2588,14 +2714,23 @@
        ldx     *x_save                 ; 1c65 -> 1c67 -> 1c69 r
        rts                             ; 1c67 -> 1c69 -> 1076,16a8 r s=f3..f9,02
  3$:   lda     object1080_onscreen_shape_ptr_lo - 0x10,x ; 1c32 -> 1c6a -> 1c6d r x=14..77
        sta     *video_line_ptr + 1     ; 1c7f -> 1c82 -> 1c84 r
        ldy     *draw_x0                ; 1c82 -> 1c84 -> 1c86 r
  5$:   lda     *draw_y                 ; 1c84,1ca5 -> 1c86 -> 1c88 r
-@@ -2608,12 +2743,25 @@
+@@ -2607,12 +2742,25 @@
        bcc     7$                      ; 1c90 -> 1c92 -> 1c94,1ca1 r c=0..1
        cpy     *clip_x1                ; 1c92 -> 1c94 -> 1c96 r y=6c..a4
        bcs     7$                      ; 1c94 -> 1c96 -> 1c98,1ca1 r c=0..1
        iny                             ; 1ca1 -> 1ca2 -> 1ca3 r
        cpy     *draw_x1                ; 1ca2 -> 1ca3 -> 1ca5 r y=5c..a5
        bcc     5$                      ; 1ca3 -> 1ca5 -> 1c86,1ca7 r c=0..1
-@@ -2627,8 +2775,17 @@
+@@ -2626,8 +2774,17 @@
        stx     *x_save                 ; 1db0 -> 1cb2 -> 1cb4 r
        tay                             ; 1cb2 -> 1cb4 -> 1cb5 r
        lda     shape_data_ptr_lo,y     ; 1cb4 -> 1cb5 -> 1cb8 r y=16..ff
        sta     3$ + 1                  ; 1cbb -> 1cbe -> 1cc1 r
        lda     shape_width_bytes,y     ; 1cbe -> 1cc1 -> 1cc4 r y=16..ff
        clc                             ; 1cc1 -> 1cc4 -> 1cc5 r
-@@ -2637,6 +2794,11 @@
+@@ -2636,6 +2793,11 @@
        lda     *draw_x0                ; 1cc7 -> 1cc9 -> 1ccb r
        lsr     a                       ; 1cc9 -> 1ccb -> 1ccc r
        bcc     0$                      ; 1ccb -> 1ccc -> 1cce,1cd4 r c=0..1
        lda     *draw_misc_mask         ; 1ccc -> 1cce -> 1cd0 r
        eor     *draw_misc_mask_xor     ; 1cce -> 1cd0 -> 1cd2 r
        sta     *draw_misc_mask         ; 1cd0 -> 1cd2 -> 1cd4 r
-@@ -2652,6 +2814,10 @@
+@@ -2651,6 +2813,10 @@
        lda     video_line_table_hi,y   ; 1ce5 -> 1ce7 -> 1cea r y=00..bc
        adc     #0x00                   ; 1ce7 -> 1cea -> 1cec r c=0..1 d=0
        sta     *video_line_ptr + 1     ; 1cea -> 1cec -> 1cee r
        lda     *draw_misc_mask         ; 1cec -> 1cee -> 1cf0 r
        sta     *draw_misc_mask_temp    ; 1cee -> 1cf0 -> 1cf2 r
        ldy     *draw_x0                ; 1cf0 -> 1cf2 -> 1cf4 r
-@@ -2660,13 +2826,30 @@
+@@ -2659,13 +2825,30 @@
        bcs     4$                      ; 1cf6 -> 1cf8 -> 1cfa r c=0
        cpy     #0x28                   ; 1cf8 -> 1cfa -> 1cfc r y=00..2d
        bcs     4$                      ; 1cfa -> 1cfc -> 1cfe,1d05 r c=0..1
        inx                             ; 1d09 -> 1d0b -> 1d0c r
        iny                             ; 1d0b -> 1d0c -> 1d0d r
        cpy     *draw_x1                ; 1d0c -> 1d0d -> 1d0f r y=01..2e
-@@ -2687,7 +2870,7 @@
+@@ -2686,7 +2869,7 @@
        asl     a                       ; 1d23 -> 1d24 -> 1d25 r
        sta     *draw_misc_ptr          ; 1d24 -> 1d25 -> 1d27 r
        lda     #0x00                   ; 1d25 -> 1d27 -> 1d29 r
        sta     *draw_misc_ptr + 1      ; 1d29 -> 1d2b -> 1d2d r
        lda     *half_dimension         ; 1d2b -> 1d2d -> 1d2f r
        lsr     a                       ; 1d2d -> 1d2f -> 1d30 r
-@@ -2696,6 +2879,12 @@
+@@ -2695,6 +2878,12 @@
        lsr     a                       ; 1d31 -> 1d32 -> 1d33 r
        lsr     a                       ; 1d32 -> 1d33 -> 1d34 r
        tay                             ; 1d33 -> 1d34 -> 1d35 r
        lda     draw_misc_mask_table,y  ; 1d34 -> 1d35 -> 1d38 r y=00..06
        sta     *draw_misc_mask         ; 1d35 -> 1d38 -> 1d3a r
        lda     draw_misc_mask_xor_table,y ; 1d38 -> 1d3a -> 1d3d r y=00..06
-@@ -2772,6 +2961,62 @@
+@@ -2771,6 +2960,62 @@
        ldy     *draw_misc_y_save       ; 1d1b -> 1db3 -> 1db5 r
  rts_1db5:
        rts                             ; 1da1,1db3 -> 1db5 -> 1076,1d61,1d7d,1d82,1d87 r s=ee..f7
  draw_misc_mask_table:
        .db     0xff                    ; 1db6 r
        .db     0x00                    ; 1db7 r
-@@ -2782,72 +3027,18 @@
+@@ -2781,72 +3026,18 @@
        .db     0xd5                    ; 1dbc r
        .db     0xff                    ; 1dbd r
  draw_misc_mask_xor_table:
  sub_1e00:
        jmp     loc_1e2a                ; 15dc -> 1e00 -> 1e2a r
  test_player_fire:
-@@ -3006,77 +3197,7 @@
+@@ -3005,77 +3196,7 @@
        adc     #0x01                   ; 1f32 -> 1f33 -> 1f35 r c=0 d=0
        sta     object1080_velocity_x_hi + 0x50 ; 1f33 -> 1f35 -> 1f38 r
        rts                             ; 1f35 -> 1f38 -> 15df r s=f9
  barr_1f80:
        .db     0x43                    ; 1f80 r
        .db     0x02                    ; 1f81 r
-@@ -3241,12 +3362,16 @@
-       sta     vec_0200                ; 2028 -> 202a -> 202d r
-       lda     #>restart               ; 202a -> 202d -> 202f r
-       sta     vec_0200 + 1            ; 202d -> 202f -> 2032 r
--      ldx     #0x4e                   ; 202f -> 2032 -> 2034 r
-+.if DHGR ; language card
-+      lda     hw_lc_bank1_ram_we
-+      lda     hw_lc_bank1_ram_we
-+.endif
-+      ldx     #<relocate_addr         ; 202f -> 2032 -> 2034 r
-       ldy     #0x20                   ; 2032 -> 2034 -> 2036 r
- 0$:   .db     0xbd                    ; 2034,203d,2046 -> 2036 -> 2039 r "lda 0x2000,x" x=00..ff
--1$:   .dw     0x2000                  ; 2037 rw
-+1$:   .db     0,>relocate_addr ;.dw 0x2000                    ; 2037 rw
-       .db     0x9d                    ; 2036 -> 2039 -> 203c r "sta 0x7ded,x" x=00..ff
--2$:   .dw     0x7ded                  ; 203a rw
-+2$:   .dw     data_end - 0x2000 ;0x7ded                       ; 203a rw
-       inx                             ; 2039 -> 203c -> 203d r
-       bne     0$                      ; 203c -> 203d -> 2036,203f r z=0..1
-       inc     1$ + 1                  ; 203d -> 203f -> 2042 r
-@@ -3257,9 +3382,20 @@
-       txs                             ; 2048 -> 2049 -> 204a r
-       cld                             ; 2049 -> 204a -> 204b r
-       jmp     [vec_start]             ; 204a -> 204b -> 17d1 r
-+relocate_addr:
+@@ -3214,7 +3335,17 @@
+       .db     0x00                    ; 1fff r
  
        .area   data0
+-
 +data0_start:
++ 
 +.if DHGR
 +.include /dhgr_pixel_shape_index.inc/
 +.else
  shape_data_ptr_lo:
        .db     <shape_23_bomb3 + 0x28  ; 4000 r
        .db     <shape_23_bomb3 + 0x28  ; 4001 r
-@@ -4802,6 +4938,9 @@
+@@ -4757,6 +4888,9 @@
        .db     0x01                    ; 45fd r
        .db     0x01                    ; 45fe r
        .db     0x04                    ; 45ff r
  draw_misc_table:
        .db     0x01                    ; 4600 r
        .db     0x07                    ; 4601 r
-@@ -9477,6 +9616,15 @@
+@@ -9432,6 +9566,15 @@
        .dw     0x0000                  ; 5bfa r
        .dw     0x0000                  ; 5bfc r
        .dw     0x0000                  ; 5bfe r
  shape_20_bomb0:
        .db     0x5c                    ; 5c00 r
        .db     0x02                    ; 5c01 r
-@@ -21897,510 +22045,12 @@
+@@ -21852,510 +21995,12 @@
        .db     0xe0                    ; 8c05 r
        .db     0x83                    ; 8c06 r
        .db     0x9e                    ; 8c07 r
  microcode_table_5560_data_8e00:
        .db     0x30                    ; 8e00 r
        .db     0x0f                    ; 8e01
-@@ -26971,9 +26621,12 @@
-       .db     0x7c                    ; 9dea
-       .db     0x98                    ; 9deb
-       .db     0x00                    ; 9dec
--
--      .area   udata2
--
+@@ -26951,8 +26596,16 @@
+       lda     #>restart               ; 9e16 r
+       sta     vec_restart + 1         ; 9e18 r
+       jmp     start                   ; 9e1b r
 +data_end:
+-      .area   udata2
++; normally this is .area udata2, but don't bother with a separate area,
++; put the address here so the DHGR build can use the ordinary Makefile
++;     .area   udata2
 +.if DHGR
 +      .ds     0xf100 - 0xd000 - (. - data1_start)
 +.else
 +      .ds     0xa800 - 0x4000 - (. - data0_start)
 +.endif
  x_table_times2_div7_plus_5b:
        .ds     0x100                   ; a800 rw
- x_table_times2_mod7_minus_03:
index 98a1b09..8186036 100644 (file)
@@ -5,13 +5,16 @@ LDFLAGS=-g
 all: \
 cg_default \
 emu_65c02 \
+apple_ii+_applesoft_rom.ihx \
 Apple\ II+\ -\ 341-0011\ -\ Applesoft\ BASIC\ D000\ -\ 2716.bin \
 Apple\ II+\ -\ 341-0012\ -\ Applesoft\ BASIC\ D800\ -\ 2716.bin \
 Apple\ II+\ -\ 341-0013\ -\ Applesoft\ BASIC\ E000\ -\ 2716.bin \
 Apple\ II+\ -\ 341-0014\ -\ Applesoft\ BASIC\ E800\ -\ 2716.bin \
 Apple\ II+\ -\ 341-0015\ -\ Applesoft\ BASIC\ F000\ -\ 2716.bin \
+apple_ii+_autostart_monitor_rom.ihx \
 Apple\ II+\ -\ 341-0020\ -\ Applesoft\ BASIC\ Autostart\ Monitor\ F800\ -\ 2716.bin \
 Apple\ II+\ -\ 7341-0036\ -\ Character\ Generator\ Rev7+\ -\ 2716.bin \
+apple_iie_rom.ihx \
 Apple\ IIe\ CD\ Enhanced\ -\ 342-0304-A\ -\ 2764.bin \
 Apple\ IIe\ EF\ Enhanced\ -\ 342-0303-A\ -\ 2764.bin \
 Apple\ IIe\ Video\ Enhanced\ -\ 342-0265-A\ -\ 2732.bin
@@ -25,6 +28,20 @@ emu_65c02: emu_65c02.o stty_sane.o vrEmu6502/src/vrEmu6502.o
 
 emu_65c02.o: cg_default
 
+apple_ii+_applesoft_rom.ihx: \
+Apple\ II+\ -\ 341-0011\ -\ Applesoft\ BASIC\ D000\ -\ 2716.bin \
+Apple\ II+\ -\ 341-0012\ -\ Applesoft\ BASIC\ D800\ -\ 2716.bin \
+Apple\ II+\ -\ 341-0013\ -\ Applesoft\ BASIC\ E000\ -\ 2716.bin \
+Apple\ II+\ -\ 341-0014\ -\ Applesoft\ BASIC\ E800\ -\ 2716.bin \
+Apple\ II+\ -\ 341-0015\ -\ Applesoft\ BASIC\ F000\ -\ 2716.bin
+       ./rom2hex.py 0x11000 "\
+Apple II+ - 341-0011 - Applesoft BASIC D000 - 2716.bin,\
+Apple II+ - 341-0012 - Applesoft BASIC D800 - 2716.bin,\
+Apple II+ - 341-0013 - Applesoft BASIC E000 - 2716.bin,\
+Apple II+ - 341-0014 - Applesoft BASIC E800 - 2716.bin,\
+Apple II+ - 341-0015 - Applesoft BASIC F000 - 2716.bin" \
+$@
+
 Apple\ II+\ -\ 341-0011\ -\ Applesoft\ BASIC\ D000\ -\ 2716.bin: \
 ../orig/APPLE\ Computer\ and\ Peripheral\ Card\ Roms\ Collection.zip
        rm -f "$@"
@@ -55,6 +72,10 @@ Apple\ II+\ -\ 341-0015\ -\ Applesoft\ BASIC\ F000\ -\ 2716.bin: \
        unzip "$<" "$@"
        touch "$@"
 
+apple_ii+_autostart_monitor_rom.ihx: \
+Apple\ II+\ -\ 341-0020\ -\ Applesoft\ BASIC\ Autostart\ Monitor\ F800\ -\ 2716.bin
+       ./rom2hex.py --reset-vector 0x13800 "$<" $@
+
 Apple\ II+\ -\ 341-0020\ -\ Applesoft\ BASIC\ Autostart\ Monitor\ F800\ -\ 2716.bin: \
 ../orig/APPLE\ Computer\ and\ Peripheral\ Card\ Roms\ Collection.zip
        rm -f "$@"
@@ -67,6 +88,14 @@ Apple\ II+\ -\ 7341-0036\ -\ Character\ Generator\ Rev7+\ -\ 2716.bin: \
        unzip "$<" "$@"
        touch "$@"
 
+apple_iie_rom.ihx: \
+Apple\ IIe\ CD\ Enhanced\ -\ 342-0304-A\ -\ 2764.bin \
+Apple\ IIe\ EF\ Enhanced\ -\ 342-0303-A\ -\ 2764.bin
+       ./rom2hex.py --reset-vector 0x20000 "\
+Apple IIe CD Enhanced - 342-0304-A - 2764.bin,\
+Apple IIe EF Enhanced - 342-0303-A - 2764.bin" \
+$@
+
 Apple\ IIe\ CD\ Enhanced\ -\ 342-0304-A\ -\ 2764.bin: \
 ../orig/APPLE\ Computer\ and\ Peripheral\ Card\ Roms\ Collection.zip
        rm -f "$@"
index e17dd40..18c3a4b 100644 (file)
@@ -245,12 +245,193 @@ void rom_load(char *name, uint8_t *data, int size) {
   close(fd);
 }
 
-int obj_load(char *name) {
-  int load_address = -1;
+int load_bin(char *name, int addr, int len) {
+  int fd = open(name, O_RDONLY);
+  if (fd == -1) {
+    perror(name);
+    exit(EXIT_FAILURE);
+  }
+
+  if (addr == -1)
+    addr = 0;
+  if (len == -1) {
+    len = MEM_SIZE - addr;
+    if (read(fd, mem + addr, len) == -1) { // short read OK
+      perror("read()");
+      exit(EXIT_FAILURE);
+    }
+  }
+  else if (read(fd, mem + addr, len) != len) {
+    perror("read()");
+    exit(EXIT_FAILURE);
+  }
+
+  close(fd);
+  return addr;
+}
+
+int load_a2bin(char *name, int addr, int len) {
+  int fd = open(name, O_RDONLY);
+  if (fd == -1) {
+    perror(name);
+    exit(EXIT_FAILURE);
+  }
+
+  uint8_t header[4];
+  if (read(fd, header, 4) != 4) {
+    perror("read()");
+    exit(EXIT_FAILURE);
+  }
+  if (addr == -1)
+    addr = header[0] + (header[1] << 8);
+  if (len == -1)
+    len = header[2] + (header[3] << 8);
+  int end_addr = addr + len;
+  if (end_addr < addr || end_addr > MEM_SIZE) {
+    fprintf(stderr, "invalid load range: [0x%x, 0x%x)\n", addr, end_addr);
+    exit(EXIT_FAILURE);
+  }
+
+  if (read(fd, mem + addr, len) != len) {
+    perror("read()");
+    exit(EXIT_FAILURE);
+  }
+
+  close(fd);
+  return addr;
+}
+
+int load_ihx(char *name, int addr0, int len0) {
+  if (addr0 != -1 || len0 != -1) {
+    fprintf(stderr, "ihx loader does not implement address/length options\n");
+    exit(EXIT_FAILURE);
+  }
+
+  FILE *fp = fopen(name, "r");
+  if (fp == NULL) {
+    perror(name);
+    exit(EXIT_FAILURE);
+  }
+
+  int base = 0, entry_point = 0;
+  bool had_eof = false;
+  char line[0x100];
+  while (fgets(line, 0x100, fp)) {
+    for (char *p = line; *p; ++p)
+      if (*p == '\n') {
+        *p = 0;
+        break;
+      }
+
+    if (had_eof) {
+      fprintf(stderr, "garbage after EOF record: %s\n", line);
+      exit(EXIT_FAILURE);
+    }
+
+    if (line[0] != ':') {
+      fprintf(stderr, "require colon: %s\n", line);
+      exit(EXIT_FAILURE);
+    }
+
+    uint8_t buf[0x7f];
+    int len;
+    for (len = 0; len < 0x7f; ++len) {
+      char *p = line + 1 + len * 2;
+      if (*p == 0)
+        break;
+      if (*p == '\n') {
+        *p = 0;
+        break;
+      }
+      uint8_t c = p[2];
+      p[2] = 0;
+
+      char *q;
+      buf[len] = (uint8_t)strtol(p, &q, 16);
+      p[2] = c;
+      if (q != p + 2) {
+        fprintf(stderr, "not hex byte: %s\n", p);
+        exit(EXIT_FAILURE);
+      }
+    }
+
+    if (len == 0) {
+      fprintf(stderr, "empty line: %s\n", line);
+      exit(EXIT_FAILURE);
+    }
+
+    uint8_t checksum = 0;
+    for (int i = 0; i < len; ++i)
+      checksum += buf[i];
+    if (checksum) {
+      checksum -= buf[len - 1];
+      fprintf(
+        stderr,
+        "checksum %02x, should be %02x\n",
+        checksum,
+        buf[len - 1]
+      );
+      exit(EXIT_FAILURE);
+    }
+
+    len -= 5;
+    if (len != buf[0]) {
+      fprintf(stderr, "incorrect length: %s\n", line);
+      exit(EXIT_FAILURE);
+    }
+
+    int addr = (buf[1] << 8) | buf[2], end_addr;
+    switch (buf[3]) {
+    case 0:
+      addr += base;
+      end_addr = addr + len;
+      if (end_addr < addr || end_addr > MEM_SIZE) {
+        fprintf(stderr, "invalid load range: [0x%x, 0x%x)\n", addr, end_addr);
+        exit(EXIT_FAILURE);
+      }
+      memcpy(mem + addr, buf + 4, len);
+      break;
+    case 1:
+      had_eof = true;
+      break;
+    case 4:
+      if (len < 2) {
+        fprintf(stderr, "invalid extended linear address record: %s\n", line);
+        exit(EXIT_FAILURE);
+      }
+      base = (buf[4] << 24) | (buf[5] << 16);
+      break;
+    case 5:
+      if (len < 4) {
+        fprintf(stderr, "invalid start linear address record: %s\n", line);
+        exit(EXIT_FAILURE);
+      }
+      entry_point = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
+      break;
+    default:
+      fprintf(stderr, "unknown record type: 0x%x\n", buf[3]);
+      exit(EXIT_FAILURE);
+    }
+  }
+  if (!had_eof) {
+    fprintf(stderr, "no EOF record\n");
+    exit(EXIT_FAILURE);
+  }
+
+  fclose(fp);
+  return entry_point;
+}
+
+int load(char *name) {
   char *p;
   for (p = name; *p && *p != ','; ++p)
     ;
-  int c = *p;
+
+  char *format;
+  for (format = p - 1; format >= name && *format != '.'; --format)
+    ;
+
+  int addr = -1, len = -1, c = *p;
   *p++ = 0;
   while (c) {
     char *q;
@@ -258,41 +439,47 @@ int obj_load(char *name) {
       ;
     c = *q;
     *q++ = 0;
-    if (*p == 'a') {
+    int option = *p & ~0x20;
+    if (option == 'A' || option == 'L') {
       ++p;
-      int base = 10;
+      int base = 0;
       if (*p == '$') {
         ++p;
         base = 16;
       }
-      load_address = (int)strtol(p, NULL, base);
+      int value = (int)strtol(p, NULL, base);
+      if (value < 0) {
+        printf("negative load option %c value: -0x%x\n", option, -value);
+        exit(EXIT_FAILURE);
+      }
+      if (value > MEM_SIZE) {
+        printf("too large load option %c value: 0x%x\n", option, value);
+        exit(EXIT_FAILURE);
+      }
+      switch (option) {
+      case 'A':
+        addr = value;
+        break;
+      case 'L':
+        len = value;
+        break;
+      }
     }
     else {
-      fprintf(stderr, "unknown BLOAD option: %s\n", p);
+      fprintf(stderr, "unknown load option: %s\n", p);
       exit(EXIT_FAILURE);
     }
     p = q;
   }
 
-  int fd = open(name, O_RDONLY);
-  if (fd == -1) {
-    perror(name);
-    exit(EXIT_FAILURE);
-  }
-  uint8_t header[4];
-  if (read(fd, header, 4) != 4) {
-    perror("read()");
-    exit(EXIT_FAILURE);
-  }
-  if (load_address == -1)
-    load_address = header[0] + (header[1] << 8);
-  int load_size = header[2] + (header[3] << 8);
-  if (read(fd, mem + load_address, load_size) != load_size) {
-    perror("read()");
-    exit(EXIT_FAILURE);
-  }
-  close(fd);
-  return load_address;
+  if (strcmp(format, ".bin") == 0)
+    return load_bin(name, addr, len);
+  if (strcmp(format, ".a2bin") == 0)
+    return load_a2bin(name, addr, len);
+  if (strcmp(format, ".ihx") == 0)
+    return load_ihx(name, addr, len);
+  fprintf(stderr, "unknown load format: %s\n", format);
+  exit(EXIT_FAILURE);
 }
 
 void dos(char *line) {
@@ -307,7 +494,7 @@ void dos(char *line) {
           *q = '_';
         else if (*q >= 'A' && *q <= 'Z')
           *q += 'a' - 'A';
-      obj_load(p);
+      load(p);
     }
   }
   else {
@@ -922,70 +1109,42 @@ int main(int argc, char **argv) {
   char *cg_rom_file = NULL;
   char *video_rom_file = NULL;
 #if APPLE_IIE
-  char *cd_rom_file =
-    "Apple IIe CD Enhanced - 342-0304-A - 2764.bin";
-  char *ef_rom_file =
-    "Apple IIe EF Enhanced - 342-0303-A - 2764.bin";
+  char *cd_rom_file = NULL;
+  char *ef_rom_file = NULL;
 #else
-  char *d0_rom_file =
-    "Apple II+ - 341-0011 - Applesoft BASIC D000 - 2716.bin";
-  char *d8_rom_file =
-    "Apple II+ - 341-0012 - Applesoft BASIC D800 - 2716.bin";
-  char *e0_rom_file =
-    "Apple II+ - 341-0013 - Applesoft BASIC E000 - 2716.bin";
-  char *e8_rom_file =
-    "Apple II+ - 341-0014 - Applesoft BASIC E800 - 2716.bin";
-  char *f0_rom_file =
-    "Apple II+ - 341-0015 - Applesoft BASIC F000 - 2716.bin";
-  char *f8_rom_file =
-    "Apple II+ - 341-0020 - Applesoft BASIC Autostart Monitor F800 - 2716.bin";
+  char *d0_rom_file = NULL;
+  char *d8_rom_file = NULL;
+  char *e0_rom_file = NULL;
+  char *e8_rom_file = NULL;
+  char *f0_rom_file = NULL;
+  char *f8_rom_file = NULL;
 #endif
   bool timing = false;
   while (argn < argc) {
     if (strcmp(argv[argn], "--help") == 0) {
-      printf("usage: %s [--no-cg-rom|--cg-rom=file.bin] [--no-video-rom|--video-rom=file.bin] [--no-NN-rom|--NN-rom=file.bin ...] [--timing] [program.obj[,aNNNN] ...] [-- child-executable [child-argument ...]]\n", argv[0]);
+      printf("usage: %s [--cg-rom=file.bin] [--video-rom=file.bin] [--NN-rom=file.bin ...] [--timing] [program.obj[,aNNNN] ...] [-- child-executable [child-argument ...]]\n", argv[0]);
       exit(EXIT_FAILURE);
     }
-    if (strcmp(argv[argn], "--no-cg-rom") == 0)
-      cg_rom_file = NULL;
-    else if (memcmp(argv[argn], "--cg-rom=", 9) == 0)
+    if (memcmp(argv[argn], "--cg-rom=", 9) == 0)
       cg_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-video-rom") == 0)
-      video_rom_file = NULL;
     else if (memcmp(argv[argn], "--video_rom=", 12) == 0)
       video_rom_file = argv[argn] + 12;
 #if APPLE_IIE
-    else if (strcmp(argv[argn], "--no-cd-rom") == 0)
-      cd_rom_file = NULL;
     else if (memcmp(argv[argn], "--cd-rom=", 9) == 0)
       cd_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-ef-rom") == 0)
-      ef_rom_file = NULL;
     else if (memcmp(argv[argn], "--ef-rom=", 9) == 0)
       ef_rom_file = argv[argn] + 9;
 #else
-    else if (strcmp(argv[argn], "--no-d0-rom") == 0)
-      d0_rom_file = NULL;
     else if (memcmp(argv[argn], "--d0-rom=", 9) == 0)
       d0_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-d8-rom") == 0)
-      d8_rom_file = NULL;
     else if (memcmp(argv[argn], "--d8-rom=", 9) == 0)
       d8_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-e0-rom") == 0)
-      e0_rom_file = NULL;
     else if (memcmp(argv[argn], "--e0-rom=", 9) == 0)
       e0_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-e8-rom") == 0)
-      e8_rom_file = NULL;
     else if (memcmp(argv[argn], "--e8-rom=", 9) == 0)
       e8_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-f0-rom") == 0)
-      f0_rom_file = NULL;
     else if (memcmp(argv[argn], "--f0-rom=", 9) == 0)
       f0_rom_file = argv[argn] + 9;
-    else if (strcmp(argv[argn], "--no-f8-rom") == 0)
-      f8_rom_file = NULL;
     else if (memcmp(argv[argn], "--f8-rom=", 9) == 0)
       f8_rom_file = argv[argn] + 9;
 #endif
@@ -1034,35 +1193,44 @@ int main(int argc, char **argv) {
     }
   }
 
+  int entry_point = -1;
 #if APPLE_IIE
-  rom_load(cd_rom_file, mem + 0x20000, 0x2000);
-  rom_load(ef_rom_file, mem + 0x22000, 0x2000);
+  memset(mem + 0x20000, 0xff, 0x4000);
+  if (cd_rom_file)
+    load_bin(cd_rom_file, 0x20000, 0x2000);
+  if (ef_rom_file)
+    load_bin(ef_rom_file, 0x22000, 0x2000);
 #else
-  memset(mem + 0x10000, 0xff, 0x1000);
-  rom_load(d0_rom_file, mem + 0x11000, 0x800);
-  rom_load(d8_rom_file, mem + 0x11800, 0x800);
-  rom_load(e0_rom_file, mem + 0x12000, 0x800);
-  rom_load(e8_rom_file, mem + 0x12800, 0x800);
-  rom_load(f0_rom_file, mem + 0x13000, 0x800);
-  rom_load(f8_rom_file, mem + 0x13800, 0x800);
+  memset(mem + 0x10000, 0xff, 0x4000);
+  if (d0_rom_file)
+    load_bin(d0_rom_file, 0x11000, 0x800);
+  if (d8_rom_file)
+    load_bin(d8_rom_file, 0x11800, 0x800);
+  if (e0_rom_file)
+    load_bin(e0_rom_file, 0x12000, 0x800);
+  if (e0_rom_file)
+    load_bin(e8_rom_file, 0x12800, 0x800);
+  if (e0_rom_file)
+    load_bin(f0_rom_file, 0x13000, 0x800);
+  if (f8_rom_file)
+    load_bin(f8_rom_file, 0x13800, 0x800);
 #endif
 
-  int load_address = -1;
   while (argn < argc) {
     char *p = argv[argn++];
     if (strcmp(p, "--") == 0)
       break;
-    load_address = obj_load(p);
+    entry_point = load(p);
   }
 
   // do this before creating the CPU
-  if (load_address != -1) {
+  if (entry_point != -1) {
 #if APPLE_IIE
-    mem[RESET_VECTOR + 0x20000 - 0xc000] = (uint8_t)(load_address & 0xff);
-    mem[RESET_VECTOR + 1 + 0x20000 - 0xc000] = (uint8_t)(load_address >> 8);
+    mem[RESET_VECTOR + 0x20000 - 0xc000] = (uint8_t)(entry_point & 0xff);
+    mem[RESET_VECTOR + 1 + 0x20000 - 0xc000] = (uint8_t)(entry_point >> 8);
 #else
-    mem[RESET_VECTOR + 0x10000 - 0xc000] = (uint8_t)(load_address & 0xff);
-    mem[RESET_VECTOR + 1 + 0x10000 - 0xc000] = (uint8_t)(load_address >> 8);
+    mem[RESET_VECTOR + 0x10000 - 0xc000] = (uint8_t)(entry_point & 0xff);
+    mem[RESET_VECTOR + 1 + 0x10000 - 0xc000] = (uint8_t)(entry_point >> 8);
 #endif
   }
 
diff --git a/emu_65c02/rom2hex.py b/emu_65c02/rom2hex.py
new file mode 100755 (executable)
index 0000000..a33b6ac
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+import sys
+from intelhex import IntelHex
+
+EXIT_SUCCESS = 0
+EXIT_FAILURE = 1
+
+reset_vector = False
+if len(sys.argv) >= 2 and sys.argv[1] == '--reset-vector':
+  reset_vector = True
+  del sys.argv[1]
+if len(sys.argv) < 4:
+  print(
+    f'usage: {sys.argv[0]:s} [--reset-vector] load_addr in.bin[,in.bin...] out.ihx'
+  )
+  sys.exit(EXIT_FAILURE)
+load_addr = int(sys.argv[1], 0)
+in_bins = sys.argv[2].split(',')
+out_ihx = sys.argv[3]
+
+bin = []
+for in_bin in in_bins:
+  with open(in_bin, 'rb') as fin:
+    bin.extend(list(fin.read()))
+
+intelhex = IntelHex()
+if reset_vector:
+  intelhex.start_addr = {'EIP': bin[-4] | (bin[-3] << 8)}
+for i in range(len(bin)):
+  intelhex[load_addr + i] = bin[i]
+intelhex.write_hex_file(out_ihx)
index 67318c8..d13edea 100755 (executable)
@@ -14,21 +14,25 @@ RECRACK_LOADER=0x9ded
 
 .PHONY: all
 all: \
-star_blazer.bin \
-star_blazer_dejunked0.bin \
-star_blazer_dejunked1.bin \
-star_blazer_recrack_lzss.bin
+star_blazer.ihx \
+star_blazer.a2bin \
+star_blazer_dejunked0.a2bin \
+star_blazer_dejunked1.a2bin \
+star_blazer_recrack_lzss.a2bin
 
-star_blazer.bin: ../orig/Star_Blazer_1981_Star_Craft.do
+star_blazer.ihx: star_blazer.a2bin
+       ./a2_load.py 0x17d1 $< $@
+
+star_blazer.a2bin: ../orig/Star_Blazer_1981_Star_Craft.do
        ${DOS33} ../orig/Star_Blazer_1981_Star_Craft.do LOAD "STAR BLAZER" $@
 
-star_blazer_dejunked0.bin: star_blazer.bin
+star_blazer_dejunked0.a2bin: star_blazer.a2bin
        ./dejunk.py $< $@ 0
 
-star_blazer_dejunked1.bin: star_blazer.bin
+star_blazer_dejunked1.a2bin: star_blazer.a2bin
        ./dejunk.py $< $@ 0xff
 
-star_blazer_recrack_lzss.bin: lzss_loader.bin star_blazer_recrack.bin
+star_blazer_recrack_lzss.a2bin: lzss_loader.bin star_blazer_recrack.a2bin
        ./lzss_encode.py ${LZSS_LOADER} $^ $@
 
 lzss_loader.bin: lzss_loader.ihx
@@ -40,7 +44,7 @@ lzss_loader.ihx: lzss_loader.rel
 lzss_loader.rel: lzss_loader.asm
        ${AS6500} -l -o $<
 
-star_blazer_recrack.bin: recrack_loader.bin star_blazer_dejunked0.bin
+star_blazer_recrack.a2bin: recrack_loader.bin star_blazer_dejunked0.a2bin
        ./recrack.py $^ $@
 
 recrack_loader.bin: recrack_loader.ihx
@@ -53,4 +57,4 @@ recrack_loader.rel: recrack_loader.asm
        ${AS6500} -l -o $<
 
 clean:
-       rm -f *.bin *.hlr *.ihx *.lst *.map *.o *.rel *.rst
+       rm -f *.a2bin *.bin *.hlr *.ihx *.lst *.map *.o *.rel *.rst
diff --git a/loader/a2_load.py b/loader/a2_load.py
new file mode 100755 (executable)
index 0000000..ab50899
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+
+import py65.devices.mpu65c02
+import sys
+from intelhex import IntelHex
+
+EXIT_SUCCESS = 0
+EXIT_FAILURE = 1
+
+if len(sys.argv) < 4:
+  print(f'usage: {sys.argv[0]:s} entry_point in.a2bin out.ihx')
+  sys.exit(EXIT_FAILURE)
+entry_point = int(sys.argv[1], 0)
+in_a2bin = sys.argv[2]
+out_ihx = sys.argv[3]
+
+with open(in_a2bin, 'rb') as fin:
+  a2bin = list(fin.read())
+  hdr = a2bin[:4]
+  bin = a2bin[4:]
+load_addr = hdr[0] | (hdr[1] << 8)
+load_size = hdr[2] | (hdr[3] << 8)
+
+mem = [0] * 0x10000
+mem_used = [False] * 0x10000
+
+mem[load_addr:load_addr + load_size] = bin
+mem_used[load_addr:load_addr + load_size] = [True] * load_size
+
+class Mem:
+  def __init__(self, mem, mem_used):
+    self.mem = mem
+    self.mem_used = mem_used
+
+  def __getitem__(self, addr):
+    self.mem_used[addr] = False
+    return self.mem[addr]
+
+  def __setitem__(self, addr, data):
+    self.mem[addr] = data
+    self.mem_used[addr] = True
+
+mpu = py65.devices.mpu65c02.MPU(Mem(mem, mem_used), load_addr)
+while mpu.pc != entry_point:
+  mpu.step()
+if mpu.p & 8:
+  print('warning: d = 1')
+if mpu.sp != 0xff:
+  print('warning: s = 0x{mpu.sp:02x}')
+
+intelhex = IntelHex()
+intelhex.start_addr = {'EIP': entry_point}
+for i in range(0x10000):
+  if mem_used[i]:
+    intelhex[i] = mem[i]
+intelhex.write_hex_file(out_ihx)
index 202c58b..0579704 100755 (executable)
@@ -6,16 +6,16 @@ EXIT_SUCCESS = 0
 EXIT_FAILURE = 1
 
 if len(sys.argv) < 4:
-  print(f'usage: {sys.argv[0]:s} in.bin out.bin fill_value')
+  print(f'usage: {sys.argv[0]:s} in.a2bin out.a2bin fill_value')
   sys.exit(EXIT_FAILURE)
-in_bin = sys.argv[1]
-out_bin = sys.argv[2]
+in_a2bin = sys.argv[1]
+out_a2bin = sys.argv[2]
 fill_value = int(sys.argv[3], 0)
 
-with open(in_bin, 'rb') as fin:
-  data = list(fin.read())
-  hdr = data[:4]
-  bin = data[4:]
+with open(in_a2bin, 'rb') as fin:
+  a2bin = list(fin.read())
+  hdr = a2bin[:4]
+  bin = a2bin[4:]
 assert len(bin) == 0x9300
 
 # file was constructed from a memory dump after copy protected loader ran
@@ -59,5 +59,5 @@ bin[0x3928:0x392a] = vec_calculate_objct_shape # [0x3c28, 0x3c2a)
 bin[0x394e:0x3950] = vec_draw_miscellaneous_from_table # [0x3c4e, 0x3c50)
 bin[0x3b00:0x3b02] = vec_unknown # [0x3e00, 0x3e00)
 
-with open(out_bin, 'wb') as fout:
+with open(out_a2bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index edadba8..a3f2efd 100755 (executable)
@@ -17,15 +17,15 @@ MAX_DIST = (1 << DIST_BITS1) # distance codes are 1..MAX_DIST
 MAX_LEN = (1 << LEN_BITS1) + 1 # length codes are 2..MAX_LEN
 
 if len(sys.argv) < 3:
-  print(f'usage: {sys.argv[0]:s} in.bin out.bin')
+  print(f'usage: {sys.argv[0]:s} in.a2bin out.a2bin')
   sys.exit(EXIT_FAILURE)
-in_bin = sys.argv[1]
-out_bin = sys.argv[2]
+in_a2bin = sys.argv[1]
+out_a2bin = sys.argv[2]
 
-with open(in_bin, 'rb') as fin:
-  data = list(fin.read())
-  hdr = data[:4]
-  lzss = data[4:]
+with open(in_a2bin, 'rb') as fin:
+  a2bin = list(fin.read())
+  hdr = a2bin[:4]
+  lzss = a2bin[4:]
 load_addr0 = hdr[0] | (hdr[1] << 8)
 load_size0 = hdr[2] | (hdr[3] << 8)
 assert load_size0 == len(lzss)
@@ -120,5 +120,5 @@ if entry_point != load_addr:
   load_size += 3
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-with open(out_bin, 'wb') as fout:
+with open(out_a2bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index dfbf2c7..8ffb9f1 100755 (executable)
@@ -20,21 +20,21 @@ MAX_DIST = (1 << DIST_BITS1) # distance codes are 1..MAX_DIST
 MAX_LEN = (1 << LEN_BITS1) + 1 # length codes are 2..MAX_LEN
 
 if len(sys.argv) < 5:
-  print(f'usage: {sys.argv[0]:s} load_addr lzss_loader.bin in.bin out.bin')
+  print(f'usage: {sys.argv[0]:s} load_addr lzss_loader.a2bin in.a2bin out.a2bin')
   sys.exit(EXIT_FAILURE)
 load_addr = int(sys.argv[1], 0)
 lzss_loader_bin = sys.argv[2]
-in_bin = sys.argv[3]
-out_bin = sys.argv[4]
+in_a2bin = sys.argv[3]
+out_a2bin = sys.argv[4]
 
 with open(lzss_loader_bin, 'rb') as fin:
   lzss_loader = list(fin.read())
 assert len(lzss_loader) == 0xb3
 
-with open(in_bin, 'rb') as fin:
-  data = list(fin.read())
-  hdr = data[:4]
-  bin = data[4:]
+with open(in_a2bin, 'rb') as fin:
+  a2bin = list(fin.read())
+  hdr = a2bin[:4]
+  bin = a2bin[4:]
 load_addr0 = hdr[0] | (hdr[1] << 8)
 load_size0 = hdr[2] | (hdr[3] << 8)
 assert load_size0 == len(bin)
@@ -244,5 +244,5 @@ lzss[0x41] = entry_point & 0xff
 lzss[0x42] = entry_point >> 8
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-with open(out_bin, 'wb') as fout:
+with open(out_a2bin, 'wb') as fout:
   fout.write(bytes(hdr + lzss))
index d0e975f..ef71f05 100755 (executable)
@@ -6,19 +6,19 @@ EXIT_SUCCESS = 0
 EXIT_FAILURE = 1
 
 if len(sys.argv) < 4:
-  print(f'usage: {sys.argv[0]:s} recrack_loader.bin in.bin out.bin')
+  print(f'usage: {sys.argv[0]:s} recrack_loader.a2bin in.a2bin out.a2bin')
   sys.exit(EXIT_FAILURE)
 recrack_loader_bin = sys.argv[1]
-in_bin = sys.argv[2]
-out_bin = sys.argv[3]
+in_a2bin = sys.argv[2]
+out_a2bin = sys.argv[3]
 
 with open(recrack_loader_bin, 'rb') as fin:
   recrack_loader = list(fin.read())
 
-with open(in_bin, 'rb') as fin:
-  data = list(fin.read())
-  hdr = data[:4]
-  bin = data[4:]
+with open(in_a2bin, 'rb') as fin:
+  a2bin = list(fin.read())
+  hdr = a2bin[:4]
+  bin = a2bin[4:]
 load_addr = hdr[0] | (hdr[1] << 8)
 load_size = hdr[2] | (hdr[3] << 8)
 assert load_size == len(bin)
@@ -39,5 +39,5 @@ load_size = len(bin)
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 
-with open(out_bin, 'wb') as fout:
+with open(out_a2bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index 1bbaa10..31202f8 100644 (file)
@@ -11,14 +11,14 @@ LOAD_ADDR=0x300
 HIRES_SCREEN=0x2000
 
 .PHONY: all
-all: test.dsk
+all: test.dsk zebra.ihx
 
-test.dsk: ../util/bootable.dsk dhgr.bin zebra.bin
+test.dsk: ../util/bootable.dsk dhgr.a2bin zebra.a2bin
        cp ../util/bootable.dsk $@
-       ${DOS33} $@ SAVE B dhgr.bin DHGR
-       ${DOS33} $@ SAVE B zebra.bin ZEBRA
+       ${DOS33} $@ SAVE B dhgr.a2bin DHGR
+       ${DOS33} $@ SAVE B zebra.a2bin ZEBRA
 
-dhgr.bin: dhgr.ihx
+dhgr.a2bin: dhgr.ihx
        ${HEX2BIN} $< __temp__.bin
        ./hdr.py ${LOAD_ADDR} __temp__.bin $@
        rm __temp__.bin
@@ -29,9 +29,21 @@ dhgr.ihx: dhgr.rel
 dhgr.rel: dhgr.asm
        ${AS6500} -l -o $<
 
-zebra.bin: zebra.dhr
+zebra.a2bin: zebra.dhr
        ./hdr.py ${HIRES_SCREEN} $< $@
 
+zebra.ihx: dhgr_viewer.bin zebra.dhr
+       ./dhr2hex.py ${LOAD_ADDR} $^ $@
+
+dhgr_viewer.bin: dhgr_viewer.ihx
+       ${HEX2BIN} $< $@
+
+dhgr_viewer.ihx: dhgr_viewer.rel
+       ${ASLINK} -n -m -u -i -b text=${LOAD_ADDR} $@ $^
+
+dhgr_viewer.rel: dhgr_viewer.asm
+       ${AS6500} -l -o $<
+
 .PHONY: clean
 clean:
-       rm -f *.bin *.hlr *.ihx *.lst *.map *.rel *.rst test.dsk
+       rm -f *.a2bin *.bin *.hlr *.ihx *.lst *.map *.rel *.rst test.dsk
index 5cdf536..1e8c5fb 100644 (file)
@@ -1,16 +1,6 @@
 ; display DHGR image by copying hires screen 0 to aux of hires screen 1
 
-hires_screen0 = 0x2000
-hires_screen1 = 0x4000
-hires_screen_size = 0x2000
-
-rom_a1 = 0x3c ; source addr
-rom_a2 = 0x3e ; source end (inclusive)
-rom_a4 = 0x42 ; dest addr
-rom_auxmove = 0xc311 ; cf=0 aux->main, cf=1 main->aux
-
-; read these
-hw_kbd = 0xc000
+; read/write
 hw_clrtext = 0xc050
 hw_settext = 0xc051
 hw_clrmixed = 0xc052
@@ -23,30 +13,19 @@ hw_setdhires = 0xc05e
 hw_setioudis = 0xc07e
 hw_clrioudis = 0xc07f
 
-; write these
-hw_clr80store = 0xc000
-hw_set80store = 0xc001
+; read
+hw_kbd = 0xc000
+
+; write
+hw_clr80col = 0xc000
+hw_set80col = 0xc001
 hw_clr80vid = 0xc00c
 hw_set80vid = 0xc00d
 hw_kbdstrb = 0xc010
 
        .area   text
 
-       lda     #<hires_screen0
-       sta     rom_a1
-       sta     rom_a4
-       lda     #>hires_screen0
-       sta     rom_a1 + 1
-       lda     #>hires_screen1
-       sta     rom_a4 + 1
-       lda     #<(hires_screen0 + hires_screen_size - 1)
-       sta     rom_a2
-       lda     #>(hires_screen0 + hires_screen_size - 1)
-       sta     rom_a2 + 1
-       sec
-       jsr     rom_auxmove
-
-       sta     hw_clr80store
+       sta     hw_clr80col
        lda     hw_clrioudis
 
        lda     hw_sethires
diff --git a/test/dhgr_viewer.asm b/test/dhgr_viewer.asm
new file mode 100644 (file)
index 0000000..e352d5a
--- /dev/null
@@ -0,0 +1,36 @@
+; read
+hw_kbd = 0xc000
+
+; write
+hw_clr80col = 0xc000
+hw_set80col = 0xc001
+hw_clr80vid = 0xc00c
+hw_set80vid = 0xc00d
+hw_kbdstrb = 0xc010
+
+; read/write
+hw_clrtext = 0xc050
+hw_settext = 0xc051
+hw_clrmixed = 0xc052
+hw_setmixed = 0xc053
+hw_page1 = 0xc054
+hw_page2 = 0xc055
+hw_clrhires = 0xc056
+hw_sethires = 0xc057
+hw_setdhires = 0xc05e
+hw_setioudis = 0xc07e
+hw_clrioudis = 0xc07f
+
+       .area   text
+
+       sta     hw_clr80col
+       lda     hw_clrioudis
+
+       lda     hw_sethires
+       lda     hw_clrtext
+       lda     hw_setdhires
+       lda     hw_clrmixed
+       lda     hw_page1
+       sta     hw_set80vid
+
+       jmp     .
diff --git a/test/dhr2hex.py b/test/dhr2hex.py
new file mode 100755 (executable)
index 0000000..be48546
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+import sys
+from intelhex import IntelHex
+
+EXIT_SUCCESS = 0
+EXIT_FAILURE = 1
+
+if len(sys.argv) < 5:
+  print(f'usage: {sys.argv[0]:s} load_addr dhgr_viewer.bin in.dhr out.ihx')
+  sys.exit(EXIT_FAILURE)
+load_addr = int(sys.argv[1], 0)
+in_dhgr_viewer_bin = sys.argv[2]
+in_dhr = sys.argv[3]
+out_ihx = sys.argv[4]
+
+dhgr_viewer_bin = []
+with open(in_dhgr_viewer_bin, 'rb') as fin:
+  dhgr_viewer_bin = list(fin.read())
+
+dhr = []
+with open(in_dhr, 'rb') as fin:
+  dhr = list(fin.read())
+assert len(dhr) == 0x4000
+
+intelhex = IntelHex()
+intelhex.start_addr = {'EIP': load_addr}
+for i in range(len(dhgr_viewer_bin)):
+  intelhex[load_addr + i] = dhgr_viewer_bin[i]
+for i in range(0x2000):
+  intelhex[0x2000 + i] = dhr[0x2000 + i]
+for i in range(0x2000):
+  intelhex[0x12000 + i] = dhr[i]
+intelhex.write_hex_file(out_ihx)