?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

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