Created
December 1, 2021 12:39
-
-
Save tndata/313688ffe2e2d24b676e2264a9943d5c to your computer and use it in GitHub Desktop.
Sega MegaDrive development kit debugger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
****************************************** | |
*SEGA Megadrive comunication program * | |
*(c) 1991 Synchron Assembly * | |
*https://www.tn-data.se * | |
****************************************** | |
*f1=trace, f2=skip instruction f4=go | |
*d xxxx set dissasm window, d pc | |
*m xxxx set memory window, m pc | |
*j xxxx set sega PC | |
*bs xxxx set breakpoint | |
*br xxxx remove breakpoint | |
*f xx fill Sega rom memory with xx | |
*t busrt send game from ST to SEGA | |
*q quit | |
*l name load a sega file to adr 0 | |
*dir | |
****************************************** | |
max_breakptr: equ 8 | |
diss: | |
*Packets sendt from Sega to ST | |
*Header 'D' ($44) | |
*1: berr | |
*2: adrerror | |
*3: illegal | |
*4: zero | |
*5: chk | |
*6: trapv | |
*7: priv | |
*8: line-a | |
*9: line-f | |
*10:All registers, D0-D7/A0-A7,PC,SR | |
*11:12 bytes data som varje adressregister pekar p† i Segan, f”r reg displayen | |
*12:SEGA IRQ level 2 msg | |
*Header 'S' | |
*1: Continue exection | |
*2: Burstsend data from SRAM to ST | |
*3: Burst Send data from Z80 to ST | |
start move.l 4(A7),a0 | |
move.l a0,basepage | |
move.l $18(a0),a1 | |
add.l $1c(a0),a1 | |
adda.l #$4000,a1 | |
move.l a1,sp | |
sub.l basepage,a1 | |
move.l a1,-(a7) | |
move.l basepage,-(a7) | |
clr.w -(a7) | |
move.w #$4a,-(A7) | |
trap #1 | |
add.l #12,a7 | |
tst.l d0 | |
bsr init | |
bsr init_display | |
bsr reset_megadrive | |
tst.w d0 | |
beq.s .c0 *Reset ok? | |
illegal | |
.c0: | |
bsr boot_sega | |
bsr update_display | |
bsr get_diswin_data | |
bsr update_dis_window | |
bsr get_memwin_data | |
bsr update_mem_window | |
*Wait for Dbug commands | |
main_loop: | |
bsr check_sega | |
tst.w d0 | |
beq.s main_loop | |
bsr check_keyboard | |
tst.w d0 | |
bmi.s .ex | |
cmp.w #2,d0 | |
bne.s .c0 | |
bsr check_command | |
tst.w d0 | |
bmi.s .ex | |
bne.s main_loop | |
.c0: | |
bra.s main_loop | |
.ex: illegal | |
**************************************************** | |
check_command: | |
*Ask for the start adress of the window | |
move.l last_key(pc),d0 | |
beq.s .x | |
st lastkey_flag | |
moveq #39,d0 | |
lea rad,a0 | |
move.w #0,cx | |
move.w #24,cy | |
bsr input_line | |
tst.w d0 | |
bne.s .x | |
bsr process_command | |
.x: | |
rts | |
even | |
rts | |
**************************************************** | |
*Kolla tangentbord om n†gon tangent „r nertryckt | |
check_keyboard: | |
move.w #$b,-(a7) | |
trap #1 | |
addq.w #2,a7 | |
tst.w d0 | |
beq.s .nokey | |
bsr get_key | |
cmp.b #$1b,d0 | |
beq.s .quit | |
swap d0 | |
lea gem_kbdtab(pc),a0 | |
.l1: move.w (a0)+,d1 | |
bmi.s .nofound | |
cmp.w d0,d1 | |
beq.s .found | |
addq.w #6,a0 | |
bra.s .l1 | |
.found: | |
tst.w (a0)+ | |
beq.s .c0 | |
tst.b monitor_flag | |
bne.s .c0 | |
moveq #0,d0 | |
rts | |
.c0: | |
move.l (a0),a0 | |
jmp (a0) | |
.nofound: | |
moveq #2,d0 | |
rts | |
.nokey: moveq #1,d0 | |
rts | |
.quit: moveq #-1,d0 | |
rts | |
gem_kbdtab: | |
*Keycode, -1=only accessable while in Sega-bug, 0=don't care | |
dc.w $48,0 | |
dc.l curs_up | |
dc.w $50,0 | |
dc.l curs_down | |
dc.w $4b,0 | |
dc.l curs_left | |
dc.w $4d,0 | |
dc.l curs_right | |
dc.w $3b,-1 | |
dc.l sega_trace | |
dc.w $3c,-1 | |
dc.l sega_skip | |
dc.w $3d,-1 | |
dc.l sega_gobreak | |
dc.w $3e,-1 | |
dc.l sega_go | |
dc.w $f,0 | |
dc.l change_window | |
dc.l -1,-1 | |
.quit: moveq #-1,d0 | |
rts | |
curs_up: | |
move.w aktiv_window(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l memwin_up,diswin_down | |
curs_down: | |
move.w aktiv_window(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l memwin_down,diswin_up | |
curs_left: | |
move.w aktiv_window(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l memwin_left,diswin_down | |
curs_right: | |
move.w aktiv_window(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l memwin_right,diswin_up | |
diswin_up: | |
move.l disrowsize,d0 | |
btst.b #1,shift_flag | |
beq.s .nos | |
move.l disrowsize+40,d0 | |
.nos: move.l d0,diswin_ptr | |
bsr get_diswin_data | |
bsr update_dis_window | |
moveq #0,d0 | |
rts | |
diswin_down: | |
sub.l #2,diswin_ptr | |
bsr get_diswin_data | |
bsr update_dis_window | |
moveq #0,d0 | |
rts | |
memwin_left: | |
subq.l #1,memwin_ptr | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
memwin_right: | |
addq.l #1,memwin_ptr | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
memwin_up: | |
moveq #4,d0 *shift | |
btst.b #1,shift_flag | |
beq.s .nos | |
moveq #48,d0 | |
.nos: sub.l d0,memwin_ptr | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
memwin_down: | |
moveq #4,d0 *shift | |
btst.b #1,shift_flag | |
beq.s .nos | |
moveq #48,d0 | |
.nos: add.l d0,memwin_ptr | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
**************************************************** | |
*Single step all instructions including jcc,bsr | |
sega_gobreak: | |
moveq #"S",d0 *Sega SRAM | |
bsr send_byte | |
moveq #2,d0 | |
bsr send_byte | |
move.l sega_pc(pc),a0 | |
lea temp(pc),a1 | |
moveq #12,d0 | |
bsr burst_recieve | |
.x: moveq #0,d0 | |
moveq #20,d0 | |
bsr print_msg | |
move.l #0,obj_start | |
move.l #0,base_page | |
move.l #temp,dis_adr | |
move.l #temp+12,dis_ptr | |
move.l a6,-(a7) | |
jsr dis | |
move.l (a7)+,a6 | |
sub.l #temp,a0 | |
move.l a0,d0 | |
add.l sega_pc(pc),d0 | |
move.l d0,a0 | |
moveq #2,d0 | |
bsr add_break | |
bsr sega_go | |
* moveq #"S",d0 *GO | |
* bsr send_byte | |
* moveq #1,d0 | |
* bsr send_byte | |
moveq #0,d0 | |
rts | |
**************************************************** | |
get_diswin_data: | |
move.w diswin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l .sram,.stram | |
.sram: | |
tst.b monitor_flag | |
beq.s .x | |
moveq #"S",d0 *Sega SRAM | |
bsr send_byte | |
moveq #2,d0 | |
bsr send_byte | |
lea diswin_buf(pc),a1 | |
move.l diswin_ptr(pc),d0 | |
tst.l d0 | |
bmi.s .er | |
cmp.l #$400000-48,d0 *Rom? | |
blt.s .c0 | |
cmp.l #$ff0000,d0 | |
blt.s .er | |
cmp.l #$ffffff-48,d0 | |
bls.s .c0 | |
.er: moveq #0,d0 | |
.c0: | |
move.l d0,diswin_ptr | |
move.l diswin_ptr(pc),a0 | |
moveq #48,d0 | |
bsr burst_recieve | |
moveq #0,d0 | |
rts | |
.stram: | |
lea diswin_buf(pc),a1 | |
move.l diswin_ptr(pc),d0 | |
tst.l d0 | |
bpl.s .c9 | |
moveq #0,d0 | |
.c9: cmp.l #$3fffc0,d0 | |
bls.s .c1 | |
move.l #$3fffc0,d0 | |
.c1: move.l d0,a0 | |
move.l d0,diswin_ptr | |
moveq #48,d0 | |
.l1: move.b (a0)+,(a1)+ | |
dbra d0,.l1 | |
.x: moveq #0,d0 | |
rts | |
**************************************************** | |
*transfere the correct memwin data in to memwin_buf | |
get_memwin_data: | |
move.w memwin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l .sram,.stram,.z80,.vram | |
.sram: | |
tst.b monitor_flag | |
beq .x | |
moveq #"S",d0 *Sega SRAM | |
bsr send_byte | |
moveq #2,d0 | |
bsr send_byte | |
lea memwin_buf(pc),a1 | |
move.l memwin_ptr(pc),d0 | |
tst.l d0 | |
bmi.s .er | |
cmp.l #$400000,d0 *Rom? | |
blt.s .c0 | |
cmp.l #$ff0000,d0 | |
blt.s .er | |
cmp.l #$ffffff-48,d0 | |
bls.s .c0 | |
.er: moveq #0,d0 | |
.c0: | |
move.l d0,memwin_ptr | |
move.l d0,a0 | |
moveq #48,d0 | |
bsr burst_recieve | |
moveq #0,d0 | |
rts | |
.stram: | |
lea memwin_buf(pc),a1 | |
move.l memwin_ptr(pc),d0 | |
tst.l d0 | |
bpl.s .c9 | |
moveq #0,d0 | |
.c9: cmp.l #$3fffc0,d0 | |
bls.s .c1 | |
move.l #$3fffc0,d0 | |
.c1: move.l d0,a0 | |
move.l d0,memwin_ptr | |
moveq #48,d0 | |
.l1: move.b (a0)+,(a1)+ | |
dbra d0,.l1 | |
moveq #0,d0 | |
rts | |
.z80: | |
tst.b monitor_flag | |
beq.s .x | |
move.l memwin_ptr(pc),d0 | |
tst.l d0 | |
bpl.s .c2 | |
moveq #0,d0 | |
.c2: cmp.l #$7ec0,d0 | |
bls.s .c3 | |
move.l #$7ec0,d0 | |
.c3: move.l d0,memwin_ptr | |
moveq #"S",d0 *Sega Z80 | |
bsr send_byte | |
moveq #8,d0 | |
bsr send_byte | |
lea memwin_buf(pc),a1 | |
move.l memwin_ptr(pc),a0 | |
add.l #$a00000,a0 | |
moveq #48,d0 | |
bsr burst_recieve | |
.x: moveq #0,d0 | |
rts | |
.vram: | |
tst.b monitor_flag | |
beq.s .x | |
moveq #"S",d0 *Sega Z80 | |
bsr send_byte | |
moveq #9,d0 | |
bsr send_byte | |
move.l memwin_ptr(pc),d0 | |
tst.l d0 | |
bpl.s .c7 | |
moveq #0,d0 | |
.c7: cmp.l #$ffd4,d0 | |
bls.s .c8 | |
move.l #$ffd4,d0 | |
.c8: move.l d0,memwin_ptr | |
move.l d0,a0 | |
lea memwin_buf(pc),a1 | |
moveq #48,d0 | |
bsr burst_recieve | |
move.w #37,-(a7) | |
trap #14 | |
addq.w #2,a7 | |
moveq #0,d0 | |
rts | |
**************************************************** | |
*TAB = change current aktiv window | |
*TAB + shift = change current window type | |
change_window: | |
btst #1,shift_flag | |
bne.s .sh | |
*Byt aktivt f”nster | |
addq.w #1,aktiv_window | |
cmp.w #2,aktiv_window | |
blt.s .c0 | |
clr.w aktiv_window | |
.c0: | |
bsr update_win_header | |
rts | |
.sh: *Hit om shift+tab | |
move.w aktiv_window(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jmp (a0) | |
.tab: dc.l .memwin,.diswin | |
.memwin: | |
lea memwin_ptrtab(pc),a0 | |
move.w memwin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l memwin_ptr(pc),(a0,d0.w) | |
addq.w #1,memwin_typ | |
cmp.w #4,memwin_typ | |
blt.s .c1 | |
clr.w memwin_typ | |
.c1: | |
move.w memwin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l (a0,d0.w),memwin_ptr | |
bsr update_win_header | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
.diswin: | |
lea diswin_ptrtab(pc),a0 | |
move.w diswin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l diswin_ptr(pc),(a0,d0.w) | |
addq.w #1,diswin_typ | |
cmp.w #2,diswin_typ | |
blt.s .c2 | |
clr.w diswin_typ | |
.c2: | |
move.w diswin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l (a0,d0.w),diswin_ptr | |
bsr update_win_header | |
bsr get_diswin_data | |
bsr update_dis_window | |
moveq #0,d0 | |
rts | |
memwin_ptrtab: dc.l $100,$200,$300,$400 | |
diswin_ptrtab: dc.l 0,$100 | |
**************************************************** | |
*Trace a single command on Sega | |
sega_go: | |
tst.w diswin_typ | |
bne.s .xx | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #1,d0 | |
bsr send_byte | |
sf monitor_flag | |
moveq #17,d0 | |
bsr print_msg | |
.xx: moveq #0,d0 | |
rts | |
**************************************************** | |
*Ta bort breakpoint i Megadriven | |
*a0=adr of breakpoint to remove | |
remove_breakpoint: | |
move.l a0,a3 | |
lea breakptr_table(pc),a1 | |
move.l a1,a2 | |
moveq #max_breakptr-1,d7 | |
.lop: cmp.l 4(a1),a0 | |
beq.s .f0 | |
addq.w #8,a1 | |
dbra d7,.lop | |
bra.s .x | |
.f0: clr.l (a1) | |
clr.l 4(a1) | |
move.l a1,d3 | |
sub.l a2,d3 | |
lsr.w #3,d3 | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #10,d0 | |
bsr send_byte | |
move.w d3,d0 | |
bsr send_byte | |
.x: moveq #0,d0 | |
rts | |
**************************************************** | |
*a0=adr in SEGA to breakpoint | |
*d0=breakpoint typ | |
*0:ingen breakpoint | |
*1:permanent breakpoint | |
*2:break once breakpoint | |
*returns: d0> 0 breakpoint nr in table | |
* d0=-1 om f”r m†nga breakpoints | |
*add a breakpoint to the list and set it | |
add_break: | |
move.l a0,a3 *adr | |
move.w d0,d4 *typ | |
lea breakptr_table(pc),a0 | |
move.l a0,a1 | |
moveq #max_breakptr-1,d7 | |
.lop: tst.w (a0) | |
beq.s .c0 | |
addq.w #8,a0 | |
dbra d7,.lop | |
bra.s .er | |
.c0: *Add breakpoint in table | |
move.l a0,d3 | |
sub.l a1,d3 | |
lsr.w #3,d3 | |
move.w d4,(a0)+ | |
move.l a0,a4 | |
clr.w (a0)+ | |
move.l a3,(a0)+ | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #7,d0 | |
bsr send_byte | |
move.l a3,d2 *send breakpoint adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
move.w d3,d0 | |
bsr send_byte *send break nummer | |
move.w d4,d0 | |
bsr send_byte *send break typ | |
move.w d3,d0 | |
bsr recieve_byte1 | |
move.b d0,(a4)+ | |
bsr recieve_byte1 | |
move.b d0,(a4)+ | |
rts | |
.er: moveq #-1,d0 | |
rts | |
breakptr_table: *format 1w typ, 1w old data, 1L adress | |
ds.l max_breakptr*2 | |
**************************************************** | |
*skip current instruction | |
sega_skip: | |
tst.w diswin_typ | |
bne .xx | |
moveq #"S",d0 *Sega SRAM | |
bsr send_byte | |
moveq #2,d0 | |
bsr send_byte | |
move.l sega_pc(pc),a0 | |
lea temp(pc),a1 | |
moveq #12,d0 | |
bsr burst_recieve | |
.x: moveq #0,d0 | |
moveq #19,d0 | |
bsr print_msg | |
move.l #0,obj_start | |
move.l #0,base_page | |
move.l #temp,dis_adr | |
move.l #temp+12,dis_ptr | |
move.l a6,-(a7) | |
jsr dis | |
move.l (a7)+,a6 | |
sub.l #temp,a0 | |
move.l a0,d0 | |
add.l d0,sega_pc | |
moveq #"S",d0 *jump/set pc | |
bsr send_byte | |
moveq #6,d0 | |
bsr send_byte | |
move.l sega_pc(pc),d2 *send adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
bsr update_dis_window | |
bsr update_reg_window | |
.xx: moveq #0,d0 | |
rts | |
**************************************************** | |
*Trace a single command on Sega | |
sega_trace: | |
tst.w diswin_typ | |
bne.s .xx | |
tst.b trace_flag | |
beq.s .c0 | |
rts | |
.c0: moveq #"S",d0 | |
bsr send_byte | |
moveq #3,d0 | |
bsr send_byte | |
moveq #15,d0 | |
bsr print_msg | |
st trace_flag | |
.xx: moveq #0,d0 | |
rts | |
**************************************************** | |
*Updatera all f”nstren | |
update_display: | |
lea window_tab,a0 | |
bsr draw_all_windows | |
bsr update_win_header | |
bsr update_reg_window | |
bsr update_mem_window | |
bsr update_dis_window | |
rts | |
**************************************************** | |
*Prints out the current name of window: | |
update_win_header: | |
move.w #54,cx | |
move.w #22,cy | |
st font_size | |
sf inv_flag | |
cmp.w #0,aktiv_window | |
bne.s .c0 | |
st inv_flag | |
.c0: | |
move.w memwin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab1(pc,d0.w),a0 | |
bsr print_line | |
sf inv_flag | |
move.w #1,cx | |
move.w #22,cy | |
cmp.w #1,aktiv_window | |
bne.s .c1 | |
st inv_flag | |
.c1: | |
move.w diswin_typ(pc),d0 | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab1(pc,d0.w),a0 | |
bsr print_line | |
sf inv_flag | |
sf font_size | |
rts | |
.tab1: dc.l .a,.bb,.c,.d | |
.tab2: dc.l .e,.f,.g | |
.a: dc.b "Memory SEGA",0 | |
.bb: dc.b "Memory ST ",0 | |
.c: dc.b "Memory Z80 ",0 | |
.d: dc.b "Memory VRAM",0 | |
.e: dc.b "Dissasembly ST ",0 | |
.f: dc.b "Dissasembly SEGA",0 | |
.g: dc.b "Dissasembly Z80 ",0 | |
even | |
**************************************************** | |
get_key: | |
move.w #7,-(a7) | |
trap #1 | |
addq.w #2,a7 | |
move.l d0,last_key | |
move #-1,-(a7) | |
move #11,-(a7) | |
trap #13 | |
addq.l #4,a7 | |
move.b d0,shift_flag | |
move.l last_key(pc),d0 | |
rts | |
**************************************************** | |
*Input a line | |
*returns d0=0 om ok, d0=1 om no line entered | |
*a0=adr of dest buffer | |
*d0=max size of buffer | |
input_line: | |
move.l a0,a5 | |
move.w d0,d6 | |
*Clear input line | |
move.l phys(pc),a0 | |
add.w cx(pc),a0 | |
move.w cy,d1 | |
mulu #80*16,d1 | |
add.w d1,a0 | |
moveq #0,d1 | |
.lop1: | |
temp1: set 0 | |
rept 16 | |
move.b d1,temp1(a0) | |
temp1: set temp1+80 | |
endr | |
addq.w #1,a0 | |
dbra d0,.lop1 | |
moveq #0,d7 *Xpos | |
.lop | |
tst.b lastkey_flag | |
beq.s .no | |
sf lastkey_flag | |
move.l last_key(pc),d0 | |
bra.s .c1 | |
.no: move.w #7,-(a7) | |
trap #1 | |
addq.w #2,a7 | |
.c1: | |
cmp. #$1b,d0 | |
beq .esc | |
swap d0 | |
cmp.w #$1c,d0 | |
beq.s .ret | |
cmp.w #$53,d0 *delete | |
beq.s .lop | |
cmp.w #$e,d0 | |
beq.s .backspace | |
swap d0 | |
cmp.w d6,d7 | |
bhs.s .lop | |
addq.w #1,d7 | |
move.b d0,char | |
move.b d0,(a5)+ | |
bsr print_char | |
move.b #" ",char | |
st inv_flag | |
bsr print_char | |
sf inv_flag | |
subq.w #1,cx | |
bra .lop | |
.backspace: | |
tst.w d7 | |
beq.s .lop | |
subq.w #1,d7 | |
subq.w #1,cx | |
st inv_flag | |
move.b #" ",char | |
bsr print_char | |
sf inv_flag | |
bsr print_char | |
clr.b -(a5) | |
subq.w #2,cx | |
bra .lop | |
.ret: | |
move.b #" ",char | |
bsr print_char | |
clr.b (a5) | |
tst.w d7 | |
beq.s .esc | |
moveq #0,d0 | |
rts | |
.esc: moveq #1,d0 | |
clr.b (a5) | |
rts | |
**************************************************** | |
*1 =no header | |
*-1=error | |
*0 =header crunched ok | |
check_sega: *Check for data from Sega | |
move.w $fb0000,d0 | |
btst #8,d0 | |
beq.s .no | |
bsr recieve_byte1 | |
cmp.b #"D",d0 | |
bne.s .er | |
bsr recieve_byte1 | |
and.w #$ff,d0 | |
cmp.w #20,d0 | |
bhs.s .er | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab2(pc,d0.w),a0 | |
jmp (a0) | |
.no: moveq #1,d0 | |
rts | |
.er: cmp.b #"S",d0 | |
beq.s .no | |
illegal | |
moveq #-1,d0 | |
illegal | |
.tab2: dc.l .er,.berr,.adrerr,.ill,.zero,.chk | |
dc.l .trapv,.priv,.linea,.linef,.allregs | |
dc.l .sega_axdata,.irq,.trace | |
.berr: moveq #4,d0 | |
bsr print_msg | |
bra .exit | |
.adrerr:moveq #5,d0 | |
bsr print_msg | |
bra .exit | |
.ill: moveq #6,d0 | |
st monitor_flag ********* | |
bsr print_msg | |
*Kolla om illegalen „r en breakpoint | |
lea breakptr_table(pc),a0 | |
moveq #max_breakptr-1,d0 | |
move.l sega_pc(pc),a1 | |
.la: cmp.l 4(a0),a1 | |
beq.s .f | |
addq.w #8,a0 | |
dbra d0,.la | |
bra .c0 | |
.f: cmp.w #2,(a0) | |
beq.s .brk2 | |
bra .c0 | |
.brk2: *1g†ngs breakpoint, „r utf”rd och ta d† bort den | |
clr.l (a0)+ | |
clr.l (a0) | |
.c0: bra .exit | |
.zero: moveq #7,d0 | |
bsr print_msg | |
bra .exit | |
.chk: moveq #8,d0 | |
bsr print_msg | |
bra .exit | |
.trapv: moveq #9,d0 | |
bsr print_msg | |
bra .exit | |
.priv: moveq #10,d0 | |
bsr print_msg | |
bra .exit | |
.linea: moveq #11,d0 | |
bsr print_msg | |
bra .exit | |
.linef: moveq #12,d0 | |
bsr print_msg | |
bra .exit | |
.irq: moveq #13,d0 | |
bsr print_msg | |
st monitor_flag | |
bra .exit | |
.trace: moveq #16,d0 | |
st monitor_flag | |
bsr print_msg | |
bra .exit | |
.allregs: | |
moveq #15,d3 | |
lea sega_regs(pc),a1 | |
.lop1: | |
rept 4 | |
bsr recieve_byte1 | |
move.b d0,(a1)+ | |
endr | |
dbra d3,.lop1 | |
lea sega_pc(pc),a2 | |
rept 4 | |
bsr recieve_byte1 | |
move.b d0,(a2)+ | |
endr | |
lea sega_sr(pc),a2 | |
rept 2 | |
bsr recieve_byte1 | |
move.b d0,(a2)+ | |
endr | |
bsr update_reg_window *Dis win scroll | |
move.l sega_pc(pc),d0 | |
cmp.l last_start(pc),d0 | |
blt.s .y | |
cmp.l last_slut(pc),d0 | |
bls.s .xx | |
.y: move.l d0,diswin_ptr | |
.xx: | |
bsr get_diswin_data | |
bsr update_dis_window | |
.exit: moveq #0,d0 | |
rts | |
*Recieve 12bytes f”r varje Ax register | |
.sega_axdata: | |
lea sega_axdata(pc),a1 | |
moveq #7,d3 | |
.sax1: | |
rept 12 | |
bsr recieve_byte1 | |
move.b d0,(a1)+ | |
endr | |
dbra d3,.sax1 | |
rts | |
even | |
************************************************** | |
*a0=start adr in SEGA | |
*d0=antal bytes to recieve | |
*a1=dest adr in ST | |
burst_recieve: | |
move.l d0,d4 | |
move.l a1,a3 | |
lea .temp(pc),a2 | |
move.l a0,(a2) | |
rept 4 | |
move.b (a2)+,d0 *send start adr in SEGA | |
bsr send_byte | |
endr | |
lea .temp(pc),a2 | |
move.l d4,(a2) | |
rept 4 | |
move.b (a2)+,d0 *send start adr in SEGA | |
bsr send_byte | |
endr | |
*Do the transfere | |
lea $fb0000,a4 | |
moveq #0,d3 | |
moveq #8,d6 | |
move.w #$200,d5 | |
tst.w 100(a6) *clear ack | |
.lop: | |
.no: btst d6,(a4) *wait for strobe set | |
beq.s .no | |
move.w (a4),d0 | |
add.b d0,d3 | |
move.b d0,(a3)+ | |
tst.w 100(a6,d5.w) *set ack | |
.no1: btst d6,(a4) *wait for strobe set | |
bne.s .no1 | |
move.w (a4),d0 | |
add.b d0,d3 | |
move.b d0,(a3)+ | |
tst.w 100(a6) *clear ack | |
subq.l #2,d4 | |
bpl.s .lop | |
bsr recieve_byte | |
cmp.w d3,d0 | |
beq.s .ok | |
moveq #-1,d0 | |
rts | |
.ok: moveq #0,d0 | |
rts | |
.temp: dc.l 0 | |
************************************************** | |
update_dis_window: | |
move.w cx,save_cx | |
move.w cy,save_cy | |
move.w #12,cy | |
move.l a6,-(A7) | |
lea disrowsize(pc),a3 | |
move.l diswin_ptr(pc),a4 | |
lea diswin_buf(pc),a5 | |
moveq #10,d6 | |
move.l a5,obj_start | |
.nxtrad: | |
lea .temp(pc),a0 | |
move.l #" ",8(a0) | |
move.l #" ",12(a0) | |
move.l #" ",16(a0) | |
move.l #" ",20(a0) | |
move.l #" ",24(a0) | |
move.l #" ",28(a0) | |
move.l #" ",32(a0) | |
move.l #" ",36(a0) | |
move.l #" ",40(a0) | |
clr.w 44(a0) | |
lea 8(a0),a6 | |
move.l a4,d0 *hex adress | |
bsr conv_tohex8 | |
move.l #" ",(a6)+ | |
cmp.l sega_pc(pc),a4 *Check for PC marker | |
bne.s .no | |
move.b #">",-1(a6) | |
.no: | |
*get 128 bytes | |
move.l a5,obj_start | |
move.l a4,base_page | |
move.l a5,dis_adr | |
move.l a6,dis_ptr | |
cmp.w #$4afc,(a5) | |
bne.s .nobr | |
lea breakptr_table(pc),a1 *if breakpoint replace 4afc with real data | |
move.l a1,a2 | |
moveq #max_breakptr-1,d7 | |
.lopd: cmp.l 4(a1),a4 | |
beq.s .f0 | |
addq.w #8,a1 | |
dbra d7,.lopd | |
bra.s .nobr | |
.f0: move.w 2(a1),(a5) | |
.nobr: | |
move.l a6,-(a7) | |
bsr dis | |
move.l (a7)+,a1 | |
move.l a0,a5 | |
move.l a0,d0 | |
sub.l dis_adr,d0 | |
add.w d0,a4 | |
move.l a4,(a3)+ | |
cmp.l #"dc $",(a1) | |
bne.s .c1 | |
cmp.l #"4AFC",4(A1) | |
beQ.s .fo | |
.c1: | |
lea breakptr_table(pc),a0 | |
moveq #max_breakptr-1,d0 | |
move.l base_page(pc),a2 | |
.lo: cmp.l 4(a0),a2 | |
beq.s .fo | |
addq.w #8,a0 | |
dbra d0,.lo | |
bra.s .c0 | |
.fo: | |
tst.w (a0) | |
beq.s .c0 | |
lea .temp(pc),a0 | |
move.l #"ILLE",(a1)+ | |
move.l #"GAL ",(a1)+ | |
move.l #" ",(a1)+ | |
move.l #" ",(a1)+ | |
move.l #" ",(a1)+ | |
move.l #" ",(a1)+ | |
move.l #" ",(a1)+ | |
move.l #" ",(a1)+ | |
move.l #" ",(a1)+ | |
clr.b (a1)+ | |
.c0: | |
move.w #1,cx | |
lea .temp(pc),a0 | |
bsr print_line | |
addq.w #1,cy | |
dbra d6,.nxtrad | |
.x: | |
move.l (a7)+,a6 | |
move.w save_cx,cx | |
move.w save_cy,cy | |
move.l -16(a3),last_slut | |
move.l disrowsize(pc),last_start | |
rts | |
.temp: ds.l 20 | |
disrowsize: ds.l 12 | |
last_start: dc.l 0 | |
last_slut: dc.l 0 | |
************************************************** | |
update_reg_window: | |
move.w cx,save_cx | |
move.w cy,save_cy | |
*Update all Dataregs | |
lea sega_regs(pc),a5 | |
lea ascii_convtab(pc),a4 | |
move.w #1,cy | |
moveq #7,d7 | |
moveq #"0",d6 | |
.dl0: | |
lea temp(pc),a0 | |
move.b #"D",(a0)+ | |
move.b d6,(a0)+ | |
addq.w #1,d6 | |
move.b #":",(a0)+ | |
move.l (a5),d0 | |
bsr conv_tohex8 | |
move.b #" ",(a0)+ | |
moveq #0,d0 | |
moveq #3,d1 | |
.lop move.b (a5)+,d0 | |
move.b (a4,d0.w),d0 | |
bne.s .c0 | |
move.b #".",d0 | |
.c0: move.b d0,(a0)+ | |
dbra d1,.lop | |
clr.b (a0)+ | |
lea temp(pc),a0 | |
move.w #1,cx | |
bsr print_line | |
addq.w #1,cy | |
dbra d7,.dl0 | |
*Update all Adress regs | |
move.w #1,cy | |
moveq #7,d7 | |
moveq #"0",d6 | |
.al0: | |
lea temp(pc),a0 | |
move.b #"A",(a0)+ | |
move.b d6,(a0)+ | |
addq.w #1,d6 | |
move.b #":",(a0)+ | |
move.l (a5)+,d0 | |
bsr conv_tohex8 | |
clr.b (a0)+ | |
lea temp(pc),a0 | |
move.w #19,cx | |
bsr print_line | |
addq.w #1,cy | |
dbra d7,.al0 | |
*Update SR | |
move.w #19,cx | |
move.w #9,cy | |
lea temp(pc),a0 | |
move.w #"SR",(a0)+ | |
move.b #":",(a0)+ | |
move.w sega_sr(pc),d0 | |
bsr conv_tohex4 | |
clr.b (a0) | |
lea temp(pc),a0 | |
bsr print_line | |
*Update PC counter | |
move.w #1,cx | |
move.w #9,cy | |
lea temp(pc),a0 | |
move.w #"PC",(a0)+ | |
move.b #":",(a0)+ | |
move.l sega_pc(pc),d0 | |
bsr conv_tohex8 | |
clr.b (a0) | |
lea temp(pc),a0 | |
bsr print_line | |
*Update AX data | |
lea sega_axdata(pc),a1 | |
lea hextab(pc),a2 | |
move.w #1,cy | |
moveq #7,d3 | |
.yl1: lea temp(pc),a0 | |
moveq #5,d2 | |
.xl1: | |
move.w (a1)+,d0 | |
rept 4 | |
rol.w #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a2,d1.w),(a0)+ | |
endr | |
move.b #" ",(a0)+ | |
dbra d2,.xl1 | |
move.w #40,cx | |
clr.b (a0) | |
lea temp(pc),a0 | |
bsr print_line | |
addq.w #1,cy | |
dbra d3,.yl1 | |
move.w save_cx,cx | |
move.w save_cy,cy | |
sf trace_flag | |
rts | |
************************************************ | |
update_mem_window: | |
move.w cx,save_cx | |
move.w cy,save_cy | |
move.l memwin_ptr(pc),d6 | |
lea memwin_buf(pc),a3 | |
lea hextab(pc),a4 | |
lea ascii_convtab(pc),a5 | |
btst #0,d6 | |
seq d5 | |
move.w #12,cy | |
moveq #10,d7 | |
.ylop: | |
lea temp(pc),a0 *adress | |
move.l d6,d0 | |
bsr conv_tohex8 | |
move.b #" ",(a0)+ | |
move.w (a3),d0 *hex output | |
rept 2 | |
rol.w #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a4,d1.w),(a0)+ | |
endr | |
tst.b d5 | |
bne.s .no1 | |
move.b #" ",(a0)+ | |
.no1: | |
rept 2 | |
rol.w #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a4,d1.w),(a0)+ | |
endr | |
tst.b d5 | |
beq.s .no2 | |
move.b #" ",(a0)+ | |
.no2: | |
move.w 2(a3),d0 | |
rept 2 | |
rol.w #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a4,d1.w),(a0)+ | |
endr | |
tst.b d5 | |
bne.s .no3 | |
move.b #" ",(a0)+ | |
.no3: | |
rept 2 | |
rol.w #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a4,d1.w),(a0)+ | |
endr | |
tst.b d5 | |
beq.s .no4 | |
move.b #" ",(a0)+ | |
.no4: | |
move.b #" ",(a0)+ | |
moveq #0,d0 | |
moveq #3,d1 | |
.l1: move.b (a3)+,d0 | |
move.b (a5,d0.w),d0 | |
bne.s .c0 | |
move.b #".",d0 | |
.c0: move.b d0,(a0)+ | |
dbra d1,.l1 | |
clr.b (a0) | |
lea temp(pc),a0 | |
move.w #54,cx | |
bsr print_line | |
addq.w #1,cy | |
addq.l #4,d6 | |
dbra d7,.ylop | |
move.w save_cx,cx | |
move.w save_cy,cy | |
rts | |
************************************************ | |
*Convert D0 to hex at A0 | |
conv_tohex8: | |
moveq #7,d2 | |
lea hextab(pc),a1 | |
.lop | |
rol.l #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a1,d1),(a0)+ | |
dbra d2,.lop | |
rts | |
******************************************** | |
*Convert D0 to hex at A0 | |
conv_tohex4: | |
moveq #3,d2 | |
lea hextab(pc),a1 | |
.lop | |
rol.w #4,d0 | |
moveq #15,d1 | |
and.w d0,d1 | |
move.b (a1,d1),(a0)+ | |
dbra d2,.lop | |
rts | |
******************************************** | |
*A0=pointer to window def table | |
draw_all_windows: | |
.l0: tst.w (a0) | |
bmi.s .x | |
move.l a0,-(a7) | |
bsr draw_window | |
move.l (a7)+,a0 | |
addq.w #8,a0 | |
bra .l0 | |
.x: rts | |
******************************************** | |
*a0=pointer to window datas | |
draw_window: | |
move.l phys,a1 | |
add.w (a0)+,a1 | |
move.w (a0)+,d4 | |
mulu #80*16,d4 | |
add.w d4,a1 | |
*Draw top border corners | |
move.w (a0),d0 | |
move.l a1,a2 | |
move.l a2,a3 | |
add.w (a0),a3 | |
moveq #16,d3 | |
moveq #0,d4 | |
t: set 0 | |
rept 10 | |
move.b d4,t(a2) | |
move.b d4,t(a3) | |
t: set t+80 | |
endr | |
move.b #31,t(a2) | |
move.b #$f8,t(a3) | |
t: set t+80 | |
rept 5 | |
move.b d3,t(a2) | |
move.b #8,t(a3) | |
t: set t+80 | |
endr | |
move.w (a0),d1 | |
subq.w #2,d1 | |
move.l a1,a2 | |
addq.w #1,a2 | |
move.l a2,a3 | |
move.w 2(a0),d0 | |
addq.w #2,d0 | |
mulu #16*80,d0 | |
add.w d0,a3 | |
moveq #0,d3 | |
.xlop1: | |
t: set 0 | |
rept 10 | |
move.b d3,t(a2) | |
t: set t+80 | |
endr | |
move.b #-1,t(a2) | |
t: set t+80 | |
rept 3 | |
move.b d3,t(a2) | |
t: set t+80 | |
endr | |
t: set 0 | |
rept 7 | |
move.b d3,t(a3) | |
t: set t+80 | |
endr | |
move.b #-1,t(a3) | |
t: set t+80 | |
rept 5 | |
move.b d3,t(a3) | |
t: set t+80 | |
endr | |
addq.w #1,a2 | |
addq.w #1,a3 | |
dbra d1,.xlop1 | |
*Draw mellan dellen | |
add.w #80*16,a1 | |
move.w 2(a0),d1 | |
.ylop: move.w (a0),d0 | |
subq.w #2,d0 | |
move.l a1,a2 | |
*Draw mellan delen | |
move.b #16,d3 | |
t: set 0 | |
rept 16 | |
move.b d3,t(a2) | |
t: set t+80 | |
endr | |
addq.w #1,a2 | |
moveq #0,d3 | |
.xlop: | |
t: set 0 | |
rept 16 | |
move.b d3,t(a2) | |
t: set t+80 | |
endr | |
addq.w #1,a2 | |
dbra d0,.xlop | |
move.b #8,d3 | |
t: set 0 | |
rept 16 | |
move.b d3,t(a2) | |
t: set t+80 | |
endr | |
add.w #80*16,a1 | |
dbra d1,.ylop | |
*Draw bottom corners | |
move.w (a0),d0 | |
move.l a1,a2 | |
move.l a2,a3 | |
add.w (a0),a3 | |
move.b #16,d3 | |
moveq #0,d4 | |
t: set 0 | |
rept 7 | |
move.b d3,t(a2) | |
move.b #8,t(a3) | |
t: set t+80 | |
endr | |
move.b #31,t(a2) | |
move.b #$f8,t(a3) | |
t: set t+80 | |
rept 8 | |
move.b d4,t(a2) | |
move.b d4,t(a3) | |
t: set t+80 | |
endr | |
rts | |
******************************************** | |
init_display: | |
move.w #11,cy | |
move.w #0,cx | |
dc.w $a00a | |
lea ymultab(pc),a0 | |
moveq #0,d1 | |
moveq #49,d0 | |
.lop: move.w d1,(a0)+ | |
add.w #80*8,d1 | |
dbra d0,.lop | |
move.w #2,-(a7) | |
trap #14 | |
addq.l #2,a7 | |
move.l d0,phys | |
*make inverse font | |
lea font(pc),a0 | |
lea font_inv(pc),a1 | |
move.w #2047,d1 | |
.lop1 move.b (a0)+,d0 | |
not.b d0 | |
move.b d0,(a1)+ | |
dbra d1,.lop1 | |
pea .cls | |
move.w #9,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
rts | |
.cls: dc.b 27,"E",27,"Y",42,43,13,10,0 | |
even | |
**************************************** | |
print_line: *a0=adr of line | |
*a1=font | |
*a3=ymultab | |
movem.l d0-d2/a0-a4,-(a7) | |
tst.b update_cyflag | |
bne.s .ok2 | |
move.w cy,d0 | |
cmp.w max_y(pc),d0 | |
bls.s .ok2 | |
move.w max_y(pc),cy | |
.ok2: | |
lea font(pc),a1 | |
lea ymultab(pc),a3 | |
tst.b inv_flag | |
beq.s .recalc | |
lea font_inv(pc),a1 | |
.recalc: | |
move.l phys(pc),a2 | |
add.w cx(pc),a2 *add | |
move.w cy(pc),d1 | |
add.w d1,d1 *add y | |
tst.b font_size | |
bmi.s .c0 | |
add.w d1,d1 * | |
.c0: add.w (a3,d1.w),a2 | |
.lop: | |
moveq #0,d2 | |
move.b (a0)+,d2 | |
beq .klar | |
cmp.b #13,d2 | |
beq .return | |
cmp.b #10,d2 | |
beq .line_feed | |
lsl.w #3,d2 *font | |
lea (a1,d2.w),a4 | |
tst.b font_size | |
bmi.s .size48 | |
temp1: set 0 | |
rept 8 | |
move.b (A4),temp1(a2) | |
move.b (a4)+,80+temp1(a2) | |
temp1: set temp1+160 | |
endr | |
addq.w #1,a2 | |
bra.s .lop | |
.size48 | |
move.b (A4)+,(a2) | |
move.b (A4)+,80(a2) | |
move.b (A4)+,160(a2) | |
move.b (A4)+,240(a2) | |
move.b (A4)+,320(a2) | |
move.b (A4)+,400(a2) | |
move.b (A4)+,480(a2) | |
move.b (A4)+,560(a2) | |
addq.w #1,a2 | |
bra .lop | |
.klar: | |
movem.l (A7)+,d0-d2/a0-a4 | |
rts | |
.return: | |
clr.w cx | |
bra .recalc | |
.line_feed: | |
addq.w #1,cy | |
bra .recalc | |
**************************************** | |
print_char: *char=tecken, output=80*24 | |
*inv=0 om normal text, inv=-1 om inverse text | |
*Font_size: 0=80*24, -1=80*48 | |
movem.l d0-d2/a0-a3,-(a7) | |
lea font(pc),a1 | |
tst.b inv_flag | |
beq.s .c0 | |
lea font_inv(pc),a1 | |
.c0: | |
tst.b update_cyflag | |
bne.s .ok2 | |
move.w cy,d0 | |
cmp.w max_y(pc),d0 | |
bls.s .ok2 | |
move.w max_y(pc),cy | |
* bsr scroll_screen_up80x24 | |
.ok2: | |
moveq #0,d2 | |
move.b char(pc),d2 | |
cmp.b #13,d2 | |
beq .return | |
cmp.b #10,d2 | |
beq .line_feed | |
move.w cx(pc),d0 | |
move.w cy(pc),d1 | |
move.l phys(pc),a0 | |
add.w d0,a0 *add | |
add.w d1,d1 *add y | |
add.w d1,d1 * | |
lea ymultab(pc),a3 | |
add.w (a3,d1.w),a0 | |
lsl.w #3,d2 *font | |
add.w d2,a1 | |
tst.b font_size | |
bmi.s .size48 | |
temp1: set 0 | |
rept 8 | |
move.b (A1),temp1(a0) | |
move.b (a1)+,80+temp1(a0) | |
temp1: set temp1+160 | |
endr | |
bra .x | |
;--------------------- | |
.size48: | |
move.b (A1)+,(a0) | |
move.b (A1)+,80(a0) | |
move.b (A1)+,160(a0) | |
move.b (A1)+,240(a0) | |
move.b (A1)+,320(a0) | |
move.b (A1)+,400(a0) | |
move.b (A1)+,480(a0) | |
move.b (A1)+,560(a0) | |
;--------------------- | |
.x: | |
addq.w #1,cx | |
tst.b update_cyflag | |
bne.s .ok | |
move.w cx,d0 | |
cmp.w max_x,d0 | |
bls.s .ok | |
clr.w cx | |
moveq #0,d0 | |
addq.w #1,cy | |
.ok: | |
movem.l (a7)+,d0-d2/a0-a3 | |
rts | |
.return: | |
clr.w cx | |
movem.l (a7)+,d0-d2/a0-a3 | |
rts | |
.line_feed: | |
addq.w #1,cy | |
movem.l (a7)+,d0-d2/a0-a3 | |
rts | |
;******************************************* | |
ymultab: ds.w 50 | |
phys: dc.l 0 | |
cx: dc.w 0 | |
cy: dc.w 0 | |
font_size: dc.b 0 | |
update_cyflag: dc.b 0 *flagga om print_char rutinen skall updatera cy | |
char: dc.b 0 | |
inv_flag: dc.b 0 *inverse text flagga | |
even | |
max_y: dc.w 24 *antal rader p† sk„rmen | |
max_x: dc.w 79 *antal columner | |
tom: ds.l 40 | |
font: incbin d:\genst\font.b | |
font_inv: ds.l 512 | |
ascii_convtab: | |
.a dc.b 0 | |
ds.b 31 | |
dc.b " !",-1,"#$%&",-1,"()*+,-./" | |
dc.b "0123456789:",0,0,0,0,0,0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]",0,"_",0 | |
dc.b "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
dc.b 0,0,0,"~",0,0,0,0,0,"Ž",0,"",0,0,0,0,0,0,0,"Ž",0,0,0,0,"™",0,0,0,0,"™" | |
.q: ds.b (.a+256)-.q | |
even | |
monitor_flag: dc.b 0 *0=sega running, -1=Segabug running | |
lastkey_flag: dc.b 0 | |
sega_axdata: ds.b 8*14 *12bytes som varje AX register pekar p† i Segan | |
shift_flag: dc.b 0 | |
trace_flag: dc.b 0 | |
even | |
memwin_typ: dc.w 0 | |
*0=view SEGA | |
*1=view ST | |
*2=view Z80 | |
*3=view VRAM | |
dc.b "Memory SEGA",0 | |
dc.b "Memory ST ",0 | |
dc.b "Memory Z80 ",0 | |
dc.b "Memory VRAM",0 | |
dc.b "Dissasembly ST ",0 | |
dc.b "Dissasembly SEGA",0 | |
dc.b "Dissasembly Z80 ",0 | |
diswin_typ: dc.w 0 | |
*0=dis SEGA | |
*1=dis ST | |
*2=dis Z80 | |
aktiv_window: dc.w 0 | |
*0=memwin | |
*1=diswin | |
sega_sr: dc.w 0 | |
save_cx: dc.w 0 | |
save_cy: dc.w 0 | |
last_key: dc.l 0 | |
sega_pc: dc.l 0 | |
memwin_ptr: dc.l 0 | |
diswin_ptr: dc.l 0 | |
sega_regs: ds.l 20 | |
memwin_buf: | |
ds.b 50 | |
diswin_buf: | |
ds.b 50 | |
window_tab: | |
dc.w 0,0 *start x,y | |
dc.w 79,8 *width, height | |
dc.w 53,11 *mem | |
dc.w 25,10 | |
dc.w 0,11 *dis | |
dc.w 52,10 | |
dc.l -1,-1 | |
even | |
**************************************************** | |
lop: | |
bsr get_command | |
bsr process_command | |
bra lop | |
basepage: ds.l 1 | |
*read | |
ram: dc.w 5 *9 for Vram | |
*5 for cartridge/Sram | |
*11 REad z80 | |
*Write | |
ram2: dc.w 6 *6 for cart/sram mem | |
*10 For Vram | |
**************************************** | |
process_command: | |
lea rad(pc),a0 | |
move.b (a0)+,d0 | |
bne.s .noret | |
move.b last_command(pc),d0 | |
.noret: | |
and.w #255-32,d0 | |
move.b d0,last_command | |
cmp.w #"Z",d0 | |
bhi.s .x | |
sub.w #"A",d0 | |
bmi.s .x | |
add.w d0,d0 | |
add.w d0,d0 | |
lea .bratab(pc,d0.w),a0 | |
jmp (a0) | |
.x: rts | |
.bratab: | |
bra alive a show alive | |
bra set_breakpoint b set break point | |
bra .x c | |
bra diswin_set **disssasm window set / DIR | |
bra .x e | |
bra .fill f | |
bra .go g Boot cartgame | |
bra .x h | |
bra .x i | |
bra .setpc j **Set PC | |
bra .x k | |
bra load l **Load binary game from disk | |
bra memwin_set m **set memwin baseadress | |
bra .x n | |
bra .x o | |
bra project p *Load and exec project phile | |
bra quit q **Quit debugger | |
bra reset_sega r Reset megadrive | |
bra .x s | |
bra burst t Transfere game to Segamemory | |
bra .x u | |
bra .x v | |
bra .x w | |
bra .x x | |
bra .x y | |
bra memsize z | |
.go: moveq #3,d0 | |
bsr send_byte | |
rts | |
.setpc: | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #6,d0 | |
bsr send_byte | |
lea rad+1(pc),a0 | |
bsr get_hexval | |
move.l d0,d2 | |
* move.l a0,d2 *send dest adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
bsr update_reg_window | |
rts | |
.fill: | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #5,d0 | |
bsr send_byte | |
lea rad+1(pc),a0 | |
bsr get_hexval | |
bsr send_byte | |
bsr recieve_byte | |
tst.b d0 | |
beq.s .ok | |
moveq #18,d0 | |
bsr print_msg | |
rept 4 | |
bsr recieve_byte *get adress that made error | |
move.b d0,d2 | |
ror.l #8,d2 | |
endr | |
move.l d2,d0 | |
bsr write_hex8 | |
bsr print_space | |
bsr print_space | |
bsr recieve_byte *get adress that made error | |
bsr write_hex2 | |
bsr print_space | |
bsr print_space | |
bsr recieve_byte *get adress that made error | |
bsr write_hex2 | |
rts | |
.ok: moveq #0,d0 | |
bsr print_msg | |
rts | |
************************************************ | |
memsize: | |
illegal | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #11,d0 | |
bsr send_byte | |
rept 4 | |
rol.l #8,d2 | |
bsr recieve_byte *get adress that made error | |
move.b d0,d2 | |
endr | |
moveq #0,d0 | |
rts | |
************************************************ | |
*load and execute project batch file | |
project: | |
move.l #dir_table,dir_pointer | |
clr.l proj_pc | |
lea rad+1(pc),a0 | |
.l1: cmp.b #" ",(a0) | |
bne.s .c0 | |
addq.w #1,a0 | |
bra.s .l1 | |
.c0: | |
lea proj_buf(pc),a1 | |
bsr load_file | |
tst.w d0 | |
beq.s .c1 | |
moveq #22,d0 | |
bsr print_msg | |
bra.s .no | |
.c1: | |
lea proj_buf(pc),a0 | |
bsr decode_phile | |
.no: moveq #0,d0 | |
rts | |
proj_pc: dc.l 0 | |
dir_pointer: dc.l 0 | |
file_size: dc.l 0 | |
file_crc: dc.w 0 | |
filename_start: dc.l 0 | |
dir_table: ds.l 32*22 | |
*format: | |
*12b Filename.ext | |
*4b start adr in Sega | |
*4b Phile size in Sega | |
*2b CRC vaule of phile *22bytes | |
even | |
proj_buf: ds.l 1024 | |
************************************************ | |
set_drive: | |
*d0=drive nummer | |
*returns drivemap | |
move.w d0,-(a7) | |
move.w #$e,-(a7) | |
trap #1 | |
addq.l #4,a7 | |
rts | |
change_path:*a0=path | |
move.l a0,-(a7) | |
move.w #$3b,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
rts | |
*************************************************** | |
*Execute the commands in the project phile | |
*a0=adr of ascii project phile | |
decode_phile: | |
_next1: | |
move.b (a0),d0 | |
beq .ok | |
cmp.b #"#",d0 | |
beq _comment | |
cmp.b #"$",d0 | |
beq _org | |
cmp.b #":",1(a0) | |
beq _path | |
cmp.b #"\",(a0) | |
beq _path | |
move.l a0,a1 | |
.lp2 cmp.b #10,(a1)+ | |
bne.s .lp2 | |
clr.b -2(a1) | |
move.l a1,-(a7) | |
move.l spel(pc),a1 | |
;-------------------------- | |
bsr load_file *load phile into buffer | |
tst.w d0 | |
beq.s .c1 | |
moveq #21,d0 | |
bsr print_msg | |
bra.s .no | |
.c1: | |
bsr make_crc *Get Checksum on current phile | |
bsr add_to_dir *add data to dir table | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #4,d0 | |
bsr send_byte | |
move.l proj_pc(pc),a0 | |
move.l spel(pc),a1 | |
move.l file_size(pc),d0 | |
subq.l #1,d0 | |
bsr burst_send *transfere file into Sega | |
move.l proj_pc(pc),d0 | |
add.l file_size(pc),d0 | |
btst #0,d0 | |
beq.s .c0 *word align | |
addq.l #1,d0 | |
.c0: move.l d0,proj_pc | |
.no: | |
;-------------------------- | |
move.l (a7)+,a0 | |
bra _next1 | |
.ok: moveq #0,d0 | |
rts | |
_comment: | |
.lp1 cmp.b #10,(a0)+ | |
bne.s .lp1 | |
bra _next1 | |
_org: | |
addq.w #1,a0 *skip $ | |
move.l a0,a1 | |
.lp2 cmp.b #10,(a1)+ | |
bne.s .lp2 | |
clr.b -2(a1) | |
move.l a1,-(a7) | |
bsr get_hexval | |
move.l (a7)+,a0 | |
move.l d0,proj_pc | |
bra _next1 | |
_path: | |
cmp.b #":",1(a0) | |
bne.s .nodr | |
move.b (a0),d0 | |
and.w #223,d0 | |
sub.b #"A",d0 | |
addq.w #2,a0 | |
move.l a0,a4 | |
bsr set_drive | |
tst.w d0 | |
bmi.s .er | |
move.l a4,a0 | |
.nodr: cmp.b #"\",(a0) | |
bne.s .nopath | |
move.l a0,a1 | |
.lp2 cmp.b #10,(a1)+ | |
bne.s .lp2 | |
clr.b -2(a1) | |
move.l a1,-(a7) | |
bsr change_path | |
tst.w d0 | |
bmi.s .er | |
move.l (a7)+,a0 | |
bra _next1 | |
.nopath: | |
.lp3 cmp.b #10,(a0)+ | |
bne.s .lp3 | |
bra _next1 | |
.er: moveq #-1,d0 | |
rts | |
.ok: moveq #0,d0 | |
rts | |
*************************************************** | |
*Add current phile parameter to the dir pointer table | |
add_to_dir: | |
move.l dir_pointer(pc),a0 | |
lea 12(a0),a2 | |
move.l filename_start(pc),a1 | |
move.l #" ",(a0) | |
move.l #" ",4(a0) | |
move.l #" ",8(a0) | |
*copy phile name | |
.lop1: move.b (a1)+,d0 | |
beq.s .x1 | |
cmp.b #".",d0 | |
beq.s .c0 | |
and.b #223,d0 | |
.c0: move.b d0,(a0)+ | |
bra.s .lop1 | |
.x1: | |
move.l proj_pc(pc),(a2)+ | |
move.l file_size(pc),(a2)+ | |
move.w file_crc(pc),(a2) | |
add.l #22,dir_pointer | |
rts | |
*************************************************** | |
make_crc: | |
move.l buf(pc),a0 | |
move.l file_size(pc),d0 | |
subq.l #1,d0 | |
moveq #0,d1 | |
moveq #0,d2 | |
.la: move.b (a0)+,d2 | |
add.w d2,d1 | |
subq.l #1,d0 | |
tst.l d0 | |
bpl.s .la | |
move.w d1,file_crc | |
rts | |
************************************************ | |
*Load phile into memory | |
*a0=adr of philename | |
*a1=dest adress to load | |
*return d0=0 if ok, d0=-1 error | |
load_file: | |
move.l a0,filename_start | |
move.l a1,a4 | |
clr.w -(a7) | |
move.l a0,-(a7) | |
move.w #$3d,-(a7) *open | |
trap #1 | |
addq.w #8,a7 | |
tst.w d0 | |
bmi.s .er | |
move.w d0,d7 | |
move.l a4,-(a7) | |
move.l #1024*256,-(a7) | |
move.w d0,-(a7) | |
move.w #$3f,-(a7) | |
trap #1 | |
add.w #12,a7 | |
tst.l d0 | |
bmi.s .er | |
beq.s .er | |
move.l d0,file_size | |
move.w d7,-(a7) | |
move.w #$3e,-(a7) | |
trap #1 | |
addq.w #4,a7 | |
tst.w d0 | |
bmi.s .er | |
moveq #0,d0 | |
rts | |
.er: moveq #-1,d0 | |
rts | |
************************************************ | |
*a0=adr in SEGA to breakpoint | |
*d0=breakpoint number | |
*d1=breakpoint typ | |
*0:ingen breakpoint | |
*1:permanent breakpoint | |
*2:break once breakpoint | |
set_breakpoint: | |
lea rad(pc),a0 | |
move.b 1(a0),d0 | |
and.w #255-32,d0 | |
cmp.b #"S",d0 | |
beq.s .set | |
cmp.b #"R",d0 | |
beq.s .remove | |
moveq #0,d0 | |
rts | |
.set: | |
lea rad+2(pc),a0 | |
bsr get_hexval | |
tst.l d0 | |
beq.s .x | |
move.l d0,a0 | |
moveq #1,d0 | |
bsr add_break | |
tst.w d0 | |
bmi.s .er | |
.x: | |
bsr get_diswin_data | |
bsr update_dis_window | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
.remove: | |
lea rad+2(pc),a0 | |
bsr get_hexval | |
tst.l d0 | |
beq.s .x1 | |
move.l d0,a0 | |
bsr remove_breakpoint | |
.x1: | |
bsr get_diswin_data | |
bsr update_dis_window | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
rts | |
.er: illegal | |
************************************************ | |
*Set the baseadress for the Memwindow | |
memwin_set: | |
lea rad+1(pc),a0 | |
bsr get_hexval | |
tst.l d1 | |
bne.s .x | |
move.l d0,memwin_ptr | |
.no1: | |
bsr get_memwin_data | |
bsr update_mem_window | |
moveq #0,d0 | |
.x: rts | |
************************************************ | |
*Set the baseadress for the Dis window | |
*Also dir | |
diswin_set: | |
move.b rad+1(pc),d0 | |
lsl.w #8,d0 | |
move.b rad+2(pc),d0 | |
and.w #$9393,d0 | |
cmp.w #"IR",d0 | |
beq.s .dir | |
lea rad+1(pc),a0 | |
bsr get_hexval | |
tst.l d1 | |
bne.s .x | |
move.l d0,diswin_ptr | |
.no1: | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #2,d0 | |
bsr send_byte | |
lea diswin_buf(pc),a1 | |
move.l diswin_ptr(pc),a0 | |
moveq #48,d0 | |
bsr burst_recieve | |
bsr update_dis_window | |
moveq #0,d0 | |
.x: rts | |
*--------------------------------------- | |
.dir: | |
illegal | |
lea rad+2(pc),a0 | |
moveq #0,d0 | |
moveq #0,d1 | |
.l0 move.b (a0)+,d0 | |
beq.s .xx | |
cmp.w #$21,d0 | |
blt.s .l0 | |
.xx: moveq #0,d0 | |
rts | |
************************************************ | |
quit: moveq #-1,d0 | |
rts | |
************************************************ | |
load: | |
moveq #0,d1 | |
lea rad+1(pc),a0 | |
.l0 move.b (a0),d0 | |
beq.s .ut | |
move.b (a0)+,d0 | |
cmp.b #" ",d0 *space? | |
bne.s .ut | |
move #0,-(a7) | |
move.l a0,-(a7) | |
move #$3d,-(a7) | |
trap #1 | |
addq.l #8,a7 | |
tst.l d0 | |
bmi .err | |
move d0,d7 | |
move.l spel,-(a7) | |
move.l #512*1024,-(a7) | |
move d7,-(a7) | |
move #$3f,-(a7) | |
trap #1 | |
lea 12(a7),a7 | |
tst.l d0 | |
bmi .err | |
move d7,-(a7) close | |
move #$3e,-(a7) | |
trap #1 | |
addq.l #4,a7 | |
tst.w d0 | |
bne .err | |
.ut: moveq #0,d0 | |
bsr print_msg | |
rts | |
.err: moveq #1,d0 | |
bsr print_msg | |
moveq #0,d0 | |
rts | |
************************************************ | |
burst: | |
moveq #"S",d0 | |
bsr send_byte | |
moveq #4,d0 | |
bsr send_byte | |
lea $00,A0 | |
move.l spel,A1 | |
add.w #$00,a1 | |
move.l end_spel,d0 | |
sub.l a1,d0 | |
BSR burst_send | |
tst.w d0 | |
bne.s .er | |
moveq #0,d0 | |
bsr print_msg | |
moveq #0,d0 | |
rts | |
.er: moveq #2,d0 | |
bsr print_msg | |
moveq #0,d0 | |
rts | |
************************************************ | |
trans: | |
lea $0,A0 | |
move.l spel,A1 | |
move.l end_spel,d0 | |
sub.l spel,d0 | |
BSR poke_block | |
tst.w d0 | |
bne.s .er | |
moveq #0,d0 | |
bsr print_msg | |
rts | |
.er: moveq #2,d0 | |
bsr print_msg | |
rts | |
reset_sega: | |
bsr reset_megadrive | |
bsr boot_sega | |
rts | |
***************************************************** | |
print_msg: | |
move.w #0,cx | |
move.w #24,cy | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .msgtab(pc,d0.w),a0 | |
bsr print_line | |
rts | |
.msgtab:dc.l .m0,.m1,.m2,.m3,.m4,.m5,.m6,.m7,.m8,.m9,.ma,.mb,.mc,.md,.me,.mf,.mg,.mh,.mj,.mk,.ml,.mm,.mn | |
.m0: dc.b "OK ",0 | |
.m1: dc.b "Error while reading file...",0 | |
.m2: dc.b "Transfere error... ",0 | |
.m3: dc.b "SEGA reseted... ",0 | |
.m4: dc.b "*** Buss Error ",0 | |
.m5: dc.b "*** Adress Error ",0 | |
.m6: dc.b "*** Breakpoint reached ",0 | |
.m7: dc.b "*** Division by Zero ",0 | |
.m8: dc.b "*** CHK Exception ",0 | |
.m9: dc.b "*** Trapv Exception ",0 | |
.ma: dc.b "*** Priviedge Violation ",0 | |
.mb: dc.b "*** Line-A ",0 | |
.mc: dc.b "*** Line-F ",0 | |
.md: dc.b "*** Extern Sega IRQ ",0 | |
.me: dc.b "Problem while reseting ....",0 | |
.mf: dc.b "Trace instruction ",0 | |
.mg: dc.b "Trace exception ",0 | |
.mh: dc.b "Sega GO ",0 | |
.mj: dc.b "Fill error... ",0 | |
.mk: dc.b "Skip instruction ",0 | |
.ml: dc.b "Trace2 ",0 | |
.mm: dc.b "binary file not found... ",0 *21 | |
.mn: dc.b "Project file not found... ",0 *22 | |
even | |
***************************************************** | |
alive: | |
moveq #1,d0 | |
bsr send_byte | |
lea temp(pc),a0 | |
.lop: bsr recieve_byte | |
move.b d0,(a0)+ | |
bne.s .lop | |
clr.b (a0)+ | |
pea temp | |
move.w #9,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
rts | |
***************************************************** | |
*Poke a block of data from Sega to ST | |
*a0=start adress in Sega to write to | |
*a1=start adress in ST to read from | |
*d0=antal bytes to Transfere, must be even number -1 | |
*returns d0=0 om ok, d0=-1 om error | |
poke_block: | |
move.l $4ba,d5 | |
movem.l d2-d5,-(a7) | |
move.l d0,d3 | |
move.l d0,d4 | |
move.w ram2,d0 | |
bsr send_byte | |
move.l a0,d2 *send dest adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
rept 4 *send length of block | |
move.b d3,d0 | |
lsr.l #8,d3 | |
bsr send_byte | |
endr | |
moveq #0,d3 | |
.lop: | |
move.b (a1)+,d0 | |
add.b d0,d3 | |
bsr send_byte | |
subq.l #1,d4 | |
move.b (a1)+,d0 | |
add.b d0,d3 | |
bsr send_byte | |
subq.l #1,d4 | |
bpl.s .lop | |
bsr recieve_byte | |
cmp.b d0,d3 | |
beq.s .ok | |
move.l $4ba,d0 | |
sub.l d5,d0 | |
bsr write_hex8 | |
moveq #-1,d0 | |
movem.l (a7)+,d2-d5 | |
bsr print_return | |
rts | |
.ok: | |
move.l $4ba,d0 | |
sub.l d5,d0 | |
bsr write_hex8 | |
bsr print_return | |
moveq #0,d0 | |
movem.l (a7)+,d2-d5 | |
rts | |
***************************************************** | |
***************************************************** | |
*Peek a block of data from Sega to ST | |
*a0=start adress in Sega | |
*a1=dest adress in ST | |
*d0=antal bytes to Transfere | |
*returns d0=0 om ok, d0=-1 om error | |
peek_block: | |
movem.l d2-d4,-(a7) | |
move.l d0,d3 | |
move.l d0,d4 | |
move.w ram,d0 | |
bsr send_byte | |
move.l a0,d2 *send dest adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
rept 4 *send length of block | |
move.b d3,d0 | |
lsr.l #8,d3 | |
bsr send_byte | |
endr | |
* illegal | |
moveq #0,d3 | |
.lop: | |
bsr recieve_byte | |
move.b d0,(a1)+ | |
add.b d0,d3 | |
subq.l #1,d4 | |
bpl.s .lop | |
bsr recieve_byte | |
cmp.b d0,d3 | |
beq.s .ok | |
moveq #-1,d0 | |
movem.l (a7)+,d2-d4 | |
rts | |
.ok: moveq #0,d0 | |
movem.l (a7)+,d2-d4 | |
rts | |
******************************************* | |
old_dptr: dc.l 0 | |
temp: ds.l 100 | |
ant_rader: dc.w 8 | |
******************************************* | |
dump2: | |
rts | |
******************************************* | |
dump_cell: | |
rts | |
******************************************* | |
get_hexval: | |
moveq #0,d0 | |
moveq #0,d1 | |
.l0 move.b (a0)+,d0 | |
beq.s .tom | |
cmp.w #$21,d0 | |
blt.s .l0 | |
move.w d0,d2 | |
and.w #255-32,d2 | |
cmp.b #"P",d2 | |
beq.s .pc | |
moveq #7,d2 | |
.lop: | |
lsl.l #4,d1 | |
cmp.w #"0",d0 | |
blt.s .err | |
cmp.w #"9",d0 | |
bhi.s .no1 | |
sub.w #"0",d0 | |
bra.s .no2 | |
.no1: and.w #$df,d0 | |
cmp.w #"A",d0 | |
blt.s .err | |
cmp.w #"F",d0 | |
bhi.s .err | |
sub.w #"A",d0 | |
add.w #10,d0 | |
.no2: | |
or.b d0,d1 | |
move.b (a0)+,d0 | |
dbeq d2,.lop | |
move.l d1,d0 | |
moveq #0,d1 | |
rts | |
.pc: | |
move.l sega_pc,d0 | |
moveq #0,d1 | |
rts | |
.tom: moveq #-1,d1 | |
rts | |
.err: moveq #1,d1 | |
rts | |
******************************************* | |
write_hex8: | |
movem.l d0-d3/a0-a3,-(a7) | |
lea hextab(pc),a0 | |
lea .buf(pc),a1 | |
moveq #7,d2 | |
.lop rol.l #4,d0 | |
move.w d0,d1 | |
and.w #15,d1 | |
move.b (a0,d1.w),(a1)+ | |
dbra d2,.lop | |
clr.b (a1)+ | |
pea .buf(pc) | |
move.w #9,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
movem.l (a7)+,d0-d3/a0-a3 | |
rts | |
.buf: ds.b 10 | |
******************************************* | |
write_hex2: | |
movem.l d0-d3/a0-a3,-(a7) | |
lea hextab(pc),a0 | |
lea .buf(pc),a1 | |
moveq #1,d2 | |
.lop rol.b #4,d0 | |
move.w d0,d1 | |
and.w #15,d1 | |
move.b (a0,d1.w),(a1)+ | |
dbra d2,.lop | |
clr.b (a1)+ | |
pea .buf(pc) | |
move.w #9,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
movem.l (a7)+,d0-d3/a0-a3 | |
rts | |
.buf: ds.b 10 | |
******************************************* | |
print_dollar: | |
movem.l d0-d3/a0-a3,-(a7) | |
move.w #"$",-(a7) | |
move.w #2,-(a7) | |
trap #1 | |
addq.l #4,a7 | |
movem.l (a7)+,d0-d3/a0-a3 | |
rts | |
******************************************* | |
print_space: | |
movem.l d0-d3/a0-a3,-(a7) | |
move.w #" ",-(a7) | |
move.w #2,-(a7) | |
trap #1 | |
addq.w #4,a7 | |
movem.l (a7)+,d0-d3/a0-a3 | |
rts | |
******************************************* | |
print_return: | |
movem.l d0-d3/a0-a3,-(a7) | |
pea .ret | |
move.w #9,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
movem.l (a7)+,d0-d3/a0-a3 | |
rts | |
.ret: dc.b 13,10,0,0 | |
******************************************* | |
get_command: | |
clr.l rad | |
clr.l rad+4 | |
clr.l rad+8 | |
clr.l rad+12 | |
clr.l rad+16 | |
move.w #".",-(a7) | |
move.w #2,-(a7) | |
trap #1 | |
addq.w #4,a7 | |
pea line(pc) | |
move.w #10,-(a7) | |
trap #1 | |
addq #6,a7 | |
bsr print_return | |
bsr print_return | |
rts | |
line: dc.b 80,0 | |
rad: ds.b 80 | |
******************************************* | |
*POKE an adress in SEGA, command $03 | |
*a0 = adress to POKE | |
*d0.b= vaule to POKE | |
*format: | |
*s 1 b Sync header ($EA) | |
*s 4 b adress, lsb f”rst | |
*s 1 b vaule to poke | |
poke_sega: | |
move.b d0,d2 | |
move.b #$ea,d0 *send SYNC | |
bsr send_byte | |
move.l a0,d1 *send dest adress | |
rept 4 | |
move.b d1,d0 | |
lsr.l #8,d1 | |
bsr send_byte | |
endr | |
move.b d2,d0 | |
bsr send_byte | |
rts | |
******************************************* | |
*PEEK an adress in the SEGA, command $02 | |
*a0=adress to peek | |
*format: | |
*s 1 b Sync header ($EA) | |
*s 4 b adress, lsb f”rst | |
*r 1 b peeked vaule | |
peek_sega: | |
movem.l d1-d2,-(a7) | |
moveq #2,d0 | |
bsr send_byte | |
move.l a0,d2 *send dest adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
bsr recieve_byte | |
and.w #$ff,d0 | |
movem.l (a7)+,d1-d2 | |
rts | |
******************************************* | |
send_byte: | |
*Set strobe high | |
and.w #255,d0 | |
bset #9,d0 | |
add.w d0,d0 | |
tst.w 100(a6,d0.w) | |
mulu d1,d1 | |
*wait for ack high | |
lop1: btst #9,$fb0000 | |
beq.s lop1 | |
mulu d1,d1 | |
*set strobe low | |
tst.w 100(a6) | |
mulu d1,d1 | |
*wait for ack low | |
lop2: btst #9,$fb0000 | |
bne.s lop2 | |
rts | |
************************************************* | |
recieve_byte: | |
recieve_byte1: | |
*wait for strobe high from Sega | |
.no: move.w $fb0000,d0 | |
btst #8,d0 *r”r ej | |
beq.s .no | |
.noo: move.w $fb0000,d0 | |
btst #8,d0 *r”r ej | |
beq.s .noo | |
and.w #255,d0 | |
*set Ack high | |
move.w #256*2+100,d1 *bit 8 | |
tst.w (a6,d1.w) | |
move.w #256*2+100,d1 *bit 8 | |
tst.w (a6,d1.w) | |
*wait for strobe low from Sega | |
.no1: btst #8,$fb0000 | |
bne.s .no1 | |
.noo1: btst #8,$fb0000 | |
bne.s .noo1 | |
*Set ack low | |
tst.w 100(a6) | |
rts | |
************************************************* | |
pause1: | |
movem.l d0-d1,-(a7) | |
move.w #26170,d1 | |
.del: | |
mulu d0,d0 | |
mulu d0,d0 | |
mulu d0,d0 | |
dbra d1,.del | |
movem.l (a7)+,d0-d1 | |
rts | |
******************************************* | |
reset_megadrive: | |
moveq #5,d5 | |
.again: | |
lea $fa0000-100,a6 | |
moveq #0,d0 | |
tst.w 100(a6,d0.l) *clear latches | |
moveq #0,d0 | |
bset #10,d0 | |
add.w d0,d0 | |
tst.w 100(a6,d0.w) | |
move.w #6170,d1 | |
.del: | |
mulu d0,d0 | |
mulu d0,d0 | |
dbra d1,.del | |
tst.w 100(a6) | |
move.w #3550,d1 | |
.del2: mulu d0,d0 | |
dbra d1,.del2 | |
move.w $fb0000,d0 | |
cmp.b #"O",d0 | |
beq.s .ok | |
moveq #14,d0 | |
bsr print_msg | |
bsr pause1 | |
dbra d5,.again | |
moveq #-1,d0 | |
rts | |
.ok: moveq #3,d0 | |
bsr print_msg | |
moveq #0,d0 | |
rts | |
******************************************* | |
init: move.l #0,-(a7) | |
move.w #$20,-(A7) | |
trap #1 | |
addq.l #6,a7 | |
lea $fa0000-100,a6 | |
moveq #0,d0 | |
tst.w 100(a6,d0.l) *clear latches | |
move.l #514*1024,-(a7) | |
move.w #$48,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
move.l d0,spel | |
move.l d0,a0 | |
add.l #1024*512-1,d0 | |
move.l d0,end_spel | |
move.l d0,a1 | |
.lop: move.b #$ea,(a0)+ | |
cmp.l a0,a1 | |
* bhs.s .lop | |
move.w #3,-(a7) | |
move.w #$e,-(a7) | |
trap #1 | |
addq.l #4,a7 | |
pea .path | |
move.w #$3b,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
rts | |
.path: dc.b "\",0 | |
even | |
******************************************* | |
*Transfere boot / init software to Sega | |
boot_sega: | |
lea .alive,a1 | |
lea temp,a0 | |
move.b #27,(a0)+ | |
move.b #"Y",(a0)+ | |
move.b #32+1,(a0)+ | |
move.b #32+1,(a0)+ | |
.lop: | |
bsr recieve_byte | |
move.b d0,(a0)+ | |
cmp.b (a1)+,d0 | |
* bne .err | |
mulu d1,d1 | |
cmp.b #"%",d0 | |
beq.s .uta | |
cmp.b #"!",d0 | |
bne.s .lop | |
.uta | |
clr.b (a0)+ | |
pea temp | |
move.w #9,-(a7) | |
trap #1 | |
addq.l #6,a7 | |
bsr pause1 | |
move.w #$ea,d0 | |
bsr send_byte | |
lea code,a0 | |
lea end_code,a1 | |
move.l a1,d3 | |
sub.l a0,d3 | |
subq.l #1,d3 | |
ror.w #8,d3 | |
move.b d3,d0 | |
bsr send_byte | |
lsr.w #8,d3 | |
move.b d3,d0 | |
bsr send_byte | |
.colop: | |
mulu d1,d1 | |
mulu d1,d1 | |
mulu d1,d1 | |
mulu d1,d1 | |
mulu d1,d1 | |
mulu d1,d1 | |
mulu d1,d1 | |
move.b (a0)+,d0 | |
bsr send_byte | |
cmp.l a0,a1 | |
bhi.s .colop | |
bsr recieve_byte | |
move.b d0,d1 | |
bsr recieve_byte | |
lsl.w #8,d1 | |
move.b d0,d1 | |
rts | |
.alive: dc.b "OK , I am alive, so what do do now!",0 | |
even | |
.err: illegal | |
*************************************************** | |
*Send a block to Sega with burst mode on | |
*8.7 sec f|r 512 Kb | |
burst_send: | |
* movem.l d2-d7/a2,-(a7) | |
lea $fa0000-100,a6 | |
* move.l $4ba,d5 | |
move.l d0,d3 | |
move.l d0,d4 | |
moveq #0,d0 | |
tst.w 100(a6,d0.l) *clear latches | |
move.l a0,d2 *send dest adress | |
rept 4 | |
move.b d2,d0 | |
lsr.l #8,d2 | |
bsr send_byte | |
endr | |
rept 4 *send length of block | |
move.b d3,d0 | |
lsr.l #8,d3 | |
bsr send_byte | |
endr | |
lea $fb0000,a2 | |
*Do the transfere | |
moveq #0,d3 | |
moveq #8,d6 | |
.lop: | |
moveq #0,d0 | |
move.b (a1)+,d0 | |
bset d6,d0 | |
add.b d0,d3 | |
add.w d0,d0 | |
tst.w 100(a6,d0.w) | |
*wait for ack change | |
.no: btst d6,(a2) | |
beq.s .no | |
moveq #0,d0 | |
move.b (a1)+,d0 | |
add.b d0,d3 | |
add.w d0,d0 | |
tst.w 100(a6,d0.w) | |
*wait for ack change | |
.no1: btst d6,(a2) | |
bne.s .no1 | |
subq.l #2,d4 | |
bpl.s .lop | |
bsr recieve_byte | |
move.b d0,d4 | |
lsl.w #8,d4 | |
bsr recieve_byte | |
move.b d0,d4 | |
ror.w #8,d4 | |
cmp.w d4,d3 | |
beq.s .ok | |
BRA .ok | |
move.l $4ba,d0 | |
sub.l d5,d0 | |
* bsr write_hex8 | |
moveq #-1,d0 | |
* movem.l (a7)+,d2-d7/a2 | |
* bsr print_return | |
rts | |
.ok: | |
* move.l $4ba,d0 | |
sub.l d5,d0 | |
* bsr write_hex8 | |
* bsr print_return | |
* moveq #"S",d0 | |
* bsr send_byte | |
* moveq #5,d0 | |
* bsr send_byte | |
bsr update_reg_window | |
bsr update_mem_window | |
bsr update_dis_window | |
moveq #0,d0 | |
* movem.l (a7)+,d2-d7/a2 | |
rts | |
.tid: dc.l 0 | |
ifd diss | |
include d:\sega\segadis.s | |
endc | |
*************************************************** | |
hextab: dc.b "0123456789ABCDEF" | |
last_command: dc.b 0 | |
even | |
stack: dc.l 0 | |
vector_table: | |
ds.l $80 | |
buf: ds.l 20 | |
spel: dc.l 0 | |
end_spel:dc.l 0 | |
************************************************************ | |
_varbase: equ $ffc000 | |
code: | |
org $ff0000 | |
move #$2700,sr | |
bra.s .c0 | |
dc.b "SEGA-BUG (C) 1992 SYNCHRON ASSEMBLY VER 1.0",0 | |
even | |
.c0: | |
lea $FFFFFC,a0 | |
move.l a0,a7 | |
move a0,usp | |
lea $c0000,a6 | |
move.w #$8004,$c00004 | |
move.w #$814c,$c00004 | |
move.l #_irq2,$68 | |
move.l #_hbl,$70 | |
move.l #_vbl,$78 | |
* move.l #0,a0 | |
* move.l a0,usp *Clear USP | |
clr.w $c0000 | |
*Start of the Segabug target software | |
bsr init_segabug | |
move #$2000,sr | |
move.l #$12345678,d7 | |
move.w #20000,d0 | |
.de1: mulu d1,d1 | |
mulu d2,d2 | |
mulu d2,d2 | |
mulu d2,d2 | |
mulu d2,d2 | |
mulu d2,d2 | |
dbra d0,.de1 | |
lea .tx,a0 | |
lea 1,a1 | |
* move.w #0,(a1) | |
moveq #0,d0 | |
* divu d0,d0 | |
* moveq #"S",d0 | |
* bsr _send_byte1 | |
illegal | |
.de2 | |
moveq #1,d0 | |
moveq #2,d0 | |
move.l #3,d0 | |
move.l #4,d0 | |
move.l #5,d0 | |
move.l #6,d0 | |
move.l #7,d0 | |
bra.s .de2 | |
.tx: dc.b "Dettar „r 12" | |
even | |
************************************************************ | |
init_segabug: | |
************************************************************ | |
lea _varbase,a0 *clear variabel arean | |
moveq #63,d0 | |
.lop: move.l #$12211221,(a0)+ | |
dbra d0,.lop | |
move.l #_irq2,$68 | |
move.l #_hbl,$70 | |
move.l #_vbl,$78 | |
clr.w $c0000 | |
movem.l d0/a0-a1,_saveallreg | |
* Setup exception vectors | |
lea _tab1,a0 | |
lea 8,a1 | |
l1: move.l (a0)+,d0 | |
bmi.s x1 | |
move.l d0,(a1)+ | |
bra l1 | |
x1: | |
*Init IRQ2 regs | |
move.w #$8b08,$c00004 | |
move.b #$80,$a1000d | |
move.b #0,$a1001f | |
move.l #_illegal,$10 | |
movem.l _saveallreg,d0/a0-a1 | |
rts | |
_tab1: dc.l _berr,_adrerr,_illegal,_zerodiv,_chk | |
dc.l _trapv,_priv,_trace,_linea,_linef,-1 | |
************************************************************ | |
_vbl: | |
_hbl: rte | |
_berr: move.l d0,_saveallreg | |
moveq #1,d0 | |
bra _exp1 | |
_adrerr:move.l d0,_saveallreg | |
moveq #2,d0 | |
bra _exp1 | |
_illegal: | |
movem.l d0-d7/a0-a7,_saveallreg | |
move.w #3,_exp_type | |
move.w 0(a7),_sr *SR | |
move.l 2(a7),_pc | |
lea $c0000,a6 | |
bsr _send_allregs | |
*Kolla om illegalen „r en breakpoint | |
lea break_table,a0 | |
moveq #max_breakptr-1,d0 | |
move.l _pc,a1 | |
.la: cmp.l 4(a0),a1 | |
beq.s .f | |
addq.w #8,a0 | |
dbra d0,.la | |
bra _irq5 | |
.f: cmp.w #2,(a0) | |
beq.s .brk2 | |
bra _irq5 | |
.brk2: *1g†ngs breakpoint, „r utf”rd och ta d† bort den | |
move.w 2(a0),(a1) | |
clr.l (a0)+ | |
clr.l (a0) | |
bra _irq5 | |
_zerodiv:move.w #4,_exp_type | |
bra _irq3 | |
_chk: move.w #5,_exp_type | |
bra _irq3 | |
_trapv: move.w #6,_exp_type | |
bra _irq3 | |
_priv: move.w #7,_exp_type | |
bra _irq3 | |
_linea: move.w #8,_exp_type | |
bra _irq3 | |
_linef: move.w #9,_exp_type | |
bra _irq3 | |
_exp1: | |
movem.l d1-d7/a0-a7,_saveallreg+4 | |
move.l $70,save_hbl | |
move.l $78,save_vbl | |
move.l #_hbl,$70 | |
move.l #_vbl,$78 | |
move.w (a7),_savestack *Access type | |
move.l 2(a7),_pc2 *Current cycle | |
move.w 6(a7),_ir *Instruction register | |
move.w 8(a7),_sr *SR | |
move.l 10(a7),_pc | |
move.w d0,_exp_type | |
addq.l #8,a7 | |
bra _irq4 | |
rte | |
_trace: | |
move #$2700,sr | |
move.w #13,_exp_type | |
bra _irq3 | |
_irq2: | |
move #$2700,sr | |
move.w #12,_exp_type | |
_irq3: | |
movem.l d0-d7/a0-a7,_saveallreg | |
move.w 0(a7),_sr *SR | |
move.l 2(a7),_pc | |
_irq5: | |
move.l $70,save_hbl | |
move.l $78,save_vbl | |
move.l #_hbl,$70 | |
move.l #_vbl,$78 | |
_irq4: | |
lea $c0000,a6 | |
moveq #"D",d0 | |
bsr _send_byte1 | |
move.w _exp_type,d0 | |
bsr _send_byte1 | |
bsr _send_axdata | |
bsr _send_allregs | |
******Here starts the real Remote Debugger code | |
*Header 'S' | |
*1: Continue exection | |
*2: Burstsend data from SRAM to ST | |
*3: Trace PC | |
*4: Burst recieve data to SEGA from ST | |
*5: Get all regs | |
*6: set PC | |
*7: Set breakpoint nr xx= Illegal command and save old instruction | |
*8: Burst Send data from Z80 to ST | |
*9: Burst send data from Vram to ST | |
*10:Remove breakpoint at adr xxxx and restore old opcode | |
*11:Get Sram size in Sega | |
*Wait for command | |
.wa: bsr _receive_byte | |
cmp.b #"S",d0 | |
bne.s .wa | |
bsr _receive_byte | |
cmp.w #1,d0 | |
beq.s .exit | |
cmp.w #3,d0 | |
beq.s .trace | |
add.w d0,d0 | |
add.w d0,d0 | |
move.l .tab(pc,d0.w),a0 | |
jsr (a0) | |
bra.s .wa | |
.tab: dc.l .no,.no,_burst_send,.no,_burst_recieve,_fill,_set_pc,_set_break | |
dc.l _read_z80,_read_vram,_remove_break,_get_memsize | |
.exit: movem.l _saveallreg,d0-d7/a0-a6 | |
move.l _sr,(a7) | |
move.l _pc,2(a7) | |
and.w #$7fff,(a7) | |
move.l save_hbl,$70 | |
move.l save_vbl,$78 | |
rte | |
.no: rts | |
.trace: | |
move.l _pc,a0 | |
cmp.w #$4afc,(a0) | |
beq .wa | |
.c0: move.l #_trace,$24 | |
movem.l _saveallreg,d0-d7/a0-a6 | |
move.l _sr,(a7) | |
move.l _pc,2(a7) | |
or.w #$8000,(a7) | |
move.l save_hbl,$70 | |
move.l save_vbl,$78 | |
rte | |
************************************************************ | |
*Get memory SRAM size | |
_get_memsize: | |
lea $fffe,a0 | |
.l1: move.w (a0),d0 | |
move.w d0,d1 | |
not.w (a0) | |
not.w d1 | |
cmp.w (a0),d1 | |
bne.s .no | |
move.w d0,(a0) | |
add.l #$10000,a0 | |
bra.s .l1 | |
.no: move.w d0,(a0) | |
sub.l #$ffff,a0 | |
move.l a0,d2 | |
rept 4 | |
rol.l #8,d2 | |
move.b d2,d0 | |
bsr _send_byte1 | |
endr | |
rts | |
************************************************************ | |
_remove_break: | |
bsr _receive_byte *get break number to remove | |
lea break_table,a0 | |
lsl.w #3,d0 | |
lea (a0,d0.w),a0 | |
tst.w (a0) | |
beq.s .x | |
move.l 4(a0),a1 | |
move.w 2(a0),(a1) | |
clr.l (a0)+ | |
clr.l (a0) | |
.x: rts | |
************************************************************ | |
*Burst read VRAM | |
_read_vram: | |
lea $c00000,a4 | |
move.l d1,d6 | |
lsl.l #2,d6 | |
lsr.w #2,d6 | |
swap d6 | |
move.l d6,4(a4) | |
lea _temp,a3 | |
rept 4 | |
bsr _receive_byte *get start adress | |
move.b d0,(a3)+ | |
endr | |
move.l _temp,d6 | |
and.l #-2,d6 *even word only | |
lsl.l #2,d6 | |
lsr.w #2,d6 | |
swap d6 | |
move.l d6,4(A4) | |
lea _temp,a3 | |
rept 4 *get antal bytes | |
bsr _receive_byte | |
move.b d0,(a3)+ | |
endr | |
move.l _temp,d2 | |
lea $c0000,a6 | |
clr.w (a6) | |
moveq #8,d6 | |
moveq #0,d3 | |
move.w #256,d5 | |
moveq #0,d0 | |
lea $c00000,a4 | |
.lop: | |
move.w (a4),_temp | |
move.b _temp,d0 | |
add.b d0,d3 *Add checksum | |
or.w d5,d0 *bset #8 | |
move.w d0,(a6) | |
*wait for ack change | |
.no: btst d6,(a6) | |
beq.s .no | |
move.b _temp+1,d0 | |
add.b d0,d3 *Add checksum | |
and.w #255,d0 *bclr #8 | |
move.w d0,(a6) | |
*wait for ack change | |
.no1: btst d6,(a6) | |
bne.s .no1 | |
subq.l #2,d2 | |
bpl.s .lop | |
clr.w (a6) | |
move.w d3,d0 | |