Mudanças entre as edições de "AnotherWorld JAMMA"

De Garoa Hacker Clube
Ir para navegação Ir para pesquisar
(Criou página com '== Relógio Central == '''Função:''' Gerar o sinal de clock para a CPU e para os circuitos de geração de vídeo '''implementação:''' (pendente) == CPU == === Unidad...')
 
 
(24 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
  +
Esta página contém rascunhos da concepção do projeto de uma placa JAMMA para o jogo Another World.
  +
Este projeto está sendo desenvolvido ao longo de uma atividade semanal no Garoa chamada [[CPU do Zero]]. Todo o projeto será implementado como hardware livre (com os esquemáticos distribuidos sob a licença livre '''CERN Open Hardware License v1.2''').
  +
  +
* os esquemáticos estão sendo projetados usando o software KICAD
  +
* os arquivos estão sendo publicados no GitHub em https://github.com/felipesanches/AnotherWorld_JAMMA
  +
* as tarefas pendentes deste projeto estão sendo monitoradas neste bugtracker: https://github.com/felipesanches/mame/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20anotherworld
  +
* o código fonte de protótipo via emulação está sendo desenvolvido em: https://github.com/felipesanches/mame/tree/anotherworld
  +
  +
 
== Relógio Central ==
 
== Relógio Central ==
   
 
'''Função:''' Gerar o sinal de clock para a CPU e para os circuitos de geração de vídeo
 
'''Função:''' Gerar o sinal de clock para a CPU e para os circuitos de geração de vídeo
 
'''implementação:''' (pendente)
 
'''implementação:''' (pendente)
  +
  +
  +
Possivelmente implementaremos um oscilador com porta NAND, capacitor e resistor. Mas talvez façamos um upgrade prum oscilador com cristal.
  +
Precisaremos também ter um divisor de clock para gerar todas as frequencias necessárias para o sistema (unidade de controle, vídeo, som, etc).
   
 
== CPU ==
 
== CPU ==
Linha 13: Linha 26:
 
Sugestão:
 
Sugestão:
   
Como o instruction set da VM é muito simples e tem opcodes com valores incrementais de 0x00 a 0x1A (mais um par de instruções especiais em 0x80 e 0x40) é possível implementar trivialmente um decoder por meio do uso de um decodificador de 5 bits para 32 linhas
+
Como o instruction set da VM é muito simples e tem opcodes com valores incrementais de 0x00 a 0x1A (mais um par de instruções especiais em 0x80 e 0x40) é possível implementar trivialmente um decoder por meio do uso de um decodificador de 5 bits para 32 linhas. Isso pode ser implementado usando 2 decoders de 4 bits para 16 linhas como o [http://www.nxp.com/documents/data_sheet/74HC_HCT154.pdf 74154].
  +
  +
As duas instruções especiais (que são relativas a renderização de video) podem ser decodificadas com algumas poucas portas NAND com dados vindo dos bits 6 e 7 do registrador de instrução.
  +
  +
==== Instruction Set ====
  +
  +
Segue abaixo uma listagem de todas as instruções e seus respectivos opcodes
  +
  +
{| class="wikitable"
  +
|+ Another World VM instruction set
  +
|-
  +
| 0x00
  +
| movConst
  +
| varID
  +
| const H
  +
| const L
  +
|
  +
|
  +
|
  +
| [varID] <= const
  +
|-
  +
| 0x01
  +
| mov
  +
| dst
  +
| src
  +
|
  +
|
  +
|
  +
|
  +
| [dst] <= [src]
  +
|-
  +
| 0x02
  +
| add
  +
| dst
  +
| src
  +
|
  +
|
  +
|
  +
|
  +
| [dst] <= [src] + [dst]
  +
|-
  +
| 0x03
  +
| addConst
  +
| varID
  +
| value
  +
|
  +
|
  +
|
  +
|
  +
| [varID] <= [varID] + value
  +
|-
  +
| 0x04
  +
| call
  +
| addr H
  +
| addr L
  +
|
  +
|
  +
|
  +
|
  +
| stack->push(PC); PC = addr
  +
|-
  +
| 0x05
  +
| ret
  +
|
  +
|
  +
|
  +
|
  +
|
  +
|
  +
| PC = m_stack->pop()
  +
|-
  +
| 0x06
  +
| Break / "pauseThread"
  +
|
  +
|
  +
|
  +
|
  +
|
  +
|
  +
| Temporarily stops the executing channel and goes to the next.
  +
|-
  +
| 0x07
  +
| jmp
  +
| addr H
  +
| addr L
  +
|
  +
|
  +
|
  +
|
  +
| PC <= addr
  +
|-
  +
| 0x08
  +
| Setvec
  +
| channelID
  +
| addr H
  +
| addr L
  +
|
  +
|
  +
|
  +
| Initialises a channel (thread) with a code address to execute
  +
|-
  +
| 0x09
  +
| djnz
  +
| varID
  +
| addr H
  +
| addr L
  +
|
  +
|
  +
|
  +
| '''D'''ecrement variable value and '''J'''ump to address if value is '''N'''ot '''Z'''ero
  +
|-
  +
| 0x0A
  +
| Conditional Jump instructions
  +
| subopcode
  +
| varID
  +
| value
  +
|
  +
|
  +
|
  +
| JZ, JNZ, JG, JGE, JL, JLE
  +
|-
  +
| 0x0B
  +
| setPalette
  +
| palID H
  +
| palID L
  +
|
  +
|
  +
|
  +
|
  +
| selects current palette
  +
|-
  +
| 0x0C
  +
| updateChannel
  +
| first
  +
| last
  +
| type
  +
|
  +
|
  +
|
  +
| Freeze (0), unfreeze (1) or delete(2) a range of channels.
  +
|-
  +
| 0x0D
  +
| selectVideoPage
  +
| bufferID
  +
|
  +
|
  +
|
  +
|
  +
|
  +
| selects the current video page
  +
|-
  +
| 0x0E
  +
| fillVideoPage
  +
| pageID
  +
| color
  +
|
  +
|
  +
|
  +
|
  +
| fills a video page with a solid color
  +
|-
  +
| 0x0F
  +
| copyVideoPage
  +
| srcPageID
  +
| dstPageID
  +
|
  +
|
  +
|
  +
|
  +
| copies the contents of a video page to another one
  +
|-
  +
| 0x10
  +
| blitFramebuffer
  +
| pageID
  +
|
  +
|
  +
|
  +
|
  +
|
  +
| updates display with the contents of the specified video page
  +
|-
  +
| 0x11
  +
| killChannel / "killThread"
  +
|
  +
|
  +
|
  +
|
  +
|
  +
|
  +
| stops running and deactivates the current channel
  +
|-
  +
| 0x12
  +
| Text
  +
| stringID H
  +
| stringID L
  +
| x
  +
| y
  +
| color
  +
|
  +
| Displays in the work screen the specified text for the coordinates x,y.
  +
|-
  +
| 0x13
  +
| sub
  +
| A
  +
| B
  +
|
  +
|
  +
|
  +
|
  +
| Subtract: [A] <= [A] - [B]
  +
|-
  +
| 0x14
  +
| and
  +
| A
  +
| B
  +
|
  +
|
  +
|
  +
|
  +
| Boolean AND: [A]&nbsp;<=&nbsp;[A]&nbsp;&&nbsp;[B]
  +
|-
  +
| 0x15
  +
| or
  +
| A
  +
| B
  +
|
  +
|
  +
|
  +
|
  +
| Boolean OR: [A]&nbsp;<=&nbsp;[A]&nbsp;&#124;&nbsp;[B]
  +
|-
  +
| 0x16
  +
| shl
  +
| varID
  +
| value H
  +
| value L
  +
|
  +
|
  +
|
  +
| Shift Left: [varID] <= [varID] << value
  +
|-
  +
| 0x17
  +
| shr
  +
| varID
  +
| value H
  +
| value L
  +
|
  +
|
  +
|
  +
| Shift Right: [varID] <= [varID] >> value
  +
|-
  +
| 0x18
  +
| play / "playSound"
  +
| resourceID H
  +
| resourceID L
  +
| freq
  +
| vol
  +
| channel
  +
|
  +
| parameters: resourceId, freq, vol, channel
  +
|-
  +
| 0x19
  +
| load / "updateMemList"
  +
| resourceID H
  +
| resourceID L
  +
|
  +
|
  +
|
  +
|
  +
| bank-switching de recursos (paletas, bytecode, polígonos, etc)
  +
|-
  +
| 0x1A
  +
| song / "playMusic"
  +
| resourceID H
  +
| resourceID L
  +
| delay H
  +
| delay L
  +
| pos
  +
|
  +
| parameters: resourceID, delay, pos
  +
|-
  +
| 0x40-0x7F
  +
| video
  +
| offset H
  +
| offset L
  +
| x
  +
| <etc>
  +
|
  +
|
  +
| renderização de polígonos
  +
|-
  +
| 0x80-0xFF
  +
| video (opcode contains 7-bit offset H)
  +
| offset L
  +
| x
  +
| y
  +
|
  +
|
  +
|
  +
| renderização de polígonos
  +
|-
  +
|}
   
 
=== Unidade de Controle - Microcódigo ===
 
=== Unidade de Controle - Microcódigo ===
Linha 24: Linha 338:
 
'''Função:''' Elementos passivos que implementam os registradores internos da CPU, Pilha e memória
 
'''Função:''' Elementos passivos que implementam os registradores internos da CPU, Pilha e memória
 
'''implementação:''' (pendente)
 
'''implementação:''' (pendente)
  +
  +
==== STACK ====
  +
  +
A VM possui uma pilha de 256 elementos de 16 bits cada. Pensei em implementar isso com [http://www.ti.com/lit/ds/symlink/sn74als870.pdf register files], mas não achei um grande o suficiente pra isso. O Mais próximo que achei foi [http://www.datasheetarchive.com/dlmain/Datasheets-112/DSAP0044877.pdf esse] que tem 64 elementos de 40 bits cada. Mesmo assim teria que ter 4 desses, sobrariam bits não usados e não sei o quão fácil é achar desse chip. Talvez seja o caso de usar uma RAM estática, mesmo que as menores disponíveis já sejam muito maiores que o realmente necessário aqui.
   
 
== Sistema de áudio ==
 
== Sistema de áudio ==
   
 
'''Função:''' Tocar 4 canais simultaneos de áudio com base em samples armazenados em ROMs
 
'''Função:''' Tocar 4 canais simultaneos de áudio com base em samples armazenados em ROMs
'''implementação:''' Estamos estudando a possibilidade de usar um chip MSM6295
+
'''implementação:''' Estamos estudando a possibilidade de usar um chip MSM6295 ou um chip Amiga Paula. Ver issue no github: https://github.com/felipesanches/mame/issues/10
   
 
== Sistema de vídeo ==
 
== Sistema de vídeo ==
Linha 34: Linha 352:
 
'''Função:''' Gerar sinal de vídeo para os pinos do conector JAMMA com base em rotinas de rasterização dos elementos poligonais armazenados em ROMs
 
'''Função:''' Gerar sinal de vídeo para os pinos do conector JAMMA com base em rotinas de rasterização dos elementos poligonais armazenados em ROMs
 
'''implementação:''' (pendente)
 
'''implementação:''' (pendente)
  +
  +
==== rasterização ====
  +
  +
'''Resolução: ''' 320x200 pixels x 16 cores sendo a paleta selecionada dentre 64 opções de paletas
  +
  +
TO-DO:
  +
  +
'''Passo 1:''' Esturar o algoritmo de rasterização com base no código fonte da [https://github.com/felipesanches/Another-World-Bytecode-Interpreter/blob/master/video.cpp reimplementação livre] da VM.
  +
  +
'''Passo 2:''' Implementar uma máquina de estados equivalente
  +
  +
'''Passo 3:''' Estágio de saída (paleta de cores) Implementar bank-switching para alternação de paletas de cores. E projetar conversor digital-analógico para os 3 canais de cores. Precisaremos de ROMs pequenas para armazenar as paletas de cores. Placas de arcade usam ROMs OTP (one-time-programmable) como a [http://www.datasheets360.com/pdf/3753113081012339967 HM-7611] usada no jogo 1984 (ver a página "COLOR MIXER" do esquemático nesse [http://www.jammarcade.net/files/Schematics/Arcade/1943.pdf PDF])
  +
  +
'''Passo 4:''' Realizar em portas lógicas e montar em protoboard ou PCB e testar
  +
  +
== Ver também ==
  +
  +
* [https://twitter.com/juca_gnu/status/686597622417719296 Tweet de 11/JAN/2016] "Emulating Eric Chahi's Another World at the bytecode level with my custom MAME fork #gamedev"
  +
* [https://twitter.com/juca_gnu/status/762719829035982848 Tweet de 08/AGO/2016] "Control unit signals sequencer configured by a set of microcode ROMs #weekendproject #anotherworld #JAMMA #CPU #hack"

Edição atual tal como às 14h59min de 29 de maio de 2017

Esta página contém rascunhos da concepção do projeto de uma placa JAMMA para o jogo Another World. Este projeto está sendo desenvolvido ao longo de uma atividade semanal no Garoa chamada CPU do Zero. Todo o projeto será implementado como hardware livre (com os esquemáticos distribuidos sob a licença livre CERN Open Hardware License v1.2).


Relógio Central

Função: Gerar o sinal de clock para a CPU e para os circuitos de geração de vídeo
implementação: (pendente)


Possivelmente implementaremos um oscilador com porta NAND, capacitor e resistor. Mas talvez façamos um upgrade prum oscilador com cristal. Precisaremos também ter um divisor de clock para gerar todas as frequencias necessárias para o sistema (unidade de controle, vídeo, som, etc).

CPU

Unidade de Controle - Decodificador de Instrução

Função: Detectar qual instrução o processador precisa executar com base no valor do código de instrução atual
implementação: (pendente)

Sugestão:

Como o instruction set da VM é muito simples e tem opcodes com valores incrementais de 0x00 a 0x1A (mais um par de instruções especiais em 0x80 e 0x40) é possível implementar trivialmente um decoder por meio do uso de um decodificador de 5 bits para 32 linhas. Isso pode ser implementado usando 2 decoders de 4 bits para 16 linhas como o 74154.

As duas instruções especiais (que são relativas a renderização de video) podem ser decodificadas com algumas poucas portas NAND com dados vindo dos bits 6 e 7 do registrador de instrução.

Instruction Set

Segue abaixo uma listagem de todas as instruções e seus respectivos opcodes

Another World VM instruction set
0x00 movConst varID const H const L [varID] <= const
0x01 mov dst src [dst] <= [src]
0x02 add dst src [dst] <= [src] + [dst]
0x03 addConst varID value [varID] <= [varID] + value
0x04 call addr H addr L stack->push(PC); PC = addr
0x05 ret PC = m_stack->pop()
0x06 Break / "pauseThread" Temporarily stops the executing channel and goes to the next.
0x07 jmp addr H addr L PC <= addr
0x08 Setvec channelID addr H addr L Initialises a channel (thread) with a code address to execute
0x09 djnz varID addr H addr L Decrement variable value and Jump to address if value is Not Zero
0x0A Conditional Jump instructions subopcode varID value JZ, JNZ, JG, JGE, JL, JLE
0x0B setPalette palID H palID L selects current palette
0x0C updateChannel first last type Freeze (0), unfreeze (1) or delete(2) a range of channels.
0x0D selectVideoPage bufferID selects the current video page
0x0E fillVideoPage pageID color fills a video page with a solid color
0x0F copyVideoPage srcPageID dstPageID copies the contents of a video page to another one
0x10 blitFramebuffer pageID updates display with the contents of the specified video page
0x11 killChannel / "killThread" stops running and deactivates the current channel
0x12 Text stringID H stringID L x y color Displays in the work screen the specified text for the coordinates x,y.
0x13 sub A B Subtract: [A] <= [A] - [B]
0x14 and A B Boolean AND: [A] <= [A] & [B]
0x15 or A B Boolean OR: [A] <= [A] | [B]
0x16 shl varID value H value L Shift Left: [varID] <= [varID] << value
0x17 shr varID value H value L Shift Right: [varID] <= [varID] >> value
0x18 play / "playSound" resourceID H resourceID L freq vol channel parameters: resourceId, freq, vol, channel
0x19 load / "updateMemList" resourceID H resourceID L bank-switching de recursos (paletas, bytecode, polígonos, etc)
0x1A song / "playMusic" resourceID H resourceID L delay H delay L pos parameters: resourceID, delay, pos
0x40-0x7F video offset H offset L x <etc> renderização de polígonos
0x80-0xFF video (opcode contains 7-bit offset H) offset L x y renderização de polígonos

Unidade de Controle - Microcódigo

Função: Implementa o comportamento de cada instrução por meio da geração de sinais de controle que manipulam o fluxo de dados
implementação: (pendente)

Fluxo de Dados

Função: Elementos passivos que implementam os registradores internos da CPU, Pilha e memória
implementação: (pendente)

STACK

A VM possui uma pilha de 256 elementos de 16 bits cada. Pensei em implementar isso com register files, mas não achei um grande o suficiente pra isso. O Mais próximo que achei foi esse que tem 64 elementos de 40 bits cada. Mesmo assim teria que ter 4 desses, sobrariam bits não usados e não sei o quão fácil é achar desse chip. Talvez seja o caso de usar uma RAM estática, mesmo que as menores disponíveis já sejam muito maiores que o realmente necessário aqui.

Sistema de áudio

Função: Tocar 4 canais simultaneos de áudio com base em samples armazenados em ROMs
implementação: Estamos estudando a possibilidade de usar um chip MSM6295 ou um chip Amiga Paula. Ver issue no github: https://github.com/felipesanches/mame/issues/10

Sistema de vídeo

Função: Gerar sinal de vídeo para os pinos do conector JAMMA com base em rotinas de rasterização dos elementos poligonais armazenados em ROMs
implementação: (pendente)

rasterização

Resolução:  320x200 pixels x 16 cores sendo a paleta selecionada dentre 64 opções de paletas

TO-DO:

Passo 1: Esturar o algoritmo de rasterização com base no código fonte da reimplementação livre da VM.

Passo 2: Implementar uma máquina de estados equivalente

Passo 3: Estágio de saída (paleta de cores) Implementar bank-switching para alternação de paletas de cores. E projetar conversor digital-analógico para os 3 canais de cores. Precisaremos de ROMs pequenas para armazenar as paletas de cores. Placas de arcade usam ROMs OTP (one-time-programmable) como a HM-7611 usada no jogo 1984 (ver a página "COLOR MIXER" do esquemático nesse PDF)

Passo 4: Realizar em portas lógicas e montar em protoboard ou PCB e testar

Ver também

  • Tweet de 11/JAN/2016 "Emulating Eric Chahi's Another World at the bytecode level with my custom MAME fork #gamedev"
  • Tweet de 08/AGO/2016 "Control unit signals sequencer configured by a set of microcode ROMs #weekendproject #anotherworld #JAMMA #CPU #hack"