; Implement main debugger logic on this file.
;
; F000:vmstart -- 0x08000000 - 0x08001FFF
; is set as usable memory in cache for us
;
;
; SECONDARY_CODEMEM:
; - 'secondary' program code is to be stored here
;
; SECONDARY_STACKMEM
; - Beginning of 'secondary' stack / cache region
;
%include "src/memory_map.asm"
bits 16
; ------------------------------------------------------------
; Temporary/test secondary program to execute
;
secondary_program:
add ax, 4
add bx, 4
sub bx, 2
mov cx, bx
dec cx
add cx, 7
cli
hlt
hlt
times 16 db 0xf4
.end:
SECONDARY_PROGRAM_SIZE equ (secondary_program.end - secondary_program)
; ------------------------------------------------------------
; The program to debug has been halted, loop here until
; reset happens.
;
program_halted:
mov si, .msg_program_halted
call serial_print
call ui_wait_keypress
cmp al, 0x72
je do_reset
jmp program_halted
.msg_program_halted:
db "Debugged program called halt, press r to restart"
db 0x0A, 0x0D, 0
; ------------------------------------------------------------
; Handle branching instructions
;
program_branched:
mov si, .msg_branch_encountered
call serial_print
call ui_wait_keypress
jmp program_branched
.msg_branch_encountered:
db "Program branching is not supported yet", 0x0A, 0x0D, 0
; ------------------------------------------------------------
; Beginning of our weird context hopping program.
;
vmstart:
; ------------------------------------------------------------
; Set single step counter to 0
;
mov edi, UI_ADDR_STEP_CNT
xor ax, ax
stosb
; ------------------------------------------------------------
; Set the initial cache pointer
;
; mov dword [SECONDARY_STACKPTR], SECONDARY_STACKMEM
mov eax, SECONDARY_STACKMEM
stosd
; ------------------------------------------------------------
; Init cycle exec counter
;
mov eax, 1
stosd
; ------------------------------------------------------------
; Set segments for relocating code to segment 0
;
mov ax, cs
mov ds, ax
xor ax, ax
mov es, ax
stosw
; ------------------------------------------------------------
; copy secondary code and return trampoline to low memory
;
mov di, SECONDARY_EXECPTR+2
mov si, return_trampoline
mov cx, (return_trampoline.end - return_trampoline)
rep movsb
; ------------------------------------------------------------
; copy secondary code/test program into cache
;
and eax, 0x0000FFFF
and esi, 0x0000FFFF
mov si, secondary_program
mov cx, SECONDARY_PROGRAM_SIZE
xor ax, ax
mov es, ax
mov edi, SECONDARY_CODEMEM
rep movsb
xor ax, ax
mov ds, ax
and edi, 0x0000FFFF
mov cx, SECONDARY_PROGRAM_SIZE
mov esi, SECONDARY_CODEMEM
; ------------------------------------------------------------
; Setup complete, we can start executing code from
; cache now
;
.exec_loop:
; ------------------------------------------------------------
; Fetch next instruction to execute
; to SECONDARY_EXECPTR
;
mov di, SECONDARY_EXECPTR
mov cx, 16
mov ax, 0x90
rep stosb
mov di, SECONDARY_EXECPTR
call load_operation
add si, dx
; ------------------------------------------------------------
; Check if we've encountered halt or branching instructions.
;
push ax
mov al, byte [SECONDARY_EXECPTR]
cmp al, 0xf4
je program_halted
call opcode_is_branching
jc program_branched
; ------------------------------------------------------------
; Store primary register values
;
mov esp, PRIMARY_REGPTR
pushad
; ------------------------------------------------------------
; Invoke debugger user interface and increment cycle counter
;
mov ebp, SECONDARY_REGPTR - (8 * 4)
call ui_prompt
call print_registers
mov edi, CYCLES_EXECUTED
xchg esi, edi
lodsd
inc eax
sub si, 4
xchg edi, esi
stosd
; ------------------------------------------------------------
; Restore secondary register values off cache and
; continue execution
;
mov esp, SECONDARY_REGPTR - (8 * 4)
popad
mov esp, dword [SECONDARY_STACKPTR]
; ------------------------------------------------------------
; Execute next debuggee instruction
;
jmp 0x0000:SECONDARY_EXECPTR
; ------------------------------------------------------------
; Return here after executing one cycle of code has been
; executed.
;
; Backup debuggee state, restore debugger state, and
; loop back to beginning.
;
.exec_loop_cycle_done:
mov dword [SECONDARY_STACKPTR], esp
; ------------------------------------------------------------
; Store secondary register values to cache
;
mov esp, SECONDARY_REGPTR
pushad
; ------------------------------------------------------------
; Restore primary register values
;
mov esp, PRIMARY_REGPTR - (8 * 4)
popad
jmp .exec_loop
return_trampoline:
times 16 db 0x90
jmp 0xF000:vmstart.exec_loop_cycle_done
.end:
%include "src/opcode_list.asm"
%include "src/opcode_parser.asm"
%include "src/debugger_ui.asm"
%include "src/disassembly.asm"
%include "src/str.asm"