quinta-feira, 26 de dezembro de 2019

Dica: usar registo Q do Z80 - detectar Z80 CPUs da NEC

Como já mencionado anteriormente, em CPUs compativeís Zilog, o registo Q, é um cache que indica se as flags foram alteradas ou não, na última instrução. É um registo interno não acessível, e afecta no output das instruções SCF e CCF as flags não documentadas.

Podemos portanto (ab)usar este comportamento, para detectar um CPU Z80 NEC, que não é 100% compatível Zilog,  e é comummente usado em máquinas Sinclair e Timex.

   ; 
   ; NEC Z80 detection
   ; Rui Ribeiro 2019
   ;
   ; PRINT USR 50000
   ;
   ; returns:
   ;
   ; 0 if NEC
   ; 1 if Z80 Zilog compatible
   ;

   ORG 50000

   LD  BC,1     ; BC=1 -- Z80 not NEC
   XOR A        ; A=0
   LD  D,A      ; D=A
   DEC D        ; A-1=$FF Q=1
   NOP          ; Q=0
   CCF          ; X=1 and Y=1 if Zilog,other compatibles
                ; X=0 and Y=0 if NEC Z80

   PUSH AF
   POP  DE      ; get F into E

   LD   A,E
   AND  $28     ; 00101000 - test X and Y

   RET  NZ      ; return if Z80 not NEC

   DEC  BC      ; Z80 is a NEC, BC=0
   RET

Usando esta rotina, com PRINT USR 50000, se a CPU ou emulador for compatível Zilog, retorna 1, de outra forma, se a implementação do Z80 do emulador não for 100% compatível Zilog ou for uma CPU Z80 NEC, retorna 0.

Nota: Agradecimentos ao Miguel Capelo por ter testado esta rotina em Z80s de Spectrums e Timexs, nomeadamente Z80A da Mostek, NEC, Zilog e SGS.

5 comentários:

  1. Obrigado Rui, e no que puder ir ajudando podes contar comigo.
    Abraço.

    ResponderEliminar
  2. Hello,
    Thank you very much for such useful article. I hope you don't mind I translated it for Slovak and Czech community and posted here https://sindik.at/?p=930709

    ResponderEliminar
    Respostas
    1. Hi, You are welcome. If you are interested on the theme, we have more technical articles here of mine, feel free to translate them.
      Regards

      Eliminar
  3. Thank you. I'll look around and try to find more articles for translation. Keep writing! ;)

    ResponderEliminar
  4. Uma possível optimização é fazer DEC C no fim, mas como a rotina é pouco usada e os opcodes ocupam um byte na mesma....DEC BC fica mais legível.

    ResponderEliminar