Login

Subversion Repositories NedoOS

Rev

Rev 539 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

# file opened: hw_safe_cspect_break.asm
 1    0000              ; The `s_break` macro is "safe" wrapper for CSpect breakpoint fake instruction `break`.
 2    0000              ;
 3    0000              ; On HW board (Z80N or regular Z80) the `break` opcode DD 01 will be processed
 4    0000              ; as wrongly prefixed `ld bc,imm16`, eating further two bytes of the code after
 5    0000              ; `break`, damaging value in BC register, and skipping two bytes of machine code.
 6    0000              ;
 7    0000              ; The `s_break` macro will produce 6 byte machine code which is "mostly harmless"
 8    0000              ; on real HW except using stack to preserve BC value and taking 11+4+10+10 T cycles
 9    0000              ; to execute. While in CSpect emulator with breakpoints enabled the code will still
10    0000              ; trigger the debugger (and add the "nop : nop : pop bc" extra instruction sequence
11    0000              ; after it).
12    0000              ;
13    0000              ; (I would still recommend to configure "debug" builds with exit/break enabled and
14    0000              ; having separate "release" configuration with `--zxnext` only, which will report
15    0000              ; any remaining break/exit instruction left in the source)
16    0000              ;
17    0000              ; (so this example is more like documentation that bad things happen if you forget
18    0000              ; CSpect `break` instruction somewhere and try such code on the HW board)
19    0000              ;
20    0000
21    0000                  MACRO s_break
22    0000 ~                    OPT push reset --zxnext=cspect
23    0000 ~                    push bc
23    0000 ~              break
23    0000 ~              nop
23    0000 ~              nop
23    0000 ~              pop bc
24    0000 ~                    OPT pop
25    0000                  ENDM
26    0000
27    0000                      ; example of usage
28    0000                      DEVICE ZXSPECTRUM48
28    0000                ORG $8000
29    8000              start:
30    8000 06 04                ld      b,4
31    8002 AF                   xor     a
32    8003                      s_break
32    8003             >        OPT push reset --zxnext=cspect
32    8003 C5          >        push bc
32    8004 DD 01       >  break
32    8006 00          >  nop
32    8007 00          >  nop
32    8008 C1          >  pop bc
32    8009             >        OPT pop
33    8009              myLoop:
34    8009 3C                   inc     a
35    800A D3 FE                out     (254),a
36    800C 10 FB                djnz    myLoop
37    800E                      ; `exit` has opcode DD 00, which on regular Z80[N] works as 8T "nop" instruction
38    800E                      OPT --zxnext=cspect
38    800E DD 00          exit      ; i.e. no need for wrapping macro
39    8010 18 FE                jr      $
40    8012
41    8012                      SAVESNA "break.sna", start
41    8012                CSPECTMAP "break.map"
42    8012
# file closed: hw_safe_cspect_break.asm

Value    Label
------ - -----------------------------------------------------------
0x8009   myLoop
0x8000 X start