From 86adaf42b548c778b286c23fc4f911759dfb618a Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Fri, 24 Jun 2022 14:05:07 +1000 Subject: [PATCH] More analysis of the microcode opcode format --- disasm/star_blazer.txt | 109 +++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/disasm/star_blazer.txt b/disasm/star_blazer.txt index 6391f9c..ffb38d3 100644 --- a/disasm/star_blazer.txt +++ b/disasm/star_blazer.txt @@ -52,7 +52,7 @@ items # decimal + 0xe: ? 0x00b0,0x0010,decimal,byte 0x00c0,0x0002,microcode_ptr_c0,word -0x00c2,0x0001,microcode_test_object,byte +0x00c2,0x0001,microcode_pair_object,byte 0x00c7,0x0001,microcode_object_c7,byte 0x00c8,0x0001,sp_save,byte 0x00c9,0x0001,microcode_x_save_c9,byte @@ -140,18 +140,97 @@ items 0x0f57,0x0001,decimal_inc,code 0x0f66,0x0001,decimal_dec,code 0x0f83,0x0001,vector_to_update_a_decimal,code -0x0f8d,0x0001,microcode_test_end,code +0x0f8d,0x0001,microcode_score,code 0x0fb1,0x0001,adjust_score_for_reset_object,code -0x0fdb,0x0001,microcode_test_loop,code -# enter with a = command from microcode, microcode_test_object setup -# these values come from do_microcode_test (I think the only external caller) -0x0fdd,0x0001,microcode_test,code +0x0fb9,0x0001,microcode_byte,code +0x0fdb,0x0001,go_microcode_score,code +# enter with microcode_pair_object = 1st byte of microcode pair, a = 2nd byte +# these values come from do_microcode_pair (I think the only external caller) +# does ldx *microcode_pair_object first, so in below, "object" refers to this +# 1st byte: +# < 0x10: go to check_microcode_status_bits +# if 1st byte bit 0 = 1, only do the rest if demo mode (otherwise continue) +# if 1st byte bit 1 = 1, only do the rest if NOT demo mode (otherwise done) +# < 0x04: go to 2$ +# 2nd byte: +# < 0x20: clear demo mode, set mission from 2nd byte bits 0..3 +# < 0x30: set demo mode, set mission from 2nd byte bits 0..3 +# < 0xa0: vector to start game +# >= 0xa0: start game demo +# < 0x08: go to microcode_score, with unusual bcc -> bcc instruction +# 2nd byte bits 4..7 +# == 0x30: vector to update a decimal based on 2nd byte bits 0..2 +# .dw loc_0ebc - 1 +# .dw loc_0ebc - 1 +# .dw loc_0ec1 - 1 +# .dw loc_0ece - 1 +# .dw loc_0ed4 - 1 +# .dw loc_0edc - 1 +# .dw loc_0ee4 - 1 +# .dw loc_0eec - 1 +# == 0x40: decimal increment +# 2nd byte bits 0..2 are *2 and give index into decimals array +# == 0x50: decimal decrement +# 2nd byte bits 0..2 are *2 and give index into decimals array +# == 0x70: go to 0$ +# 2nd byte bits 0..2 are *2 and give index into decimals array +# == 0x20: vector to draw misc from table +# 2nd byte bits 0..2 are +1 and sent into draw_misc_from_table +# otherwise ignored +# < 0x0c: go to 6$ +# 2nd byte: +# < 0xe1: vector to draw_misc_from_table (title display, etc) +# >= 0xe1: +# 2nd byte bit 0 = 0: vector to restart +# 2nd byte bit 0 = 1: video clear rectangle +# >= 0x0c: 2nd byte is a sound channel? 01..10 +# store 1st byte into sound_status_ab80[2nd byte - 1] +# >= 0x10: 1st byte is object for opcode in 2nd byte +# 2nd byte: +# < 0x08: go to 0$ +# if object is active, change its shape using 2nd byte bits 0..1 +# < 0x0e: go to 3$ +# vector to microcode_vectors routine based on 2nd byte bits 0..2 +# .dw horizontal_collision_and_zero - 1 +# .dw vertical_collision_and_zero - 1 +# .dw horizontal_collision - 1 +# .dw vertical_collision - 1 +# .dw horizontal_collision_and_copy - 1 +# .dw vertical_collision_and_copy - 1 +# = 0x0e: go to 1$ +# decrement object1080_countdown_b190, returns zf=1 terminal count? +# != 0x0f: go to microcode_byte +# if bit 7 = 0, then only do the rest if the object is inactive +# vector to routine based on 2nd byte bits 4..6 +# .dw rts_0a11 - 1 +# .dw randomize_object_position - 1 +# .dw copy_object_position - 1 +# .dw randomize_object_position_relative - 1 +# .dw move_object_pos_pos - 1 +# .dw move_object_neg_pos - 1 +# .dw move_object_neg_neg - 1 +# .dw move_object_pos_neg - 1 +# vector to routine based on 2nd byte bits 0..2 +# .dw rts_0a11 - 1 +# .dw randomize_object_velocity - 1 +# .dw copy_object_velocity - 1 +# .dw randomize_object_velocity_relative - 1 +# .dw update_object_velocity - 1 +# .dw update_object_velocity_rotate_90 - 1 +# .dw update_object_velocity_rotate_180 - 1 +# .dw update_object_velocity_rotate_270 - 1 +# if bit 3 = 1, and object1080_start_sentinel[x] != 0: +# make object active and compute bounds +# else +# reset object state +# = 0x0f: if object is active, make it inactive and erase it +0x0fdd,0x0001,microcode_pair,code 0x1009,0x0001,vector_to_microcode,code 0x1016,0x0001,check_microcode_status_bits,code -# enter with a = value for microcode_test_object, microcode_ptr_c0 setup, +# enter with a = value for microcode_pair_object, microcode_ptr_c0 setup, # y = index into table at microcode_ptr_c0 (it will be incremented twice) -# routine loads a command from the microcode table and calls microcode_test -0x106a,0x0001,do_microcode_test,code +# routine loads a command from the microcode table and calls microcode_pair +0x106a,0x0001,do_microcode_pair,code 0x107c,0x0001,decimal_zero,code # zf=1 -> go to loc_10cd # otherwise load microcode_start_sentinel from object1080_start_sentinel, @@ -162,7 +241,7 @@ items # if it's not then keep skipping 2 locations until end of table or found # when found, skip 2 locations and check for more commands (0 is end of # table, >= 0xf0 is a different section, otherwise execute + zf=0 repeat -# otherwise execute it via do_microcode_test, and check zf return because +# otherwise execute it via do_microcode_pair, and check zf return because # zf=1 means terminate the loop at loc_10cd otherwise keep executing loop # in summary there seems to be a global section at the start of the table that # is always executed, and a specific section to execute based on current state @@ -175,15 +254,15 @@ items 0x10cd,0x0001,microcode_execute_1093_done,code_ign # bug? spans ae80 and aef0 tables, don't merge them # it seems to read values from table at microcode_ptr_c0 with some complicated # indirection (value from table = index to use for next read from table?) and -# it executes them by calling do_microcode_test, this may read adjacent value? +# it executes them by calling do_microcode_pair, this may read adjacent value? # microcode_start_sentinel = counter that gets decremented to 0 # bvar_00cb = start index in table, and is advanced by the routine 0x10d1,0x0001,microcode_execute_10d1,code 0x10ed,0x0001,adjust_score,code 0x1153,0x0001,reset_decimals,code 0x1160,0x0001,reset_object_state,code -0x11a7,0x0001,set_object1080_start_sentinel_bit7_and_compute_object_bounds,code -0x11b2,0x0001,clear_object1080_start_sentinel_bit7_and_erase_object,code +0x11a7,0x0001,make_object_active_and_compute_bounds,code +0x11b2,0x0001,make_object_inactive_and_erase,code 0x11bd,0x0001,countdown_b120_or_b190_expired,code 0x1291,0x0001,homing_test,code 0x12e1,0x0001,accelerate_object_towards_another,code @@ -839,8 +918,8 @@ items # .db 0xf9 -> repeating, & 0xf3 for start sentinel (0xf1) # .db 0x00 sentinel # object1080_animate_shape_index + 0x4d holds the index into above table +# loc_0da6 does a post-increment # loc_0daf controls wraparound when sentinel >= 0xf0 reached -# loc_0da6 does a post-increment # loc_0dac for 0xff # loc_0db9 for 0xf8..0xfe (repeating, & 0xf3 for the start sentinel) # 0xf0..0xf3 value is poked into object1080_start_sentinel + object, and @@ -852,7 +931,7 @@ items # loc_0ddc a = table index where start sentinel was found (or end sentinel) # update object1080_animate_shape_index with this index (causes the # wrapping to restart the animation sequence) ... resume at loc_0da6 -# note: the microcode_test routine seems implicated in launching this: +# note: the microcode_pair routine seems implicated in launching this: # 0$: ldy object1080_start_sentinel - 0x10,x # bpl 2$ # and #0x03 -- 2.34.1