Como escrevemos no primeiro artigo:
HL',DE',BC',AF' - conjunto de registos alternativos de variáveis do Z80 (shadow registers). HL',DE',BC' acessíveis apenas através da instrução EXX e o AF' pela instrução EX AF,AF'.
Como mencionado, os registos, B',C',D',E',H',L',A' e F' não são usados directamente pela CPU. Existem no entanto instruções que os multiplexam / trocam pelos registos em uso.
A instrução EX AF, AF' troca o registo AF pelo AF' (e de volta).
A instrução EXX, troca os registos:
- B por B'
- C por C'
- D por D'
- E por E'
- H por H'
- L por L'
Estas instruções existem, para remediar o número limitado de registos de processador no Z80, sem aumentar muito a sua complexidade ao nível de gates. São também muito mais rápidas de usar do que usar posições de memória ou stack, sendo que quer a instrução EXX, quer a EX AF,AF' executam-se em 4T.
From the Z80 oral History, quoting Federico Faggin:
"So I wanted to have a couple of index registers, more 16-bit operations, a better interrupt structure. The whole idea of doubling the number of registers. And I could exchange the register with an exchange instruction, the whole register set. That was an idea that I had used already on the Intel 4040. So that one could serve it up very fast if that was a necessity. And on and on."
Por exemplo, os registos alternativos podem, por exemplo, ser usados numa rotina de interrupts. No entanto, há que ter o cuidado, que usando rotinas da ROM, notavelmente rotinas do / que usem o stack de floating point, ou de impressão, eles são usados. Por essa mesma razão, ao voltar ao BASIC, é necessário restaurar HL' a $2758.
Outro do uso dos registos alternativos, pode ser por exemplo, para passar parâmetros a uma função.
Exemplos da ROM do uso dos registos alternativos na ROM:
;; PO-SAVE | |
L0C3B: PUSH DE ; Save DE value. | |
EXX ; Switch in main set | |
RST 10H ; PRINT-A prints using this alternate set. | |
EXX ; Switch back to this alternate set. | |
POP DE ; Restore the initial DE value. | |
RET ; Return. |
;----------
;; NEW | |
L11B7: DI ; Disable Interrupts - machine stack will be | |
; cleared. | |
LD A,$FF ; Flag coming from NEW. | |
LD DE,($5CB2) ; Fetch RAMTOP as top value. | |
EXX ; Switch in alternate set. | |
LD BC,($5CB4) ; Fetch P-RAMT differs on 16K/48K machines. | |
LD DE,($5C38) ; Fetch RASP/PIP. | |
LD HL,($5C7B) ; Fetch UDG differs on 16K/48K machines. | |
EXX ; Switch back to main set and continue into... |
;------------
EX AF,AF' ; save flag?? LD ($5C5F),HL ; preserve workspace pointer in dynamic X_PTR | |
EX DE,HL ; transfer program dest pointer to HL. | |
CALL L19B8 ; routine NEXT-ONE finds following location | |
; in program or variables area. | |
CALL L19E8 ; routine RECLAIM-2 reclaims the space between. | |
EX DE,HL ; transfer program dest pointer back to DE. | |
LD HL,($5C5F) ; fetch adjusted workspace pointer from X_PTR | |
EX AF,AF' ; restore flags. |
;----------
Demonstração de uso:
LD HL,50
EXX ; HL' = 50
LD HL,25 ; HL = 25
EXX ; HL' = 25 e HL=50
Sem comentários:
Enviar um comentário