Detecting (Next) Emulator or Hardware [til/spectrum]

Written by Remy Sharp / Original link on Mar. 28, 2021

Sometimes useful, I've certainly run into bugs with emulation vs. real machines.

DEFPROC isReal()
  ; dw $01DD : nop : nop : ret
  POKE %$4000, %$dd, 1, 0, 0, %$c9
  v= USR 16384 :; can't use integer values here - important
  IF v=16384 THEN ENDPROC= 0 :; CSpect emulator
  v= % REG 0
  IF v = 8 THEN ENDPROC= 0 :; ZESarux emulator
  IF v = 10 THEN ENDPROC= 1:; real h/w

This POKE is based on a few ideas. First that when we land in machine code, that BC is the address of entry. So when the code returns in Cspect-land, the value of BC will be the same as entry, which is the address of the routine, hence IF v = 16384.

However, BC being set at the address of entry is, apparently, not a specified feature - just a happy accident. This does mean that it's not actually in place when the same call is made using integer values. i.e. % USR $4000 returns garbage (or specifically a very low value) into BC.

In Cspect, the $DD01 is a bespoke break opcode. On the hardware, I'm not 100% certain, but the $DD is skipped (a no op) and the code then translates to LD BC, 0.

/via Johnny Gilbbitts

Originally published on Remy Sharp's b:log


« CSS Container Queries: A First Look + Demo - Testing: Showing Ideas »