Interrupt brings up Monitor: working, but calling "run" leaves garbage in the SP

This commit is contained in:
Daniele Verducci (ZenPenguin) 2021-01-03 09:37:22 +01:00
parent b98ad3e136
commit 08b32b2064
3 changed files with 32 additions and 41 deletions

View File

@ -1,6 +1,6 @@
Sys_ABI: equ $007e Sys_ABI: equ $0081
Sys_Beep: equ $008e Sys_Beep: equ $0091
Sys_Print: equ $0082 Sys_Print: equ $0085
Sys_Printc: equ $0085 Sys_Printc: equ $0088
Sys_Readc: equ $0088 Sys_Readc: equ $008b
Sys_Readline: equ $008b Sys_Readline: equ $008e

View File

@ -21,9 +21,14 @@ jp Sysinit ; Startup vector: DO NOT MOVE! Must be the first instruction
; **** RESET/INTERRUPT VECTOR **** ; **** RESET/INTERRUPT VECTOR ****
; Maskable interrupt mode 1: execute memory monitor ; Maskable interrupt mode 1: when the BREAK key is pressed,
; a maskable interrupt is generated and the CPU jumps to this address.
; In this way, BREAK key brings up memory monitor at any time.
ds 0x38 ds 0x38
call Monitor_main di ; Disable maskable interrupts.
exx ; exchange registers
ex af, af'
jp Monitor_main
; **** SYSTEM CALLS **** ; **** SYSTEM CALLS ****
; System calls provide access to low level functions (input from keyboard, output to screen etc). ; System calls provide access to low level functions (input from keyboard, output to screen etc).

View File

@ -31,8 +31,6 @@ MON_DUMP_BYTES_LINES: EQU 8
MON_DUMP_BYTES_PER_LINE: EQU 8 MON_DUMP_BYTES_PER_LINE: EQU 8
Monitor_main: Monitor_main:
; Disable maskable interrupts. MI are used to break a program execution and bring up immediately the memory monitor.
call monitor_disable_int
; Print welcome string ; Print welcome string
ld bc, MON_WELCOME ld bc, MON_WELCOME
call Sys_Print call Sys_Print
@ -92,8 +90,14 @@ monitor_quit:
; newline ; newline
ld a, 10 ld a, 10
call Sys_Printc call Sys_Printc
; re-enable interrupts ; Restores registers and re-enable interrupts: when the BREAK key is pressed,
call monitor_enable_int ; a maskable interrupt is generated and the CPU jumps to 0x38 reset vector,
; where if finds a call to Memory monitor (see main.asm).
exx ; exchange registers
ex af, af'
; enable interrupts
ei
im 1 ; set interrupt mode 1 (on interrupt jumps to 0x38)
reti ; return from interrupt reti ; return from interrupt
@ -280,14 +284,18 @@ monitor_load:
monitor_run: monitor_run:
ld bc, MON_COMMAND_RUN + 1 ; autocomplete command ld bc, MON_COMMAND_RUN + 1 ; autocomplete command
call Sys_Print call Sys_Print
; Now read the memory address to be changed from the user ; Now read the memory address to be executed from the user
call monitor_arg_2byte ; returns the read bytes in hl call monitor_arg_2byte ; returns the read bytes in hl
ld a, 10 ; newline ld a, 10 ; newline
call Sys_Printc call Sys_Printc
ld sp, hl ; Point stack pointer to code to execute ; enable interrupts
; re-enable interrupts ei
call monitor_enable_int im 1 ; set interrupt mode 1 (on interrupt jumps to 0x38)
reti ; pop the last entry on the stack: this is needed (as the monitor
; runs in an interrupt) to counter-balance the missing reti statement
pop bc
; execute code
jp (hl)
monitor_adb: monitor_adb:
ld bc, MON_COMMAND_ADB + 1 ; autocomplete command ld bc, MON_COMMAND_ADB + 1 ; autocomplete command
@ -540,28 +548,6 @@ monitor_copyTermToAppMem:
dec d dec d
jp monitor_copyTermToAppMem_loop ; continue loop jp monitor_copyTermToAppMem_loop ; continue loop
; Restores registers and re-enables interrupt.
; Enable interrupts: when the BREAK key is pressed, a maskable interrupt is generated and
; the CPU jumps to 0x38 reset vector, where if finds a call to Memory monitor (see main.asm).
; In this way, BREAK key brings up memory monitor at any time.
; To be called before the user exits from monitor
monitor_enable_int:
; exchange registers
exx
ex af, af'
; enable interrupts
ei
im 1 ; set interrupt mode 1 (on interrupt jumps to 0x38)
ret
; Saves registers and disables interrupts.
; To be called when the monitor starts
monitor_disable_int:
di ; disable interrupt
; exchange registers
exx
ex af, af'
ret