shape5.png \
shape6.png
-star_blazer.dsk: ../util/bootable.dsk star_blazer_lzss_loader.bin
+star_blazer.dsk: ../util/bootable.dsk star_blazer_lzss.bin
cp ../util/bootable.dsk $@
- ${DOS33} $@ SAVE B star_blazer_lzss_loader.bin "STAR BLAZER LZSS LOADER"
+ ${DOS33} $@ SAVE B star_blazer_lzss.bin "STAR BLAZER LZSS"
-star_blazer_lzss_loader.bin: \
-star_blazer_hires_loader.bin \
+star_blazer_lzss.bin: \
+star_blazer.bin \
../loader/lzss_loader.bin \
-../loader/star_blazer_lzss_loader.bin
+../loader/star_blazer_recrack_lzss.bin
../loader/lzss_encode.py ${LZSS_LOADER} ../loader/lzss_loader.bin $< $@
- -diff -q ../loader/star_blazer_lzss_loader.bin $@
+ -diff -q ../loader/star_blazer_recrack_lzss.bin $@
-star_blazer_hires_loader.bin: \
+star_blazer.bin: \
star_blazer.ihx \
-../loader/star_blazer_hires_loader.bin
- ./pack.py $< $@
- -diff -q ../loader/star_blazer_hires_loader.bin $@
+../loader/star_blazer_recrack.bin
+ ./a2_hex2bin.py $< $@
+ -diff -q ../loader/star_blazer_recrack.bin $@
star_blazer.ihx: star_blazer.rel
# add for DHGR: -b data1=0xd000
-b udata0=0x200 \
-b udata1=0x400 \
-b text=0x9fd \
--b loader=0x2000 \
-b data0=0x4000 \
$@ $<
shape_data.inc
${AS6500} -l -o $<
-star_blazer.asm: trace.txt star_blazer.txt mem.bin star_blazer.asm.patch
- ./disasm.py star_blazer.txt mem.bin $@ <trace.txt
+star_blazer.asm: \
+trace.txt \
+star_blazer.txt \
+../loader/star_blazer_recrack.bin \
+star_blazer.asm.patch
+ ./disasm.py star_blazer.txt ../loader/star_blazer_recrack.bin $@ <trace.txt
cp $@ $@0
patch $@ <$@.patch
shape_data.inc: shape.txt shape0.png
./shape_compile.py --data shape0.png <$< >$@
-shape0.png: mem.bin
+shape0.png: ../loader/star_blazer_recrack.bin
./shape_extract.py $< $@
shape1.png: shape0.png
shape0c.png: shape_dhgr.png
./shape_color_to_mono.py $< $@
-mem.bin: ../loader/star_blazer_hires_loader.bin
- ./load.py $^ $@
-
.PHONY: clean
clean:
rm -f \
--- /dev/null
+#!/usr/bin/env python3
+
+import bisect
+import sys
+from intelhex import IntelHex
+
+EXIT_SUCCESS = 0
+EXIT_FAILURE = 1
+
+if len(sys.argv) < 3:
+ print(f'usage: {sys.argv[0]:s} in.ihx out.bin')
+ sys.exit(EXIT_FAILURE)
+in_ihx = sys.argv[1]
+out_bin = sys.argv[2]
+
+intelhex = IntelHex(in_ihx)
+segments = [j for i in intelhex.segments() for j in i]
+for i in range(0, len(segments), 2):
+ print(f'[{segments[i]:04x}, {segments[i + 1]:04x})')
+
+load_addr = segments[0] #intelhex.minaddr()
+load_size = segments[-1] - load_addr #intelhex.maxaddr() + 1 - load_addr
+
+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:
+ fout.write(bytes(hdr + bin))
pc1 = int(line[8:12], 16)
# hacks so I don't have to redo the trace
- if pc0 >= 0x2000 and pc0 < 0x200f:
+ if pc0 == 0x9fd:
+ pc1 = 0x9ded
+ if pc0 >= 0x2000 and pc0 < 0x4000:
continue
- if pc0 >= 0x200f and pc0 < 0x2100:
- pc0 -= 0xf
- if pc1 >= 0x200f and pc0 < 0x2100:
- pc1 -= 0xf
if pc0 not in trace_nexts:
trace_nexts[pc0] = set()
print('reading image')
with open(in_bin, 'rb') as fin:
- mem = list(fin.read())
-assert len(mem) == 0x10000
+ data = list(fin.read())
+ hdr = data[:4]
+ bin = data[4:]
+load_addr = hdr[0] | (hdr[1] << 8)
+load_size = hdr[2] | (hdr[3] << 8)
+assert load_size == len(bin)
+
+mem = [0] * 0x10000
+mem[load_addr:load_addr + load_size] = bin
mpu = py65.devices.mpu65c02.MPU(mem, 0)
disassembler = py65.disassembler.Disassembler(mpu)
+++ /dev/null
-#!/usr/bin/env python3
-
-import sys
-
-EXIT_SUCCESS = 0
-EXIT_FAILURE = 1
-
-HIRES_SCREEN = 0x2000
-HIRES_SCREEN_SIZE = 0x2000
-
-if len(sys.argv) < 3:
- print(f'usage: {sys.argv[0]:s} in.bin out.bin')
- sys.exit(EXIT_FAILURE)
-in_bin = sys.argv[1]
-out_bin = sys.argv[2]
-
-with open(in_bin, 'rb') as fin:
- data = list(fin.read())
- hdr = data[:4]
- bin = data[4:]
-load_addr = hdr[0] + (hdr[1] << 8)
-load_size = hdr[2] + (hdr[3] << 8)
-assert len(bin) == load_size
-
-# load
-mem = [0] * 0x10000
-mem[load_addr:load_addr + load_size] = bin
-
-# initialize needed udata
-addr = HIRES_SCREEN
-while addr < HIRES_SCREEN + 0x32:
- assert mem[addr] == 0xa9 # lda #$nn
- data = mem[addr + 1]
- if mem[addr + 2] == 0x85: # sta $nn
- dest = mem[addr + 3]
- addr += 4
- elif mem[addr + 2] == 0x8d: # sta $nnnn
- dest = mem[addr + 3] + (mem[addr + 4] << 8)
- addr += 5
- else:
- assert False
- mem[dest] = data
-
-# relocate
-relocate_addr = HIRES_SCREEN + 0x4e
-assert mem[relocate_addr - 3:relocate_addr] == \
- [0x6c, 0x20, 0x00] # jmp [vec_start]
-relocate_size = HIRES_SCREEN + HIRES_SCREEN_SIZE - relocate_addr
-assert mem[0x2039] == 0x9d # sta end_of_image - hires_screen_size
-end_of_image = mem[0x203a] + (mem[0x203b] << 8) + HIRES_SCREEN_SIZE
-mem[end_of_image - relocate_size:end_of_image] = \
- mem[relocate_addr:relocate_addr + relocate_size]
-mem[relocate_addr:relocate_addr + relocate_size] = \
- [0] * relocate_size
-
-with open(out_bin, 'wb') as fout:
- fout.write(bytes(mem))
+++ /dev/null
-#!/usr/bin/env python3
-
-import bisect
-import sys
-from intelhex import IntelHex
-
-EXIT_SUCCESS = 0
-EXIT_FAILURE = 1
-
-HIRES_SCREEN = 0x2000
-HIRES_SCREEN_SIZE = 0x2000
-
-defeat = False
-if len(sys.argv) >= 2 and sys.argv[1] == '--defeat':
- defeat = True
- del sys.argv[1]
-if len(sys.argv) < 3:
- print(f'usage: {sys.argv[0]:s} [--defeat] in.ihx out.bin')
- sys.exit(EXIT_FAILURE)
-in_ihx = sys.argv[1]
-out_bin = sys.argv[2]
-
-intelhex = IntelHex(in_ihx)
-intelhex.padding = 0
-load_addr = intelhex.minaddr()
-bin = list(intelhex.tobinstr(load_addr, intelhex.maxaddr()))
-segments = [j for i in intelhex.segments() for j in i]
-for i in range(0, len(segments), 2):
- print(f'[{segments[i]:04x}, {segments[i + 1]:04x})')
-
-# language-card version of relocator is slightly larger
-relocator = HIRES_SCREEN + 0x32
-if (
- bin[relocator - load_addr:relocator + 6 - load_addr] ==
- [0xad, 0x87, 0xc0] * 2 # lda hw_lc_bank1_ram_we twice
-):
- relocator += 6
-
-# what will be relocated at runtime
-assert bin[relocator - load_addr] == 0xa2 # ldx #NN
-assert bin[relocator + 4 - load_addr] == 0xbd # lda MM00,x
-assert bin[relocator + 5 - load_addr] == 0x00
-addr = (
- bin[relocator + 1 - load_addr] |
- (bin[relocator + 6 - load_addr] << 8)
-) # MMNN
-assert bin[addr - 3 - load_addr] == 0x6c # jmp [vec_start]
-assert bin[addr - 2 - load_addr] == 0x20
-assert bin[addr - 1 - load_addr] == 0x00
-
-# how much will be copied at runtime
-size = HIRES_SCREEN + HIRES_SCREEN_SIZE - addr
-rounding = ((size + 0xff) & 0xff00) - size # >0 if first block is partial
-assert bin[relocator + 2 - load_addr] == 0xa0 # ldy #NN
-assert bin[relocator + 3 - load_addr] == (size + rounding) >> 8
-
-# where it will be copied to
-dest = load_addr + len(bin) - size
-assert bin[relocator + 7 - load_addr] == 0x9d # sta MM00,x
-assert bin[relocator + 8 - load_addr] == (dest - rounding) & 0xff
-assert bin[relocator + 9 - load_addr] == (dest - rounding) >> 8
-
-print(f'addr {addr:04x} size {size:04x} dest {dest:04x}')
-
-# if dest falls between segments, adjust up to start of next segment
-i = bisect.bisect_right(segments, dest)
-if (i & 1) == 0:
- diff = segments[i] - dest
- i += 1
-
- addr += diff
- bin[relocator + 1 - load_addr] = addr & 0xff
- bin[relocator + 6 - load_addr] = addr >> 8
- size -= diff
- rounding = ((size + 0xff) & 0xff00) - size # >0 if first block is partial
- bin[relocator + 3 - load_addr] = (size + rounding) >> 8
- dest += diff
- bin[relocator + 8 - load_addr] = (dest - rounding) & 0xff
- bin[relocator + 9 - load_addr] = (dest - rounding) >> 8
-
- print(f'diff {diff:04x} addr {addr:04x} size {size:04x} dest {dest:04x}')
-
-# relocate
-if defeat: # just nop out the relocation code
- bin[0x2033 - load_addr:0x2049 - load_addr] = [0xff] + [0xea] * 0x15
-else:
- bin[addr - load_addr:addr + size - load_addr] = bin[dest - load_addr:]
- del bin[dest - load_addr:]
-
- # if (adjusted) dest falls at start of segment, trim off padding
- if dest == segments[i - 1]:
- trim = segments[i - 2]
- print(f'trim {trim:04x}')
- assert bin[trim - load_addr:] == [0] * (load_addr + len(bin) - trim)
- del bin[trim - load_addr:]
-
-load_size = len(bin)
-hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-
-with open(out_bin, 'wb') as fout:
- fout.write(bytes(hdr + bin))
out_png = sys.argv[2]
with open(in_bin, 'rb') as fin:
- mem = list(fin.read())
-assert len(mem) == 0x10000
+ data = list(fin.read())
+ hdr = data[:4]
+ bin = data[4:]
+load_addr = hdr[0] | (hdr[1] << 8)
+load_size = hdr[2] | (hdr[3] << 8)
+assert load_size == len(bin)
+
+mem = [0] * 0x10000
+mem[load_addr:load_addr + load_size] = bin
image_out = numpy.zeros((PITCH_Y * 32, PITCH_X * 8), numpy.uint8)
0x0200,0x0002,udata0,uninit
0x0400,0x03f0,udata1,uninit
0x09fd,0x1603,text,init
-0x2000,0x004e,loader,init
-0x4000,0x5ded,data0,init
+0x4000,0x5e1e,data0,init
0xa800,0x0d80,udata2,uninit
items
-0x0020,0x0002,vec_start,word
0x0022,0x0002,vec_init_game,word
0x0024,0x0002,vec_start_game,word
0x0028,0x0002,vec_calculate_object_shape,word
0x00f1,0x0001,button_state,byte
# >= 0x80 = key waiting (uses lsr to clear it)
0x00f2,0x0001,key_state,byte
+0x0200,0x0002,vec_restart,word
0x0400,0x0070,object1080_onscreen,byte
0x0480,0x0070,object1080_onscreen_clipped,byte
0x0500,0x0070,object1080_onscreen_x0,byte
0x16fd,0x0001,inc_mission,code
0x1708,0x0001,init_game,code
0x1719,0x0001,start_game_demo,code
-0x171b,0x0001,start_game_entry,code
+0x171b,0x0001,start_game,code
0x1750,0x0001,test_key,code
0x1797,0x0001,read_buttons,code
0x17b1,0x0001,vector_to_start_game,code
0x1db6,0x0008,draw_misc_mask_table,byte
0x1dbe,0x0008,draw_misc_mask_xor_table,byte
0x1e03,0x0001,test_player_fire,code # returns cf=1 if firing (random for demo mode)
-0x2036,0x0001,,code_ign # relocator source (don't merge source instructions)
-0x2037,0x0002,,word
-0x2039,0x0001,,code_ign # relocator destination (don't create a label for it)
-0x203a,0x0002,,word
+0x2000,0x2000,hires_screen,byte
0x4000,0x0100,shape_data_ptr_lo,byte
0x4100,0x0100,shape_data_ptr_hi,byte
0x4200,0x0100,shape_width_bytes,byte
0x9dd9,0x0001,microcode_table_55c6_data_9dd9,byte
0x9dde,0x0001,microcode_table_5658_data_9dde,byte
0x9de0,0x0001,microcode_table_5758_data_9de0,byte
+0x9ded,0x0001,recrack_loader,byte
0xa800,0x0001,x_table_times2_div7_plus_5b,byte
0xa900,0x0001,x_table_times2_mod7_minus_03,byte
0xaa00,0x0001,video_line_table_lo,byte
HEX2BIN=hex2bin.py
LZSS_LOADER=0x800
-HIRES_LOADER=0x2000
+RECRACK_LOADER=0x9ded
.PHONY: all
all: \
star_blazer.bin \
star_blazer_dejunked0.bin \
star_blazer_dejunked1.bin \
-star_blazer_lzss_loader.bin
+star_blazer_recrack_lzss.bin
star_blazer.bin: ../orig/Star_Blazer_1981_Star_Craft.do
${DOS33} ../orig/Star_Blazer_1981_Star_Craft.do LOAD "STAR BLAZER" $@
star_blazer_dejunked1.bin: star_blazer.bin
./dejunk.py $< $@ 0xff
-star_blazer_lzss_loader.bin: lzss_loader.bin star_blazer_hires_loader.bin
+star_blazer_recrack_lzss.bin: lzss_loader.bin star_blazer_recrack.bin
./lzss_encode.py ${LZSS_LOADER} $^ $@
lzss_loader.bin: lzss_loader.ihx
lzss_loader.rel: lzss_loader.asm
${AS6500} -l -o $<
-star_blazer_hires_loader.bin: hires_loader.bin star_blazer_dejunked0.bin
- ./hires_loader.py $^ $@
+star_blazer_recrack.bin: recrack_loader.bin star_blazer_dejunked0.bin
+ ./recrack.py $^ $@
-hires_loader.bin: hires_loader.ihx
+recrack_loader.bin: recrack_loader.ihx
${HEX2BIN} $< $@
-hires_loader.ihx: hires_loader.rel
- ${ASLINK} -n -m -u -i -b text=${HIRES_LOADER} $@ $^
+recrack_loader.ihx: recrack_loader.rel
+ ${ASLINK} -n -m -u -i -b text=${RECRACK_LOADER} $@ $^
-hires_loader.rel: hires_loader.asm
+recrack_loader.rel: recrack_loader.asm
${AS6500} -l -o $<
clean:
+++ /dev/null
-vec_start = 0x20
-start = 0x17d1
-
-vec_init_game = 0x22
-init_game = 0x1708
-
-vec_start_game = 0x24
-start_game = 0x171b
-
-vec_calculate_object_shape = 0x28
-calculate_object_shape = 0x0d6c
-
-vec_draw_miscellaneous_from_table = 0x4e
-draw_miscellaneous_from_table = 0x1d1c
-
-vec_unknown = 0x0200
-unknown = 0x1999
-
-; also address of loader
-hires_screen = 0x2000
-hires_screen_size = 0x2000
-
-; points after last byte initialized by loader
-end_of_image = 0x9ded
-
- .r65c02
-
- .area text
-
- lda #<start
- sta vec_start
- lda #>start
- sta vec_start + 1
-
- lda #<init_game
- sta vec_init_game
- lda #>init_game
- sta vec_init_game + 1
-
- lda #<start_game
- sta vec_start_game
- lda #>start_game
- sta vec_start_game + 1
-
- lda #<calculate_object_shape
- sta vec_calculate_object_shape
- lda #>calculate_object_shape
- sta vec_calculate_object_shape + 1
-
- lda #<draw_miscellaneous_from_table
- sta vec_draw_miscellaneous_from_table
- lda #>draw_miscellaneous_from_table
- sta vec_draw_miscellaneous_from_table + 1
-
- lda #<unknown
- sta vec_unknown
- lda #>unknown
- sta vec_unknown + 1
-
- ldx #<2$ ; skip loader size in first 0x100-byte block
- ldy #>hires_screen_size ; number of 0x100-byte blocks
-1$: lda hires_screen,x
- sta end_of_image - hires_screen_size,x
- inx
- bne 1$
- inc 1$+2
- inc 1$+5
- dey
- bne 1$
-
- dex
- txs
- cld
- jmp [vec_start]
-
-2$: ; start of data relocated by loader
+++ /dev/null
-#!/usr/bin/env python3
-
-import sys
-
-EXIT_SUCCESS = 0
-EXIT_FAILURE = 1
-
-if len(sys.argv) < 4:
- print(f'usage: {sys.argv[0]:s} my_loader.bin in.bin out.bin')
- sys.exit(EXIT_FAILURE)
-my_loader_bin = sys.argv[1]
-in_bin = sys.argv[2]
-out_bin = sys.argv[3]
-
-with open(my_loader_bin, 'rb') as fin:
- my_loader = list(fin.read())
-
-with open(in_bin, 'rb') as fin:
- data = list(fin.read())
- hdr = data[:4]
- bin = data[4:]
-assert len(bin) == 0x9300
-
-bin = bin[0x06fd:0x9300] + bin[0x1d00:0x24ed]
-assert len(bin) == 0x93f0 # [0x09fd:0x9ded)
-
-load_addr = 0x09fd
-hires_screen = 0x2000 - load_addr
-hires_screen_size = 0x2000
-
-relocate_start = hires_screen + len(my_loader)
-relocate_size = hires_screen_size - len(my_loader)
-bin[hires_screen:relocate_start] = my_loader
-bin[relocate_start:hires_screen + hires_screen_size] = bin[-relocate_size:]
-bin[-relocate_size:] = []
-load_size = len(bin)
-
-bin[:3] = [0x4c, 0x00, 0x20] # jmp 0x2000
-hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-
-with open(out_bin, 'wb') as fout:
- fout.write(bytes(hdr + bin))
--- /dev/null
+#!/usr/bin/env python3
+
+import sys
+
+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')
+ sys.exit(EXIT_FAILURE)
+recrack_loader_bin = sys.argv[1]
+in_bin = sys.argv[2]
+out_bin = 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:]
+load_addr = hdr[0] | (hdr[1] << 8)
+load_size = hdr[2] | (hdr[3] << 8)
+assert load_size == len(bin)
+
+assert load_size == 0x9300
+entry_point = 0x9ded
+
+bin = (
+ [0x4c, 0xed, 0x9d] + # jmp 0x9ded, end of image
+ bin[0x0a00 - load_addr:0x2000 - load_addr] + # [0x0a00, 0x2000)
+ [0] * 0x2000 + # [0x2000, 0x4000)
+ bin[0x4000 - load_addr:0x9600 - load_addr] + # [0x4000, 0x9600)
+ bin[0x2000 - load_addr:0x27ed - load_addr] + # [0x9600, 0x9ded)
+ recrack_loader
+)
+load_addr = 0x09fd
+load_size = len(bin)
+
+hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
+
+with open(out_bin, 'wb') as fout:
+ fout.write(bytes(hdr + bin))
--- /dev/null
+vec_start = 0x20
+start = 0x17d1
+
+vec_init_game = 0x22
+init_game = 0x1708
+
+vec_start_game = 0x24
+start_game = 0x171b
+
+vec_calculate_object_shape = 0x28
+calculate_object_shape = 0x0d6c
+
+vec_draw_misc_from_table = 0x4e
+draw_misc_from_table = 0x1d1c
+
+vec_restart = 0x0200
+restart = 0x1999
+
+ .r65c02
+
+ .area text
+
+ ldx #0xff
+ txs
+ cld
+
+ ; this doesn't seem to be referenced after start
+ ;lda #<start
+ ;sta vec_start
+ ;lda #>start
+ ;sta vec_start + 1
+
+ lda #<init_game
+ sta vec_init_game
+ lda #>init_game
+ sta vec_init_game + 1
+
+ lda #<start_game
+ sta vec_start_game
+ lda #>start_game
+ sta vec_start_game + 1
+
+ lda #<calculate_object_shape
+ sta vec_calculate_object_shape
+ lda #>calculate_object_shape
+ sta vec_calculate_object_shape + 1
+
+ lda #<draw_misc_from_table
+ sta vec_draw_misc_from_table
+ lda #>draw_misc_from_table
+ sta vec_draw_misc_from_table + 1
+
+ lda #<restart
+ sta vec_restart
+ lda #>restart
+ sta vec_restart + 1
+
+ jmp start