Some background: I want to create a CPC MicroSD interface, so my first step is trying to hook the CAS* jumpblock entries just like AMSDOS and other DOSes do.
My first goal is to override CAS CATALOG
so that Basic's CAT
does not try reading from the cassette and instead prints something and returns immediately to Basic's prompt (just like CAT
does when AMSDOS is loaded).
After inspecting Basic 1.0's listing (see D246
for Basic's CAT
code) I discovered Basic also calls the CAS IN/OUT ABANDON
functions (in D2AD
) so I'll hook those too just in case.
I made a ROM (see the listing at the bottom of the question) that hooks the CAS CATALOG
, CAS IN ABANDON
and CAS OUT ABANDON
functions and prints their names instead.
Everything seems to load and run fine (I'm using WinAPE), but when I type CAT
in Basic, after the hooked CAS* functions are called (and their names are printed, so the hook worked)... the CPC is stuck reading from tape! I get no other message, and the only way to get the "Ready" message and keyboard response is to either press ESC to trigger a *break*
or play a tape. Playing a tape from start to finish produces no output at all, but once finished cataloguing returns to Basic's prompt.
What am I doing wrong?
Here's AMSDOS which instantly goes back to Basic prompt (indicated by the Ready
message) as I want mine to do:
And here's my ROM waiting for tape data:
My ROM after pressing ESC:
My ROM Listing
hello.rasm
(works with RASM).
save "hello.rom",#c000,#ffff-#c000
org #c000
os_reset equ #0000
os_txt_output equ #bb5a
os_cas_in_abandon equ #bc7d
os_cas_catalog equ #bc9b
os_cas_out_abandon equ #bc92
kl_curr_selection equ #b912
header:
db 1
db 0,0,0
dw rsx_commands
rsx_table:
jp init
jp hello
jp reset
rsx_commands:
str "TEST ROM"
str "HELLO"
str "RESET"
db 0
ALIGN 2
init:
push ix,bc
;; Reserve 9 bytes for RST 18h args
ld bc, -9
add hl, bc
inc hl ;; HL = first available byte
push af
push hl ;; load hl into ix
pop ix
call kl_curr_selection ;; A = current upper ROM number
;; BB AA XX -- FAR CALL to AABB in ROM XX
ld (ix+0), lo(my_cas_catalog)
ld (ix+1), hi(my_cas_catalog)
ld (ix+2), a
ld (ix+3), lo(my_cas_in_abandon)
ld (ix+4), hi(my_cas_in_abandon)
ld (ix+5), a
ld (ix+6), lo(my_cas_out_abandon)
ld (ix+7), hi(my_cas_out_abandon)
ld (ix+8), a
pop af
;; Patch jump block entries with FAR CALL into our ROM
;; (HL) = DF LL HH = RST 18h (HHLL)
ld bc, 3
ld ix, os_cas_catalog
ld (ix+0), #df
ld (ix+1), l
ld (ix+2), h
add hl, bc
ld ix, os_cas_in_abandon
ld (ix+0), #df
ld (ix+1), l
ld (ix+2), h
add hl, bc
ld ix, os_cas_out_abandon
ld (ix+0), #df
ld (ix+1), l
ld (ix+2), h
ld bc, -6
add hl, bc
;; Print copyright message
push hl
ld hl, str_init
call print_str
pop hl
;; HL = last available address for next ROM
dec hl
pop bc,ix
ret
;; |HELLO
hello:
push hl
ld hl, str_hello
call print_str
pop hl
ret
;; |RESET
reset:
jp os_reset
;; ----
print_str:
ld a, (hl)
or a
ret z
call os_txt_output
inc hl
jr print_str
my_cas_catalog:
push hl
ld hl, str_cas_catalog
call print_str
pop hl
;; reset Z (preserving A)
push bc
ld b, a
ld a, 1
cp 0
ld a, b
pop bc
;; set carry flag
scf
;; !Z && C == success
ret
my_cas_in_abandon:
ld hl, str_cas_in_abandon
call print_str
ret
my_cas_out_abandon:
ld hl, str_cas_out_abandon
call print_str
ret
str_init: db " kaoD testing",10,13,10,13,0
str_hello: db "Hello world!",10,13,10,13,0
str_cas_catalog: db "CAS CATALOG",10,13,10,13,0
str_cas_in_abandon: db "CAS IN ABANDON",10,13,10,13,0
str_cas_out_abandon: db "CAS OUT ABANDON",10,13,10,13,0