Fórum DingooBR
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Procurar
 
 

Resultados por:
 


Rechercher Pesquisa avançada

março 2024
DomSegTerQuaQuiSexSáb
     12
3456789
10111213141516
17181920212223
24252627282930

Calendário Calendário

Últimos assuntos
» PERGUNTA: ALGUÉM AINDA USANDO SEU DINGOO? SE TIVEREM POSTEM FOTOS
por Andy_Devil Qui 04 maio 2023, 2:33 pm

» Instalando Opendingux ou Dingux em 2019
por Matheus290 Sáb 08 maio 2021, 10:21 pm

» Duvida Powkiddy Q80
por retrogamer87 Sáb 18 Jul 2020, 4:19 pm

» Duvidas RS97
por retrogamer87 Sáb 18 Jul 2020, 7:59 am

» dingoo ligando sozinho
por lucas_tamp Qui 09 Jan 2020, 7:31 pm

» Case para raspberry pi zero da Retroflag
por filipe0606 Sex 19 Abr 2019, 7:42 pm

» CoolBoy RS-97: Um portátil com Dingux que custa menos de 50 dólares!
por Tarquineos Seg 09 Jul 2018, 3:48 pm

» Review GPD XD
por ricardo85x Dom 08 Jul 2018, 12:53 pm

» Peças de reposição para dingoo a320 em 2018
por corey Ter 03 Jul 2018, 11:29 am

» [Vendo] Mouse Gamer R$150 - SSD R$420
por eduardo.oc Qui 03 maio 2018, 12:53 am

» ATARI VCS-console novo da Atari depois de anos.
por Andre Pedreira dos Santos Sex 23 Mar 2018, 7:20 pm

» Boteco do Boteco
por Andre Pedreira dos Santos Qua 21 Fev 2018, 11:26 pm

» Onde conseguir um bom portátil "retrogame"?
por guilhoboy Qua 14 Fev 2018, 9:57 am

» [Android] Pacote de Emuladores Android (07-02-2017)
por willk Sex 29 Dez 2017, 1:38 am

» JXD S7300b - Temperatura elevada (será que é a bateria esquentando)?
por Dcnautamarvete Sáb 16 Dez 2017, 12:52 pm


[TUTORIAL] Criando um Emulador de NES

+2
gilplay3000
omundodogabriel
6 participantes

Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty [TUTORIAL] Criando um Emulador de NES

Mensagem por omundodogabriel Qui 13 Jun 2013, 6:59 pm

Bem, há algum tempo atrás eu tinha vontade de criar um emulador, emuladores sempre me interessaram, é impressionante como você pode emular todo um console com vários jogos diferentes com um só programa. Eu sempre usei muitos emuladores para conseguir jogar vários sistemas que nunca tive, até chegar ao ponto que tive vontade de fazer o meu próprio emulador.

É difícil achar um tutorial para fazer um emulador, ainda mais em português. Foi pensando nisso que eu decidi escrever um tutorial ensinando o pouco que eu sei, aqui eu pretendo ensinar a fazer um emulador de NES do ZERO.

IMPORTANTE - Nesse tutorial estarei escrevendo o emulador em Visual Basic .NET, que é uma linguagem que eu acho fácil de se trabalhar e é a que eu domino melhor, não sou muito bom em linguagens como C, então prefiro não me arriscar.

PARTE 1 - Introdução


Essa primeira parte eu vou falar só da teoria, e de como funciona o emulador. Na segunda parte, eu pretendo mostrar como botar a CPU pra funcionar. Na terceira, vídeo e controles, e na quarta polimentos e considerações finais.

1. O básico de como funciona a CPU:

Basicamente, quando o console é ligado, parte do código do cartucho é carregado na RAM, como a RAM dos sistemas antigos geralmente é bem limitada para cortar gastos, apenas uma parte do código é carregada por ver. No caso do NES, existe dentro dos cartuchos chips mapeadores chamados de mappers, que copiam partes do código do jogo para RAM na hora certa. Além disso, os gráficos dos jogos também são carregadas na VRAM, ou memória de video do console. Novamente, apenas parte dos gráficos é copiado para a VRAM, e qual parte é copiada também é controlada pelo chip mapeador.

O processador lê diversos dados da memória RAM. Uma das coisas que ele lê da memória é o Program Counter, ou PC. Esse registro serve pro processador saber onde ele está lendo as instruções, em que endereço da memória. Basicamente, o processador funciona em um loop infinito, onde ele lê um Opcode (Operation Code) da memória. Um Opcode é basicamente um código que indica qual instrução o código do jogo mandou o processador fazer. Os processadores mais antigos 8 bits não têm muitos Opcodes, o processador do NES (6502) por exemplo, tem 56 Opcodes. Porém, esses Opcodes podem ser executados com modos de endereçamento diferentes, algo que não vamos discutir agora.

O emulador funciona alterando seus registros. Os registros dos processadores serve a grosso modo para guardar valores, que mais tarde serão usados para fazer cálculos, de acordo com que instrução é usada. Mas ai você pergunta, como o processador se comunica com o resto do hardware? Bom, além de ler da memória RAM, o processador também "escreve" na memória RAM. Os dados que o processador adiciona na memoria vai ser usado por outras partes do hardware, como o chip gráfico, para criar o vídeo.

1.1 Entendendo Bits e Bytes

Bytes e bits são diferentes, é muito importante que você saiba a diferença entre eles para fazer um emulador. Um byte é um valor entre 0 e 255. Porém, como você já deve saber, as maquinas entendem 1 e 0. Um bit é o número de números de um código binário. Por isso, 8 bits = 1 byte. Os bits são um pouco confusos de se entender, pois é um monte de 1 e 0.

Você provavelmente ficou um pouco confuso, por isso, vou dar um exemplo.

Vamos usar como exemplo o número 100. Ele está entre 0 e 255, certo? Então ele é o equivalente a 1 byte. Se a gente converter para binário, ficaria "01100100". São 8 números, ou seja, 8 bits. Mas e se fosse, por exemplo, 500? É mais de 255, ou seja, é mais de 1 byte. Se convertemos 500 para binário vai ficar "00000001 11110100", são 16 números, ou seja, 16 bits. 16 bits = 2 bytes, pois se 8 bits = 1 byte, 16 / 8 = 2 bytes. Acho que você já deve ter pego a ideia.

OBS - Qualquer número entre 0 e 65536 vai ter 2 bytes - 16 bits, pois 256 * 256 = 65536.

Os registros do processador, em sua maioria, são 8 bits, pois vão guardar um valor entre 0 e 255. O registro

Nos consoles 16 bits como o Super Nintendo e Mega Drive, todos os registros são 16 bits, porém ele também pode trabalhar com 8 bits.

Um lugar onde bits e bytes é usado bastante atualmente é na internet. Por exemplo, se você tem uma internet de 15 megas, você vai baixar a 1,8mb/s. Por que? os vendedores da internet informam a velocidade da internet em bits, porém a velocidade em que é medida o download dos arquivos é em bytes. Então, se você dividir a velocidade da sua internet por 8, vai saber a velocidade máxima do download.

PARTE 2 - Abrindo a ROM e lendo o Header

1. O que é um Header

O Header da ROM, também chamado de cabeçalho, serve para guardar alguns dados sobre a ROM em si necessárias para o carregamento correto da mesma, além de conter informações do próprio cartucho que não estão gravadas na memória, tais como o Mapper que é um chip dentro do cartucho, ou o tamanho da ROM.

1.1 Abrindo o Header



Bem, agora que vimos um pouquinho de teoria e você deve saber o básico, vamos aprendendo o resto da melhor maneira - na prática!

Primeiro, vamos carregar o arquivo. Dependendo que que linguagem você vai usar, vai ser um método diferente para abrir o arquivo, mas vou mostrar como eu faço no vb.net.

Primeiro, vamos declarar duas váriaveis, "PROM" e "VROM", que são respectivamente o programa do jogo e a memória do Video. Declare elas como byte. Em seguida, vamos declarar as variáveis usadas pelo Header para definir algumas coisas da Rom, como tamanho da PRG-ROM e da Video ROM, Mapper e Mirroring.

Veja como eu fiz:

Código:

Public Structure Header
        Dim PrgSize As Byte 'Tamanho da PRG-ROM, ou o código em si do jogo
        Dim ChrSize As Byte 'Tamanho da memória onde ficam os gráficos do jogo
'OBS - Nem sempre o jogo guarda os gráficos aqui, vários jogos guardam na
'PRG e esse valor pode ser 0
        Dim Mapper As Byte 'Esse é o número do chip mapeador usado no cartucho
'Se o valor for 0 significa que o jogo não usa mapper nenhum, como Super Mario
        Dim Mirroring As Byte 'É usado na rolagem das telas do jogo, será explicado depois
        Dim Trainer As Byte 'Será explicado depois
        Dim FourScreen As Byte 'É um tipo especial do Mirroring, usado na rolagem
        Dim SRAM As Boolean 'Save RAM, para cartuchos com bateria pra salvar
    End Structure
    Public ROMHeader As Header 'Aqui dizemos que a variavel ROMHeader comporta todos esses valores que a gente definiu acima

Pronto, agora que declaramos onde vai ficar armazenada a ROM, podemos carregar o jogo!

Código:

        ' Carrega a ROM
        '---------------------------------------
        Dim Input As New FileStream(FileName, FileMode.Open)
        Dim ROM(CInt(Input.Length - 1)) As Byte
        Input.Read(ROM, 0, CInt(Input.Length))
        Input.Close()

Essa primeira parte, a gente abre o arquivo da rom .NES e carrega ele todo na variavel ROM. Reparem que a variavel FileName, você deve substituir ela pelo caminho onde está sua rom, por exemplo, "C:\Minha pasta de Roms\NES\smb.nes", COM as aspas. Se você está escrevendo em outras linguagens de programação que não sejam .NET, vai usar outro método para abrir.

Abaixo vamos começar a ler o Header, o Header da ROM de NES tem 16 bytes, ou seja, vai do byte 0 até o byte 15. Os quatro primeiros bytes se convertidos para caracteres ASCII vai formar o nome "NES ", ou seja, eles são inúteis, só servem pra você ter certeza que realmente é um jogo de NES, e não um arquivo com formato errado. Por isso, começamos a ler a partir do byte 4.

Código:

        ' Lê o Header, ou cabeçalho da ROM
        '---------------------------------------
        Dim PrgMark As Integer
        Dim ROMCtrl As Byte
        Dim ROMCtrl2 As Byte

'O 4º byte da ROM (lembre-se, começamos do 0)
'Ele é o número de bancos de PRG que temos
'Lembre-se, cada banco tem 16k, aqui vemos o NÚMERO DE BANCOS, não o total
        ROMHeader.PrgSize = ROM(4)
'Já aqui é o número de bancos de CHR - chr são os gráficos do jogo, a ROM de video (não confunda ROM com memória RAM, a ROM tem tudo, já que tem capacidade bem grande, já a RAM é limitada e vai ter apenas uma parte.
        ROMHeader.ChrSize = ROM(5)
'Aqui são outros bytes usados para fazer o cáculo para saber o Mapper e o Mirroring
        ROMCtrl = ROM(6)
        ROMCtrl2 = ROM(7)

        ROMHeader.Mapper = (ROMCtrl And &HF0) \ 16
        ROMHeader.Mapper += ROMCtrl2

        ROMHeader.Mirroring = ROMCtrl And &H1 'Mirroring
        ROMHeader.Trainer = ROMCtrl And &H4
        ROMHeader.FourScreen = ROMCtrl And &H8 'Mirroring
        If ROMCtrl And &H2 Then ROMHeader.SRAM = True 'Save RAM
'Lembra que eu disse que cada banco de prg tem 16kb? 16kb = 16384 bytes
'Multiplicamos o NÚMERO DE BANCOS, pelo tamanho em byte de cada banco, para saber o tamanho total em BYTES que tem a PRG-ROM (código do jogo)
        PrgMark = ROMHeader.PrgSize * 16384

        ' Preenche as variaveis VROM e PROM
        '---------------------------------------
'ReDim serve para redimensionar uma Array, aqui deixamos a Array PRG-ROM do tamanho da PRG-ROM
        ReDim PROM(PrgMark)
        Dim StartAt As Integer
'Os trainers é como um hack dentro da ROM, não é uma coisa boa pois é um "armengue" usado pelos NES piratas, onde um código extra era usado no inicio da rom para que mappers não suportados pelo clone fossem adaptados para usar um mapper que fosse suportado. O código do Trainer ocupa 512 bytes depois do Header. Então, se a ROM tiver Trainer, 512 + 16 bytes do Header = 528, a PRG-ROM começa a partir do byte 528, se nao, começa logo após o termino do Header, no byte 16.
        If ROMHeader.Trainer Then StartAt = 528 Else StartAt = 16
        Buffer.BlockCopy(ROM, StartAt, PROM, 0, UBound(PROM))

Como eu já disse, assim como o  PRG a Video ROM também tem seu valor carregado em número de pages. Porém, casa page da Video ROM só tem 8kb, ou seja 8192 bytes.
        ReDim VROM(ROMHeader.ChrSize * 8192)
        PrgMark = &H4000 * ROMHeader.PrgSize + StartAt
        If ROMHeader.ChrSize Then Buffer.BlockCopy(ROM, PrgMark, VROM, 0, UBound(VROM))

        ' Reset NES
        '---------------------------------------
        Mapper_Reset() 'Depois veremos isso
        Reset_CPU() 'Zera os valores da CPU, depois veremos isso

A função Buffer.BlockCopy serve para copiar bytes da memória do computador. Ele copia bytes da ROM para VROM e para PRG-ROM. Em outras linguagens, você vai ter que usar outras funções. Você pode usar também a API MemCopy do Windows.

Veja a linha de código:

Código:
Buffer.BlockCopy(ROM, StartAt, PROM, 0, UBound(PROM))

Ele copia a variavel ROM, começando a partir do valor StartAt, que é onde começar a PRG-ROM, e copia para a variavel PROM, começando do 0, e por fim o número de bytes que ele vai copiar, que é o tamanho da array PROM, que é o PrgMark.

- Com esse código, já conseguimos abrir a ROM e carregar os valores do Header. Na próxima parte, vamos começar a escrever o código da CPU e da memória, para que possamos de fato "rodar" alguma coisa.

- Em breve vou adicionar mais coisas aqui....

OBS: Podem haver alguns errinhos aqui e ali, pois eu não domino totalmente o assunto ainda. Caso você tenha conhecimento de alguma informação errada aqui, por favor, me avise para que eu possa corrigir Wink

Edit: Corrigi algumas  coisinhas, ao invés de um emulador de Gameboy vou fazer um tuto pra um emulador de NES, pois eu ja tenho um pronto e vai ser mais rápido e facil.


Última edição por omundodogabriel em Sex 14 Jun 2013, 8:41 pm, editado 6 vez(es)
omundodogabriel
omundodogabriel
User Level IV
User Level IV

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 527
Data de inscrição : 03/09/2011
Idade : 26
Localização : Unknow

http://gamebots.blogspot.com

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por gilplay3000 Qui 13 Jun 2013, 7:21 pm

sobre internet eu calculei de forma diferente. mas meio que válida eu acho, eu tenho 2mb (2.048k) enquanto a anatel obriga pelo menos oferecer 10% da conexão prometida, então 2.048 - 90% = 204k, essa é a velocidade máxima q consigo baixar arquivo aqui, e raramente dá uns 257kbps.
gilplay3000
gilplay3000
User Level IV
User Level IV

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 615
Data de inscrição : 15/10/2012
Idade : 33
Localização : Bacabal-MA

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por RodRock Sex 14 Jun 2013, 7:19 am

Muito boa a iniciativa! Sou desenvolvedor, e ainda não tive oportunidade de implementar um emulador, apesar de gostar muito do assunto (e obviamente utilizar emuladores).

Só uma pequena correção: Em 1 byte (8 bits), vc consegue escrever valores de 0 (00000000) a 255 (11111111), isso se vc estiver não estiver considerando o sinal (unsigned). Caso considere o sinal (signed), o bit mais significativo passa a ser utilizado para representar o sinal, logo sua faixa de valores passa a ser de -128 a 127.

Aguardando continuação do tutorial!
RodRock
RodRock
User Level II
User Level II

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 67
Data de inscrição : 01/01/2012
Idade : 41
Localização : Uberlândia - MG

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por lordkill Sex 14 Jun 2013, 8:43 am

Aguardando continuação também amigo, gostei da idéia, parabéns, sou programador intermediário em C#, já fiz vários sistemas e sempre gostei da idéia de emular um processador de video game.

lordkill
User Level I
User Level I

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 22
Data de inscrição : 12/01/2013

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por italo Sex 14 Jun 2013, 3:07 pm

Muito boa essa iniciativa... já programei em Pascal e este ano estou aprendendo Delphi e estou me adaptando. Posso arriscar criar um emulador usando Object Pascal?
italo
italo
Moderador
Moderador

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 1803
Data de inscrição : 06/06/2011
Idade : 27
Localização : Aracaju-SE

http://rockmancentral.com.br/

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por omundodogabriel Sex 14 Jun 2013, 5:54 pm

italo escreveu:Muito boa essa iniciativa... já programei em Pascal e este ano estou aprendendo Delphi e estou me adaptando. Posso arriscar criar um emulador usando Object Pascal?
Italo, emuladores de NES não são tão complexos, e podem ser escritos em quase qualquer linguagem. Eu nunca usei object pascal, mas se suportar apis da sim.[/quote]
omundodogabriel
omundodogabriel
User Level IV
User Level IV

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 527
Data de inscrição : 03/09/2011
Idade : 26
Localização : Unknow

http://gamebots.blogspot.com

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por italo Sex 14 Jun 2013, 8:14 pm

omundodogabriel escreveu:
italo escreveu:Muito boa essa iniciativa... já programei em Pascal e este ano estou aprendendo Delphi e estou me adaptando. Posso arriscar criar um emulador usando Object Pascal?
Italo, emuladores de NES não são tão complexos, e podem ser escritos em quase qualquer linguagem. Eu nunca usei object pascal, mas se suportar apis da sim.
[/quote]

Queria tirar uma onda com o pessoal da escola que não tá conseguindo manjar das manjarias do Delphi... já estou me acostumando com o ambiente e com os comandos. Pra você que já fez um jogo no Delphi não deve ser tão difícil fazer um emulador usando a mesma linguagem...

PS: Pq num posta esses tutos no seu blog também? renderia mais visitas Smile
italo
italo
Moderador
Moderador

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 1803
Data de inscrição : 06/06/2011
Idade : 27
Localização : Aracaju-SE

http://rockmancentral.com.br/

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por omundodogabriel Sex 14 Jun 2013, 8:46 pm

italo, para você adaptar os códigos que eu vou colocar pra delphi não vai ser tão dificil, você só vai precisar usar 4 APIs, o resto vai ser código puro.

As APIs são CopyMemory, QueryPerformanceCounter, QueryPerformanceFrequencye StrectchDIBits.

Você fazendo essas 4 APIs funcionarem, vai conseguir tranquilo.
omundodogabriel
omundodogabriel
User Level IV
User Level IV

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 527
Data de inscrição : 03/09/2011
Idade : 26
Localização : Unknow

http://gamebots.blogspot.com

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por lordkill Sáb 15 Jun 2013, 10:26 am

Muito bom cara, vou aproveitar o tutorial e programar o meu em c#, ai vou fazendo junto.

lordkill
User Level I
User Level I

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 22
Data de inscrição : 12/01/2013

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por Winchester Qua 03 Jul 2013, 11:21 pm

Achei isto sem querer. Achei legal e que poderia ser bom pra este tópico.

Um tutorial de criação de um emulador de game boy:

http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-The-CPU

Winchester
User Level III
User Level III

Avisos :
[TUTORIAL] Criando um Emulador de NES Left_bar_bleue0 / 1000 / 100[TUTORIAL] Criando um Emulador de NES Right_bar_bleue

Mensagens : 203
Data de inscrição : 08/03/2013

Ir para o topo Ir para baixo

[TUTORIAL] Criando um Emulador de NES Empty Re: [TUTORIAL] Criando um Emulador de NES

Mensagem por Conteúdo patrocinado


Conteúdo patrocinado


Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos