;
;Debugging routines. These are of two kinds:
;
; * Routines to assist in debugging the z-machine itself.
; * Diagnostic output should a z-program fail.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Code for debugging the Z-machine.
;
;This prints the text immediately following the CALL:
;
; call ilprint
; defb 'text'
;
ilprint:
ex (sp),hl ;HL -> inline parameter
push af
push bc
push de
ld d,h
ld e,l
push hl
ld c,9
ld a,(trace)
or a
call ZXFDOS
pop hl
ilpr1: ld a,(hl)
inc hl
cp '$'
jr nz,ilpr1
pop de
pop bc
pop af
ex (sp),hl
ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;This subroutine causes a border colour change and waits for a keypress.
;It is intended to provide a simple method of tracing where the program has
;got to.
;
;yes_i_live:
;
;<< v0.02 >> Spectrum-specific code moved to ZXIO.BIN as ZXILIV.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Print a hex number in A/BC/DE/HL/IX, and wait for a keypress.
;
hexa: push de
ld d,0
ld e,a
jr hexd1
;
hexix: push de
push ix
pop de
jr hexd1
hexbc: push de
ld d,b
ld e,c
hexd1: call hexde
pop de
ret
;
hexhl: ex de,hl
call hexde
ex de,hl
ret
;
hexde: push af
push bc
push de
push hl
ex de,hl
ld de,hbuf+4
push de
call sphex4
pop de
ld c,9
call ZXFDOS
popd: pop hl ;<< v0.02 This code was in yes_i_live
pop de ; but has been moved
pop bc
pop af
ret ;>>
;
showlcl:
push af ;<< v0.04 Show local variables
push bc
push de
push hl
showl0: push ix
ld b,6
showl3: call ilprint
defb ' Locals $'
ld hl,(zsp)
ld de,4
add hl,de
;
showl1: ld e,(hl)
inc hl
ld d,(hl)
inc hl
call hexde
call ilprint
defb ' $'
djnz showl1
showle: call ilprint
defb 13,10,'$'
pop ix
jr popd
showpc: push af
push bc
push de
push hl
ld a,(trace)
or a
jr z,popd
spc2: ld hl,(zpc)
ld bc,(zpc+2)
ld de,hbuf+2
push de
call sphex6
pop de
ld c,9
call ZXFDOS
jr showl0 ;Show local variables
ld de,crlf
ld c,9
call ZXFDOS
;; ld c,1
;; call zxfdos
jr popd
hbuf: defb '00000000$'
crlf: defb 13,10,'$'
trace: defb 0
;
ifpc: push hl
ld hl,(zpc)
and a
sbc hl,bc
jr nz,ifpc0
ld a,(zpc+2)
cp d
ifpc0: pop hl
ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Routines for debugging Z-programs.
;
; This prints the Z-machine's stack (excluding the artificial 'entry' frame).
;
showstk:
ld de,strace ;"Stack trace:"
ld c,9
call ZXFDOS
ld ix,(zsp) ;Bottom of stack
shows1: call dframe ;Dump a frame
ld de,38
add ix,de ;Reached the top yet?
push ix
pop hl
ld de,(zstop)
and a
sbc hl,de
jr nz,shows1
ld de,strend ;"[End of stack]"
ld c,9
call ZXFDOS
ret
;
dframe: ld de,sfr1 ;Dump a single stack frame
ld l,(ix+0)
ld h,(ix+1)
ld c,(ix+2)
call sphex6 ;PC
ld de,sfr2
ld a,(ix+34)
call sphex2 ;CALL method
ld de,sfr3
ld l,(ix+36)
ld h,(ix+37)
call sphex4 ;Routine stack pointer
ld de,sfr4
ld a,(ix+35)
call sphex2 ;No. of parameters
push ix
ld de,sframe
ld c,9
call ZXFDOS ;Print stack frame line
pop ix
ld b,15
push ix
llp: ld de,lln
ld l,(ix+4)
ld h,(ix+5)
push bc
push ix
call sphex4
ld de,lln
ld c,9
call ZXFDOS
pop ix
pop bc
inc ix
inc ix
djnz llp
ld de,crlf_
ld c,9
call ZXFDOS
pop ix
ret
;
sframe: defb 'Caller PC='
sfr1: defb '000000 Call type='
sfr2: defb '00 Routine sp='
sfr3: defb '0000 params '
sfr4: defb '00'
defb 13,10,'$'
lln: defb '0000$'
strace: defb 'Z-machine stack trace:',13,10,'$'
strend: defb '[End of stack]'
crlf_: defb 13,10,'$'
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Illegal instruction error
;
fail2: pop de ;POP the stack twice first
fail1: pop de ;POP the stack once first
fail: ld hl,(zipc)
ld bc,(zipc+2)
ld de,iistr1
call sphex6 ;PC
ld de,iistr
ld a,(inst)
cp 0BEh ;EXT:?
jr nz,faila
call sphex2
ld a,(inst+1)
call sphex2
ex de,hl
ld (hl),13
inc hl
ld (hl),10
inc hl
ld (hl),'$'
jr failb
;
faila: call sphex2 ;Opcode
failb: ld de,iistr0
ld c,9 ;Print message
call ZXFDOS
ld hl,iinst
xor a
ret
;
iinst: defb 'A Illegal instructio'
defb 0EEh ;'n'+ 80h
iistr0: defb 'Illegal instruction at PC='
iistr1: defb '000000 : opcode = '
iistr: defb '00'
defb 13,10,36,0,0 ;The 2 zeroes allow the string to grow...
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Stack overflow error
;
spfail2:
pop de
spfail1:
pop de
spfail: ld hl,(zpc)
ld bc,(zpc+2)
ld de,sostr1
call sphex6 ;PC
ld a,(inst)
ld de,sostr
call sphex2 ;Opcode
ld de,sostr0
ld c,9 ;Print message
call ZXFDOS
ld hl,sover
xor a
ret
;
sover: defb '4 Out of stac'
defb 0EBh ;'k'+80h
sostr0: defb 'Illegal instruction at PC='
sostr1: defb '000000 : opcode = '
sostr: defb '00'
defb 13,10,36
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
proper2:
pop hl
proper1:
pop hl
properr:
push de ;Object no.
push bc ;Property no.
ld hl,(zpc)
ld bc,(zpc+2)
ld de,pestr1
call sphex6 ;PC
pop bc
ld a,c
ld de,pestr3
call sphex2
pop hl
ld de,pestr2
call sphex4
ld de,pestr
ld c,9 ;Print message
call ZXFDOS
ld hl,perr
xor a
ret
;
perr: defb '2 Property not foun'
defb 0E4h ;'d'+80h
pestr: defb 'Invalid property at PC='
pestr1: defb '000000 Object '
pestr2: defb '0000 property '
pestr3: defb '00',13,10,'$'
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Division by 0
;
div0: ld hl,(zpc)
ld bc,(zpc+2)
ld de,d0str1
call sphex6
ld de,d0str
ld c,9
call ZXFDOS
ld hl,d0err
xor a
ret
;
d0str: defb 'Division by zero at PC='
d0str1: defb '000000',13,10,'$'
d0err: defb '6 Division by zer'
defb 0EFh ;'o'+80h
;