Postagens mais visitadas

Construindo uma interface I/O para o Mega Drive - Parte 3 Diagramas e Sinais

   Bom, essa é a terceira parte da nossa série...

  Os dois primeiros posts foram mais teóricos, então nesse pretendo ser bem mais pratico e ensinar a aplicar toda a teoria vista até aqui.

  Sabemos o básico sobre o funcionamento de um barramento de maneira genérica e vimos que no caso especifico do Mega Drive temos muitas facilidades que o projeto dele nos proporciona e é justamente desse ponto que vamos partir. Antes de tudo precisaremos dar uma olhada mais de perto na interface com a qual vamos nos comunicar.

  Por uma questão de comodidade estarei usando a porta de expansão (Expansion Port) que fica na lateral do console, a mesma na qual acoplamos o Sega CD, mas o mesmo principio pode ser aplicado para se comunicar através do Slot de Cartuchos, o que nos permite projetar uma interface de comunicação para um periférico externo acoplado a porta de expansão, ou então um hardware embarcado dentro de um cartucho.

  Hoje vamos aprender como fazer o circuito de saída, o de entrada fica para o próximo Post!

Vamos Começar...

  Antes de mais nada precisamos saber exatamente que sinais temos disponíveis na porta de Expansão e a qual pino corresponde cada sinal.

  Olhando de frente para a porta de expansão do Mega Drive temos essa configuração:



  Baseado nos diagramas e em umas pesquisas que eu fiz consegui identificar e descrever a pinagem da seguinte maneira:


[Eu não sei se essa tabela esta 100% correta (provavelmente não 😅 ), então caso tenha alguma informação adicional ou correção me comunique pelos comentários ou pelo Discord que eu atualizo o post]

  Se observarmos bem veremos que temos diversos sinais no nosso barramento de controle, especificamente 3 são os que nos interessam! O /UWR, o /LWR e o /FDWR!

  O /UWR e o /LWR controlam o tamanho do frame de dados que vamos gravar, quando movermos um valor de 8 Bits apenas o sinal /LWR sera acionado, quando o valor for de 16 Bits ambos os sinais serão acionados.

  Só lembrando que nesse caso, como tem essas barra "/" no nome do pino, significa que o estado dele de acionado é ZERO!

  O Sinal /FDWR como esta especificado na tabela, sera acionado sempre que tentarmos gravar um valor dentro do Range de endereços que vai de 0xA12000 até 0xA120FF, esse é o range de endereços que a Sega deixou "Pré-mapeado" para a gente, como vamos implementar apenas um registrador de saída de 16 Bits (por enquanto) não precisaremos verificar o barramento de endereços, apenas esse sinal, fornece toda a informação que precisamos! Isso significa que o nosso registrador sera "espelhado" em todo esse intervalo de memoria!

  Agora que ja temos os sinais que precisamos, temos que "construir" o nosso registrador, ele sera de 16 bits e sera a junção de dois registradores de 8 bits, sendo que o MSB sera controlado por um sinal e o LSB por outro sinal (o /LWR e /UWR lembram?).

  Um registrador nada mais é do que um arranjo de Flip-Flops D, então vou estar usando 2 C.I.'s 74373, mas qualquer outro Latch deve servir.

 Os Sinais /LWR e /UWR indicam quando os dados estão sendo escritos no Barramento, porem precisamos usar o sinal de /FDWR como "Gatilho", pois ele indica se esses dados estão direcionados para o endereço de Memoria do nosso registrador ou não.

  Tendo em mente que o sinal de acionado desses pinos é ZERO, e que o sinal de Latch Enable/Clk (Pino 11 do 74373) é acionado com UM, podemos montar as nossas tabelas da verdade, na primeira os sinais de entrada serão o par /LWR e /FDWR e o sinal de saída sera o LD_LE (Low Data Latch Enable), a segunda tabela sera idêntica a primeira, porem para os sinais de Upper Data:  



  Um bom observador pode notar que a equação Booleana dessa tabela é bem simples, basicamente é só inverter os sinais de entrada e injetar-los em uma porta AND.

  Um excelente observador deve ter notado que uma porta AND com todas as entrada invertidas na verdade é uma porta NOR!

  Isso significa que podemos implementar nossa Interface usando apenas 1 Latch de 16 bits e duas portas NOR!

  Como eu não tinha nenhuma porta NOR no meu estoque de componentes eu projetei o circuito usando portas AND e NOT mesmo, então bolei esse diagrama:


  Como não queria ficar só na teoria eu então tratei de pegar uma placa perfurada universal, um slot ISA de uma placa mãe de PC antiga (que encaixa bem na porta de expansão do Mega Drive) e montei o circuito na pratica!

  Para testar ele escrevi um programar simples no NextBasic (o NextBasic é um compilador para o Mega Drive que eu mesmo desenvolvi, não conhece? Então dê um Click >>AQUI<< )

O programa é um Exemplo Simples de "Blink Led". 


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import"\system\genesis_header.asm" ' Header de uma ROM de mega Drive Padrão (deve ficar sempre no topo)

Equal IO_addr "&hA12000" ' Endereço do Nosso Registrador

std_init()

load_cram_dma(addressof(paleta),16,0) 
load_tiles_dma(addressof(tiles),32,1) 

'[...] O que for colocado aqui sera executado apenas uma vez

io_data = 0
frames = 0

set_sprite_size(0,3,3) ' Sprite de 32x32 pixels para a lampada
set_sprite_gfx(0,1,0)
set_sprite_position(0,272,224)

enable_global_int() ' Ativa interrupções Globais

Do 'main

if frames > 30 then            'Pisca o Led a cada meio Segundo
io_data = _inv(io_data)        'Inverte o valor da variavel
poke(io_data as word, IO_addr) 'Envia para o registrador
frames = 0
end if

if io_data then 'Anima o Sprite na tela de acordo com o valor gravado no Registrador
set_sprite_gfx(0,1,0)
else
set_sprite_gfx(0,17,0)
end if

' Espera proximo Frames
flagvb = 1
while(flagvb)_asm"nop"
Loop ' Laço infinito

sub isr_Vblank() 'Interrupção por Vblank - 60 vezes por segundo
frames += 1
flagvb  = 0
update_sprite_table()
end sub


import"\system\genesis_std.nbs" ' Biblioteca contendo funções standard do Mega Drive
tiles:
import"\spt_data.bin"
paleta:
	DATAINT	&h0000,&h04A2,&h00EE,&h0000,&h004E,&h0888,&h0666,&h0000
	DATAINT	&h0000,&h0000,&h0000,&h0000,&h0000,&h0000,&h0000,&h0000


 Depois de compilado foi só copiar para um cartão de memoria e executar no Mega Drive usando um Everdrive!

  O resultado você pode ver ai no Video:



   

     Bom, por hoje é só, espero que vocês tenham gostado! No próximo post dessa série vamos ver como fazer o circuito de entrada. Até lá...

Um comentário:

  1. Se fosse sobre FUNK o post, estava cheio de filho da fruta, mas como não queremos filhos da fruta aqui... tudo certo!

    ResponderExcluir