; ZXZVM: Z-Code interpreter for the Z80 processor ; Copyright (C) 1998-9,2006,2016 John Elliott ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; ;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 ;; Set to nonzero to enable debug trace ; 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 ;