Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download
# 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
------ - -----------------------------------------------------------
0x8000 X start
0x8009 myLoop