A listagem abaixo contém o trecho exato da BIOS que lê os paddles. Os números marcados em azul / laranja correspondem à quantidade de ciclos de máquina que o Z80 leva para executar as instruções, já considerando o WAIT State inserido a cada ciclo M1 (padrão no MSX).
Para ler os paddles, o MSX gera um pulso no pino 8 e em seguida realiza uma contagem de tempo para ver quanto tempo o sinal do paddle permaneceu ativado. A contagem termina quando o sinal do paddle retorna a nível baixo, ou quando se atingem 255 contagens.
PDLP1:
128B LD A,PSG.PB
128D DI
128E CALL RDPSG ; get current port B content
1291 AND E
1292 OR D
1293 OR C
1294 12 OUT (PSG.DW),A ; set trigger high
1296 5 XOR C
1297 12 OUT (PSG.DW),A ; set trigger low again
1299 8 LD A,0EH
129B 12 OUT (PSG.LW),A
129D 8 LD C,0 ; initialize counter
PDL2:
129F 12 IN A,(PSG.DR)
12A1 5 AND B ; end of pulse?
12A2 13/8 JR Z,PDL3 ; yes
12A4 5 INC C ; bump counter
12A5 13/8 JP NZ,PDL2 ; no overflow yet
12A8 DEC C ; make it 255
PDL3:
12A9 EI
12AA LD A,C ; return counted value
12AB RET
Os números em azul são os ciclos gastos entre a subida do pulso de saída (pino 8 do conector de joystick) e a primeira leitura efetuada (para ser mais exato eu teria que reduzir os ciclos de clock referentes à busca e início da execução da instrução OUT que levanta o sinal de trigger, porém eu teria que acrescentar um tempo idêntico referente à primeira instrução IN do ciclo de leitura).
Num total são 57 ciclos, o que equivale a 15,92us num MSX rodando a 3,5795MHz. Se considerarmos apenas a borda de descida, são 17 ciclos a menos, o que resulta em 11,17us.
Os pulsos em laranja equivalem a uma contagem. Esta temporização já é velha conhecida pois consta no 'Livro Vermelho do MSX', mas como exercício não custa conferir.
Cada interação leva 43 ciclos, ou 12,01us (a 3,5795MHz). O tempo máximo para retornar da leitura do paddle é de 3,06ms (255 * 12,01us).
Com estes números em mente, surgem algumas idéias de emulação. Para isso eis um resumo do que se deve fazer:
- Responder a uma borda de subida no pino 8 do conector de joystick em até 15us (ou uma de descida em até 11us);
- Subir para nível alto o(s) pino(s) desejado(s) e mantê-los por um tempo entre 12us e 3ms;
- Ao final do tempo desejado, colocar o pino em nível baixo (ou mantê-lo em nível baixo por um tempo superior a uma iteração).
Nenhum comentário:
Postar um comentário