segunda-feira, 7 de dezembro de 2020

Manual do Hot Asm

 Digitalização de uma cópia da cópia do manual do Hot Asm (Hot Assembler). 

A data que tenho anotada no rodapé da encadernação improvisada é de 9/11/1987!

Arquivo em PDF disponível no Dropbox


sexta-feira, 14 de junho de 2019

Atualizando um post antigo sobre o Paddle Vaus

Quando analisei há um tempo atrás a rotina de leitura do Paddle Vaus pelo jogo Arkanoid deixei passar batido um detalhe: O bit mais significativo da leitura já está na entrada "up" assim que a termina a conversão/contagem do circuito do paddle

Os 9 bits são lidos da seguinte maneira:

  • Lê registro 14 do PSG e salva em H

  • Repete 8 vezes:
    • gera um pulso de clock para deslocar 1 bit
    • lê o bit e salva em C
  • Salva o conteúdo de C para o endereço 0xEOC1
  • Isola o bit 0 de H, que é o bit mais significativo da leitura e salva em 0xE0C2
...
42fc 3e0e      ld      a,0eh       ; seleciona registro 14 do PSG
42fe d3a0      out     (0a0h),a
4300 dba2      in      a,(0a2h)    ; realiza primeira leitura
4302 67        ld      h,a         ; bit mais significativo já esta na saida
4303 0608      ld      b,08h       ; 8 bits
4305 0e00      ld      c,00h
4307 1e00      ld      e,00h
4309 3e0f      ld      a,0fh
430b d3a0      out     (0a0h),a
430d 3e1e      ld      a,1eh
430f d3a1      out     (0a1h),a    ; clock low
4311 3e1f      ld      a,1fh
4313 d3a1      out     (0a1h),a    ; clock high
4315 3e0e      ld      a,0eh
4317 d3a0      out     (0a0h),a
4319 dba2      in      a,(0a2h)
431b 5f        ld      e,a
431c cb3f      srl     a           ; lê bit
431e cb11      rl      c           ; armazena em C
4320 10e7      djnz    4309h       ; próximo bit
4322 79        ld      a,c
4323 32c1e0    ld      (0e0c1h),a  ; armazena bits menos significativos
4326 7c        ld      a,h         ; pega primeira leitura
4327 e601      and     01h         ; isola bit 0 (up)
4329 32c2e0    ld      (0e0c2h),a  ; armazena bit mais significativo
 

432c 3e0f      ld      a,0fh       ; gera um pulso para iniciar
432e d3a0      out     (0a0h),a    ; a próxima conversão/contagem
4330 3e1f      ld      a,1fh
4332 d3a1      out     (0a1h),a    ; pino8 high
4334 3e0f      ld      a,0fh
4336 d3a1      out     (0a1h),a    ; pino8 low
4338 3e1f      ld      a,1fh
433a d3a1      out     (0a1h),a    ; pino8 high
433c 3e0e      ld      a,0eh
433e d3a0      out     (0a0h),a
4340 dba2      in      a,(0a2h)
4342 5f        ld      e,a
4343 21c4e0    ld      hl,0e0c4h
4346 7e        ld      a,(hl)
4347 73        ld      (hl),e
4348 e60f      and     0fh
434a a3        and     e
434b ab        xor     e
434c 32c5e0    ld      (0e0c5h),a
434f 47        ld      b,a
4350 3a0be0    ld      a,(0e00bh)
4353 b7        or      a
4354 c0        ret     nz

4355 cb48      bit     1,b         ; Testa botão de tiro
4357 c8        ret     z           ; bit 1 -> DOWN do reg 14

4358 3a0ae0    ld      a,(0e00ah)
435b b7        or      a
435c ca7043    jp      z,4370h
435f af        xor     a
4360 320ae0    ld      (0e00ah),a
4363 213ce5    ld      hl,0e53ch
4366 113de5    ld      de,0e53dh
4369 3600      ld      (hl),00h
436b 010700    ld      bc,0007h
436e edb0      ldir
4370 3e01      ld      a,01h
4372 320ce0    ld      (0e00ch),a
4375 c9        ret

...



 


quinta-feira, 13 de junho de 2019

Diferentes versões de Arkanoid

Eu montei um clone do controle de Arkanoid e ao testar notei que o jogo não reconhecia o controle. Achei estranho pois me lembrava de ter visto o código e até "desassemblado" um trecho de uma ROM que gerava os sinais para ler o controle da Taito.
Clone do Paddle Arkanoid da TAITO

Pesquisando em alguns sites achei uma versão cujo binário era realmente era diferente, e que funcionou com o Paddle que montei.

Arkanoid 1 (1986) (Taito) (J).rom

Comparando com mais detalhes as duas versões dá pra ver que a ROM em que o Paddle não funciona chama apenas a rotina de leitura de teclado (0x425b - CD 0141H) ao passo em que a outra ROM chama uma função no endereço 0x42FD que é justamente responsável por gerar os sinais e ler os dados vindos do paddle (vide artigo anterior)



Além disso existe uma diferença "visual" entre as ROMS. A que lê o Paddle coloca na tela a mensagem TAITO CORPORATION. Já a ROM que não lê o paddle escreve TAITO IMAGINE LTD.










A última difereça é o último byte do arquivo, que em uma versão tem o valor 0x00 e na outra 0x3F

sábado, 8 de junho de 2019

Diagrama redesenhado do Modulador de RF do Hotbit

Redesenhei o diagrama do modulador de RF do Hotbit. Aproveitei o corrigi o diagrama da placa principal pois a alimentação que vai para o conector do modulador de RF é de 12Volts em vez de 5 Volts.

Arquivos disponíveis no github

quarta-feira, 6 de junho de 2018

BGM player

Subrotina em assembler para ser usada em jogos ou demos. Permite tocar uma trilha sonora de tons simples que pode ser gerada a partir de arquivos padrão RTTL.

A subrotina utiliza formato próprio, composto de 3 bytes, contendo duração da nota (1byte) e sua "frequência" (2 bytes).

duração      : [ 1 byte ]  1..255
"frequencia" : [---lsb--][0000-msb]  0..4095



A subrotina não é blocante e deve ser chamada a cada interrupção do VDP. Por isso a duração corresponde a intervalos de tempo múltiplos de 16.67ms (1/60Hz) ou de 20ms (1/50Hz) conforme o padrão da máquina.

A "frequência" corresponde ao divisor de clock que deve ser carregado nos registros de divisão do PSG (12 bits).

Uma nota com duração igual a 0 (zero) corresponde a um comando, dessa forma

duração: [ 0 ]  Comando
         [ccccrrrr][dddddddd]  

         cccc comando 0..15  
         rrrr argumento 0..15
         dddddddd dado 0..255

Até o momento três comandos estão definidos:

cccc = 0, : Reinicializa música
rrrr, dddddddd sem uso
                                  
cccc = 1,  : Escreve num registro do PSG
rrrr = registro [0..15]
dddddddd = dado [0..255] valor a ser escrito.


cccc = 2,  : Escreve num registro do PSG 
             e interpreta proximo comando ainda no mesm
             intervalo de tmepo
rrrr = registro [0..15]
dddddddd = dado [0..255] valor a ser escrito.

                                  
A geração das músicas a partir de "Ringtones" no formato RTTL pode ser feita utilizando um script python que permite inclusive que as músicas sejam ouvidas (pelo menos na versão windows)

Alguns detalhes:
Um valor de divisor para geração da frequência igual a 0 faz com que o canal do PSG fique mudo e isso é usado para gerar a pausa. Em nenhuma das referências que consultei havia essa informação.

O valor máximo de duração de uma nota é por volta de 4.3 segundos. Para gerar notas de maior duração o script gera uma segunda nota de mesma frequencia com o valor de duração excedente.

Códigos fonte e demais arquivos disponíveis no repositório do GitHub mas também tem uma imagem de disco na página do projeto no Hackaday.io que dá pra testar no WebMSX


segunda-feira, 21 de maio de 2018

Diagrama redesenhado da placa CPU do HOTBIT

Desenhei este diagrama nas férias do início do ano, mas só agora me lembrei de postar. Ele foi baseado num diagrama que achei no site do Luciano (MSXPRO).

A título de curiosidade este diagrama foi editado num netbook Asus EEE 1005HA com tela de 1024x600

O circuito está disponível nos formatos PDF e Eagle (versão >=6.0) em meu repositório de MSX do Github
https://github.com/Danjovic/MSX/raw/master/Schematics/HOTBIT%20HB8000/HotBit.pdf

segunda-feira, 19 de dezembro de 2016

Nova versão do Joy232

Nova versão do Joy232, que é um programa que intercepta os caraceteres enviados para a impressora e os transmite serialmente pela porta de joystick.

Novidades desta versão (1.3):
  • Código reescrito e otimizado de forma a  caber 64 bytes da fila da RS232 que não é usada no MSX, e portanto não vai ser sobrescrito por outro programa
  • Suporta 14400 bauds (além de 1200,2400,4800,9600 e 19200 bauds)
  • Permite transmitir sem paridade (N) ou com paridade par (E) e ímpar (O)
Mais detalhes na página do projeto no https://hackaday.io/project/18552-joy232



Meus agradecimentos ao Fábio Belavenuto pela SD Mapper! Tem me ajudado pra caramba!!!

E para os apressados:
10 REM
20 REM Joy232 hook code
30 REM danjovic 2016
40 REM version 1.31 19/12/2016
50 REM
60 EI=&HFAF5:SIZE=63
70 FOR A = EI TO EI+SIZE
80 READ B$: POKE A,VAL("&H"+B$)
90 NEXT A
100 REM
110 POKE &HFFB8,&HFA
120 POKE &HFFB7,&HF5
130 POKE &HFFB6,&HC3
140 REM
150 DATA F3,F5,C5,E5,6F,3E,0F,D3
160 DATA A0,26,FF,A7,CB,15,CB,14
170 DATA 06,0B,DB,A2,CB,87,CB,1C
180 DATA CB,1D,CE,00,D3,A1,0E,11
190 DATA 0D,20,FD,10,ED,E1,C1,F1
200 DATA A7,FB,33,33,C9,CE,00,D3
210 DATA A1,0E,06,0D,20,FD,10,ED
220 DATA E1,C1,F1,FB,33,33,C9,00
230 REM
240 REM To change baudrate
250 REM
260 REM POKE &HFB27,value
270 REM
280 REM Baudrate  value
290 REM 1200      170
300 REM 2400      83
310 REM 4800      39
320 REM 9600      17
330 REM 14400     10
340 REM 19200      6
350 REM
360 REM ----------------------
370 REM To use parity
380 REM
390 REM POKE &HF96D,value
400 REM
410 REM Parity    value
420 REM NONE        0 (or 1)
430 REM EVEN        2
440 REM ODD         3


 A conexão ao PC é feito na porta A de Joystick usando-se um adaptador ("dongle") USB-Serial.

segunda-feira, 5 de dezembro de 2016

domingo, 13 de março de 2016

MSX Includes

Arquivos para incluir em projetos de programas em assembly retirados do RED BOOK contendo:

  • Chamadas da Bios
  • Variáveis de Sistema
  • Hooks
Os arquivos estão disponíveis no meu GitHub

domingo, 29 de novembro de 2015

Convertendo jogos para uso com Paddles (5)

Pesquisa do(s) endereço(s) de memória que armazenam as coordenadas do personagem na tela

Recapitulando do artigo anterior, descobrimos que a função localizada no endereço 0x4f1c é responsável pela leitura dos comandos do jogador, seja via teclado ou via joystick. Também descobirmos que esta função recebe um parâmetro contido no registrador A.

Endereço: 0x4f1c

Função:   Le_controles

Entrada: A = 0xff -> Lê joystick 2 ou teclas 'Z' e 'C'
         A<> 0xff -> Lê joystick 1 ou setas direcionais

Retorno: A = Direção
         A = 
                7  1  3
                 \ | /
          (Z) 7 -- 0 -- 3 (C)
                 / | \      
                7  5  3
           
Agora precisamos rastrear os trechos do jogo que chamam e função 0x4f1c e ver o que acontece quando os valores 7 e 3 são retornados, o que corresponde aos comandos de 'esquerda' e 'direita' respectivamente.


Analisando a primeira chamada, a partir de 0x4cc3 temos que quando a chamada a 0x4f1c retorna 3, o endereço 0x4f03 é chamado

E quando a chamada a 0x4f1c retorna 7 o endereço 0x4f10 é chamado

Vamos então analisar estes dois endereços:


O que encontramos nesta chamada é um bom indício de que estamos perto, pois ambas as chamadas limitam o valor da variável contida em 0xd010. Para a direita o valor é limitado a 100 (0x64 em hexadecimal). Se o valor for menor do que 100 então o conteúdo da posição de memória em 0xd010 é incrementado. Já para a esquerda o valor é limitado a 10 (0x0A).

Em ambos os casos, caso a posição em oxd010 seja alterada a função salta para 0x4ddc. Vamos ver o que tem lá:


Em 0x4ddc acontece o seguinte:
- A posição em 0xd012 é incrementada com módulo 2. Isso talvez sirva para comandar o sprite do personagem conforme ele se movimenta, mas por enquanto não importa.
- A posição de memória em 0xd015 é zerada. Isso pode ser um flag ou algo assim.

Vamos voltar um pouco e retomar a pista do endereço de memória 0xd010 e ver onde este endereço é usado e como é usado:

Bom, este endereço é utilizado em 18 lugares! São dezesseis lugares a mais para pesquisar (dois nós já vimos). Isso fica para o próximo artigo.







sábado, 28 de novembro de 2015

Convertendo jogos para uso com Paddles (4)

Pesquisa das funções que fazem a leitura do teclado / joysticks (continuação)

Começamos nossa análise ao redor dos endereços onde a função GTSTK (Get Stick) é chamada.

    Line 2043: 4f37 cdd500    call    00d5h
    Line 2058: 4f49 cdd500    call    00d5h
    Line 2061: 4f4f cdd500    call    00d5h
    Line 4602: 6214 cdd500    call    00d5h


O objetivo é rastrear as referências a esta chamada. Queremos saber se a leitura do Joystick é feita no meio do loop do jogo, ou se é chamada a partir dele. Devemos seguir o código para trás e para a frente até chegar a um bloco estanque. No caso temos todo o bloco compreendido entre os endereços 0x4f1c e 0x4f5e.



Pesquisando então pelo endereço 0x4f10 achamos quatro chamadas:


 Precisamos analisar esta função e ver o que ela recebe de entrada e o que retorna de saída. As primeiras instruções mostram que se o registrador A for igual a 0xFF na entrada, a função desvia para 0x4f48.

Analisando a primeira parte da função (chamada com A!=255), vemos que a matriz de teclado também é lida (função SNSMAT - 0141h) pesquisando-se as teclas 'C' (row 3 bit 0)  e 'Z' (row 5 bit 7)

4f1f 3e05      ld      a,05h
4f21 cd4101    call    0141h
4f24 1607      ld      d,07h
4f26 cb7f      bit     7,a       Testa 'Z'
4f28 3e07      ld      a,07h     Retorna 7 (esquerda)
4f2a c8        ret     z

4f2b 3e03      ld      a,03h
4f2d cd4101    call    0141h
4f30 cb47      bit     0,a       Testa 'C'
4f32 3e03      ld      a,03h     Retorna 3 (direita)
4f34 c8        ret     z


Caso nenhuma destas teclas esteja pressionada, a rotina lê o Joystick 2. Caso o joystick 2 esteja em repouso, ou na posição 1 (cima) ou na posição 5 (baixo) a função retorna. Por outro lado, se o joystick estiver nas posições 2,3,4 (direita e diagonais) a função retorna o valor '3' (direita). Analogamente, se a posição for superior a 5 (6,7,8 - esquerda e diagonais) a função retorna o valor '7' (esquerda).

4f35 3e02      ld      a,02h
4f37 cdd500    call    00d5h
4f3a fe02      cp      02h              retorna se menor que 2
4f3c d8        ret     c

4f3d fe05      cp      05h              retorna se igual a 5
4f3f c8        ret     z

4f40 3803      jr      c,4f45h          ; (+03h)
4f42 3e07      ld      a,07h            retorna 7 (esquerda)
4f44 c9        ret

4f45 3e03      ld      a,03h            retorna 3 (direita)
4f47 c9        ret


Os valores 3 e 7 correspondem às posições direita e esquerda, respectivamente que são os mesmos que a função GTSTK retorna quando o joystick é acionado para a esquerda ou a direita.


Já o outro trecho de código lê o teclado e o joystick 1 e também retorna 3 ou 7 caso um destes dois dispositivos esteja nas posições direita/diagonais-direita ou esquerda/diagonais-esquerda.

4f45 3e03      ld      a,03h         Retorna 3 (direita)
4f47 c9        ret

4f48 af        xor     a             A=0, Direcionais teclado
4f49 cdd500    call    00d5h
4f4c f5        push    af
4f4d 3e01      ld      a,01h         A=1, Joystick 1
4f4f cdd500    call    00d5h
4f52 c1        pop     bc
4f53 b0        or      b
4f54 fe02      cp      02h
4f56 d8        ret     c

4f57 fe05      cp      05h
4f59 c8        ret     z

4f5a 38e9      jr      c,4f45h          ; (-17h)
4f5c 3e07      ld      a,07h         Retorna 7 (esquerda)
4f5e c9        ret



Este trecho inteiro é candidato a local para se instalar os patches, mas agora é preciso descobrir como o jogo transforma o resultado dos controles direcionais em coordenadas da personagem, que é o tema do próximo artigo.


Convertendo jogos para uso com Paddles (3)

Pesquisa das funções que fazem leitura do teclado / joysticks

O MSX só tem duas vias para comandos do usuário:  O Teclado e as Portas de Joystick. Sendo assim todos os jogos necessariamente têm que acessar estas vias. Para isso o jogo pode usar as rotinas da BIOS (recomendado) ou ler diretamente as portas de I/O. Para cada jogo precisamos descobrir o método ou os métodos utilizados.

Comecemos pelas rotinas da BIOS. Segundo o Livro Vermelho, temos:

ADDR. NAME   TO    FUNCTION
------------------------------------------------

00D5H GTSTCK 11EEH Get joystick status
00D8H GTTRIG 1253H Get trigger status

00DEH GTPDL  1273H Get paddle status
0141H SNSMAT 1452H Read row of keyboard matrix

A primeira rotina a ser procurada é a GTPDL (00DEH). Se o jogo a utiliza nosso trabalho está concluído. Mas infelizmente para o Penguin Wars ainda não foi dessa vez.


A próxima é a GTSTK (00d5h). Esta retornou em 4 endereços.

Em seguida leremos GTTRIG (00d8h). Também é chamada em 4 locais.

Por último SNSMAT (0141h). Novamente, a função é chamada 4 vezes
Estes endereços serão o ponto de partida para a pesquisa das funções que guardam a posição da personagem na tela. 

quarta-feira, 25 de novembro de 2015

Convertendo jogos para uso com Paddles (2)

Disassembly do Jogo

Existem várias ferramentas para desassemblar código de Z80, mas eu gosto de usar o DZ80. O jogo que eu escolhi para adaptar foi o Penguin Wars. A ROM de MSX deste jogo tem 32Kbytes e as configurações para o disassembly ficam como na figura abaixo:


Se tudo estiver certo, a listagem em assembly gerada deve começar no endereço 0x4000 e os dois primeiros caracteres devem ser 0x41 e 0x42






Convertendo jogos para uso com Paddles

Apesar do padrão MSX estabelecer um padrão para Paddles e tanto a BIOS quanto o BASIC terem suporte a eles, nenhum jogo que eu tenha notícia os utiliza. O único jogo que utiliza Paddles é o Arkanoid, porém este utiliza um padrão próprio, em vez de usar o padrão nativo.

Pois bem, a mecânica de jogo de alguns títulos utiliza somente movimentos laterais e são ótimos candidatos a adaptações para uso de Paddles. Um exemplo é o Galaga.

Lá pelos idos de 1990 eu construí um Paddle para o MSX seguindo as especificações do Livro Vermelho do MSX. Na falta de jogos que o utilizassem eu consegui desassemblar justamente o Galaga de forma a convertê-lo para o uso de Paddles. Naquela época eu ainda usava fitas cassete e tinha que me utilizar de programas que eu mesmo escrevia de forma a poder fazer a adaptação. Como todo o processo era muito trabalhoso eu nunca me aventurei a converter nenhum outro jogo. Hoje em dia com emuladores, desassembladores, etc esta tarefa é um pouco mais facilitada mas mesmo assim não é trivial, uma vez que cada jogo, mesmo da mesma desenvolvedora, funciona de maneira diferente na hora de ler as interfaces com o usuário (teclado, joysticks).

Mas de uma maneira geral a adaptação segue os seguintes passos:

- Disassembly do jogo
- pesquisa das funções que fazem leitura do teclado / joysticks
- pesquisa do(s) endereço(s) de memória que armazenam as coordenadas do personagem na tela
- Inclusão das chamadas de leitura do paddle em substituição às funções de tratamento de teclado e mouse.
- criação de um arquivo de 'patch' para carregamento do jogo com ou sem a modificação.



segunda-feira, 20 de julho de 2015

Paddle 2 botões

Para complementar um antigo post, segue abaixo link para uma placa de circuito impresso para um Paddle padrão MSX com 2 botões, projetado especificamente para a caixa CR-096. O projeto dessa placa com dois botões era de 2007, mas ainda baseado no circuito de 1992, que não tinha o resistor em série com o potenciômetro.
Layout da placa feito em 2007

Dei uma incrementada no circuito, adicionando o resistor em série com o potenciômetro, um resistor de base para assegurar o corte do transistor e um LED para indicar o funcionamento.

Novo diagrama do "Paddle" de 2 botões.

 
Por causa das mudanças dei uma melhorada no layout da placa.
Novo "layout" da placa.
Cabe notar que os 2 "microswitches" bem como o potenciômetro e o LED devem ser montados na face da solda.
Led, Botões e potenciômetro montados do lado das soldas.

Link do dropbox contendo os arquivos.


terça-feira, 23 de junho de 2015

Cartão MSX Add-on para placa DE-1

MSX DE-1add on card baseada no projeto do Caro, cujo layout já estava pronto há algum tempo porém estava faltando oportunidade de construir a placa. 



Diagrama:


Placa de circuito impresso em face simples:

Placa em ação:

terça-feira, 28 de abril de 2015

Teclas do PV-16 - Versão final

As teclas do PV-16 na sua versão definitiva foram impressos usando plástico verde-limão com as inscrições em baixo relevo.

Seguem abaixo as fotos:






sábado, 18 de abril de 2015

Mais ensaisos para as Teclas do PV-16

Agora está bem próximo! Faltam poucos ajustes e já dá para imprimir na cor final.


terça-feira, 14 de abril de 2015

Teclas impressas para o PV-16

Um amigo meu está me ajudando a substituir as teclas que vieram faltando no PV-16 por peças impressas em 3d.

Os primeiros ensaios já foram promissores:


Funcionalmente o teclado já poderia ficar com as duas teclas protótipo, porém vamos tentar imprimir as peças com um pouco de sobra de material para poder lixar e melhorar o acabamento, bem como colocar alguns detalhes em baixo relevo.


sábado, 11 de abril de 2015

Logotipo 3D do MSX

Fiz um logotipo 3D do MSX no sketchup e estou disponibilizando no meu dropbox. Eu ia colocar no 3D warehouse mas desisti devido à atual política xereta da Trimble (que comprou o sketchup)