Pokémon Mythology
Olá, visitante! Você pode aproveitar mais o fórum se conectando ou registrando!

Conte uma história, poste uma arte ou um vídeo! Confira os guias de jogos, tire suas dúvidas e compartilhe sua jogatina. Disputa batalhas online com jogadores e participe dos RPGs. Converse sobre qualquer coisa, poste memes, faça novos amigos!
Seja bem-vindo!

Aproveite e entre em nosso Discord está na barra de menu!

Como criar um Emulador Pikalove


Participe do fórum, é rápido e fácil

Pokémon Mythology
Olá, visitante! Você pode aproveitar mais o fórum se conectando ou registrando!

Conte uma história, poste uma arte ou um vídeo! Confira os guias de jogos, tire suas dúvidas e compartilhe sua jogatina. Disputa batalhas online com jogadores e participe dos RPGs. Converse sobre qualquer coisa, poste memes, faça novos amigos!
Seja bem-vindo!

Aproveite e entre em nosso Discord está na barra de menu!

Como criar um Emulador Pikalove
Pokémon Mythology
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

Como criar um Emulador

4 participantes

Ir para baixo

Como criar um Emulador Empty Como criar um Emulador

Mensagem por Yukimaru Dom 13 Set 2009 - 10:42

Então você decidiu escrever um software de emulador? Muito bem,
pois este documento responde às perguntas técnicas comuns sobre
como escrever emuladores, podendo assim lhe ajudar em algo.

O que pode ser emulado?
O que é "emulação" e o que a difere de "simulação"?
É legal emular o hardware de um proprietário?
O que é "interpretar o emulador" e o que o difere de
"recompilar o emulador"?
Eu desejo escrever um emulador. Por onde devo começar?
Que linguagem de programação eu devo usar?
Onde eu obtenho informações do hardware a ser emulado?
Como eu emulo uma CPU?
Como eu optimizo meu código C?
O resto está por vir...


# O que pode ser emulado?

Basicamente qualquer coisa que tenha um microprocessador dentro.
Certamente, os dispositivos mais interessantes para se emular são
os que funcionam com mais ou menos flexibilidade. Incuindo:

Computadores
Calculadoras
Consoles de Videogames
Arcades de Videogames
etc.

É sempre bom lembrar que você pode emular qualquer sistema de
computador, mesmo os mais complexos ( como o computador Commodore
Amiga, por exemplo). Porém, nestes casos a performance da emulação
pode ser muito baixa.


# O que é "emulação" e o que a difere de "simulação"?

Emulação é a tentativa de imitar o desenho interior de um
dispositivo. Simulação é a tentativa de imitar as funções de um
dispositivo. Exemplos: um programa que imita o hardware do arcade
de Pacman para rodar a verdadeira ROM de Pacman é um emulador. O
jogo do Pacman escrito para um computador usar gráficos parecidos
com o real arcade é um simulador.


# É legal emular o hardware de um proprietário?

Embora muitos digam o contrário, ao que me parece é legal emular o
hardware de um proprietário, se as informações dele não forem
obtidas por meios ilegais. Você deve estar atento ao fato de que é
ilegal distribuir ROMs de sistema ( BIOS, etc. ) com emulador, se
este estiver em estado "copyrighted" (cópia registrada).


# O que é "interpretar o emulador" e o que o difere de "recompilar
o emulador"?

Há três esquemas básicos que podem ser utilizados por um emulador.
Eles podem ser combinados para se obter um melhor resultado.

Interpretação

O emulador lê o código emulado da memória byte-por-byte, o
decodifica e desempenha os comandos apropriados nos registros
emulados, memória, e I/O. O algoritimo geral de tal emulador é o
seguinte:


while(CPUIsRunning)
{
Fetch OpCode
Interpret OpCode
}

O melhor deste código é a facilidade do debug, portabilidade
e sincronização ( você pode simplesmente contar os ciclos que o
relógio faz e dar descanso à emulação por conta do ciclo ). O
simples, grande e óbvio problema é a performance. A interpretação
toma muito de tempo da CPU, e você pode precisar de um computador
rápido para rodar seu código numa velocidade decente.

Recompilação Estática

Nesta técnica, você pega o programa escrito no código emulado
e tenta traduzí-lo para o código de montagem (código assembly) de
seu computador. O resultado será um usual arquivo executável que
você poderá rodar no seu computador sem nenhuma outra ferramenta
especial.
Apesar de recompilação estática soar bem melhor, nem sempre
ela será possível. Por exemplo, você não pode recompilar
estaticamente um código auto-modificado (self-modifying), pois não
existe jeito de faze-lô rodar. Para evitar tais situações, você
pode tentar combinar a recompilação estática com a interpretação
ou recompilação dinâmica.

Recompilação Dinâmica

A recompilação dinâmica é essencialmente a mesma coisa que
a estática, a diferença é que ocorre durante execução do programa.
Ao invés de tentar recompilar todo o código em uma só vez, você
vai aonde quer com as instruções CALL ou JUMP.
Para aumentar a velocidade, esta técnica deve ser combinada com a
recompilação estática. Você pode ler mais sobre a recompilação
dinâmica no white paper (papel branco), por Ardi, criadores da
recompilação do emulador de Macintosh.


# Eu desejo escrever um emulador. Por onde devo começar?

Para escrever um emulador, você deve ter um bom conhecimento geral
de programação de computadores e de eletrônica digital. Alguma
experiência em programação em assembly lhe dará uma boa mão.

1.Escolha uma linguagem de programação para usar.
2.Ache toda informação disponível sobre o hardware a ser emulado.
3.Escreva a emulação da CPU ou obtenha o código real da emulação
da CPU.
4.Faça algum esboço do código para emular o descanso do hardware,
ao menos parcialmente.
5.Agora, será muito útil escrever um pequeno debugger embutido,
que permita parar a emulação e ver o que o programa está
fazendo. Talvez você precise de um disassembler da emulação da
linguagem do sistema assembly. Escreva o seu próprio se não
exitir um destes.
6.Tente rodar programas no seu emulador.
7.Use o disassembler e o debugger para ver que programas usam o
hardware e ajuste seu código apropriadamente.



# Que linguagem de programação eu devo usar?

As alternativas mais óbvias são C e Assembly. Aqui estão os prós e
contras de cada uma delas:

Assembly

+ Geralmente permite produzir um código rápido.
+ Os registros emulados da CPU podem ser utilizados para
armazenar diretamente os registros da CPU emulada.
+ Muitos opcodes podem ser emulados com os opcodes similares
à CPU emulada.
- O código não é portátil, ou seja, não será possível rodá-lo
num computador com arquitetura diferente.
- É difícil o debug e a manutenção do código.

C

+ O código pode se tornar portátil se trabalhar em sistemas
operacionais e computadores diferentes.
+ É relativelmente fácil o debug e a manutenção do código.
+ As diferentes hipóteses de como trabalha o hardware real
podem ser testadas rapidamente.
- C é, geralmente, mais lento que o código assembly puro.

Bom conhecimento da linguagem escolhida é absolutamente necessário
para se escrever um emulador que funcione, assim como, num projeto
complexo como este, o código deveria ser optimizado para poder
rodar o mais rápido possível.
Emulação de computadores definitivamente não é um dos projetos em
que você possa aprender uma linguagem de programação.


# Onde eu obtenho informações do hardware a ser emulado?

A seguir há uma lista de lugares onde você pode achar o que quer.

NEWSGROUPS (Grupos de Notícias)

comp.emulators.misc
Este é um grupo de notícias de discussão geral sobre emulação
de computadores. Muitos autores do emuladores lêem ele, embora o
nível de barulho seja muito alto.

comp.emulators.game-consoles
O mesmo que o comp.emulators.misc, só que mais especificado
na emulação de consoles de videogames.

comp.sys./emulated-system/
A hierarquia comp.sys.* contém grupos de notícias dedicados à
computadores específicos. Você pode obter muita informação técnica
útil na leitura desses grupos. Exemplos típicos:

comp.sys.msx Computadores MSX/MSX2/MSX2+/TurboR
comp.sys.sinclair Sinclair ZX80/ZX81/ZXSpectrum/QL
comp.sys.apple2 Apple ][
etc.

Por favor, cheque sempre as FAQS apropriadas
antes de postar em qualquer grupo.
alt.folklore.computers
rec.games.video.classic

FTP

Oulu
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link]


WWW

Emulation Programmers Resource
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link]

Emulation (emulação de macintosh)
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link]

Programmer Heaven
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link]

Komkon
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link]


FAQ

Dê uma olhada nos sites (WWW) e nos grupos de notícias


# Como eu emulo uma CPU?

Antes de tudo, se você apenas necessitar emular o padrão Z80 ou a
CPU 6502, você deverá usar um dos emuladores de CPU que eu já
citei. Devem ser aplicadas certas condições para seu uso correto.
Para que deseja escrever seu próprio código de emulação de CPU ou
está interessado em saber como ele trabalha, eu forneço o código
básico de um emulador de CPU típico em linguagem C, logo abaixo.
Para o seu próprio emulador, você pode querer retirar algumas
partes ou adicionar outras para personalizá-lo.


Counter=InterruptPeriod;
PC=InitialPC;

for(;;)
{
OpCode=Memory[PC++];
Counter-=Cycles[OpCode];

switch(OpCode)
{
case OpCode1:
case OpCode2:
...
}

if(Counter<=0) {
/* checa por interrupções e faz outra emulação do hardware */
...
counter+="InterruptPeriod;"
if(exitrequired) break;
}
}


Primeiro, nós designamos os valores iniciais ao contador de ciclo
da CPU (Counter) e ao contador do programa (PC):

Counter=InterruptPeriod;
PC=InitialPC;

O contador contém o número de ciclos que a CPU deixa à próxima -
suspeitada - interrupção. Note que a interrupção não deve ocorrer
necessariamente quando o contador expirar: você pode usar isto
para muitos outros propósitos, tal como sincronizar timers, ou
atualizar os scanlines da tela. Mais deixe isto pra mais tarde. O
PC contém uma memória endereçada, que a nossa CPU emulada lerá no
seu próximo opcode.

Depois que os valores iniciais são designados, nós iniciamos o
loop principal:

for(;;)
{

Note que este loop também pode ser implementado com:

while(CPUIsRunning)
{

Aqui, CPUIsRunning é uma variável boolean. Ela tem suas vantagens,
como a de você poder terminar o loop a qualquer momento, setando
CPUIsRunning=0. Infelizmente, checando esta variável toda vez que
ela passar, tomará muito de tempo da CPU. Seria bom que você a
evita-se quando possível, porém, não implemente este loop com:

while(1)
{

Porque, neste caso, alguns compiladores gerarão um código checando
se 1 é verdadeiro ou não. Você certamente não deseja um compilador
fazendo um trabalho desnecessário em toda passagem de um loop.
Agora nós estamos no loop, e a primeira coisa será ler o próximo
opcode, que modifica o contador de programa:

OpCode=Memory[PC++];

Este é o caminho mais simples e rápido para ler a memória emulada,
porém, ela não será possível pelas seguintes razões:

× Memória pode ser fragmentada dentro das páginas de switch
(bancos aka)
× Lá podem ser mapeadas a memória dos dispositivos I/O do sistema

Nestes casos, nós podemos ler a memória emulada pela função
ReadMemory():

OpCode=ReadMemory(PC++);

Geralmente a função WriteMemory() serve para escrever na memória
emulada. Além disso, se tratando de memória I/O mapeada e páginas,
o WriteMemory() pode fazer também o seguinte:

Protejer a ROM contra modificações
Alguns softwares baseados em cartuchos (tais como os jogos de
MSX, por exemplo) tentam escrever na pópria ROM e se recusam a
trabalhar se são bem sucedidos. Isto é freqüentemente feito para
se protejer a cópia.

Manejar a memória espelhada (mirrored memory)
Uma área de memória pode ser acessível de vários endereços
diferentes. Por exemplo, os dados que você escreve dentro
localização $4000 também pode aparecer em $6000 e $8000. Esta
situação pode ser resolvida com o uso do ReadMemory(), mas,
usualmente, ela não é desejável, já que o ReadMemory() obtêm uma
chamada/call muito mais freqüente que com o WriteMemory().
Portanto, o caminho mais eficiente deve ser implementar a memória
espelhando na função WriteMemory().

As funções ReadMemory()/WriteMemory() dão muita sobrecarga na
emulação, sendo que seu dever é a deixar mais eficiente possível,
porque elas obterão chamadas/calls muito freqüentemente. Aqui vai
um exemplo destas funções:

leitura da memória (ReadMemory) do byte em inline estático
(registra o endereço da palavra):

{
return(MemoryPage[Address>>13][Address&0x1FFF]);
}

leitura da memória (ReadMemory) vazia em inline estático
(registra o endereço da palavra e o valor do byte):

{
MemoryPage[Address>>13][Address&0x1FFF]=Value;
}

Note a palavra-chave inline. Ela contará com um compilador para
embutir a função dentro do código, ao invés de fabricar uma
chamada/call para isto.
Se seu compilador não suportar inline ou _inline, tente fabricar
uma função estática: alguns compiladores (WatcomC, por exemplo)
optimizam funções estáticas curtas por inlining.

Também, lembre-se de que na maioria dos casos, o ReadMemory() será
chamado muitas vezes mais freqüentemente que o WriteMemory().
Portanto, isto estará valendo para implementar um código maior no
WriteMemory(), guardando ReadMemory() para os mais simples e curto
possíveis.

Depois que trouxer o opcode nós diminuímos o contador de ciclos da
CPU pelo número de ciclos requeridos por este opcode:

Counter-=Cycles[OpCode];

A tabela Cycles[] deverá conter o número de ciclos da CPU para
cada opcode. Tome cuidado, pois alguns opcodes (tal como jumps
condicionais ou chamadas/calls do subrotina) podem tomam um número
diferente de ciclos dependendo de seus argumentos. Isto pode ser
ajustado mais tarde, com outro código.

Agora está na hora de interpretar o opcode e executá-lo:

switch(OpCode)
{

É comum ter a concepção de que a construção de um switch() é
ineficiente para compilar numa cadeia de declarações if() ...
else if() ... Enquanto isso é verdadeiro para construções com um
pequeno número de casos, as grandes construções ( 100-200 ou mais
casos ) sempre parecem compilar dentro uma tabela de jumps,
deixando eles completamente eficientes.

Há dois caminhos alternativos para se interpretar os opcodes.
O primeiro vai fazer uma tabela de funções e chamar a mais
apropriada. Este método aparece ser menos eficiente que o switch()
pois você irá receber uma sobrecarga de funções de chamada/call.
O segundo método é fazer uma tabela de labels, e usar a declaração
do goto. Enquanto este método é ligeiramente mais rápido que o
switch(), ele trabalhará unicamente nos compiladores que suportam
"precomputed labels" (labels pré computadas). Outros compiladores
não permitirão que você crie um arranjo de endereços de labels.

Depois da bem sucedida interpretação e execução dum opcode, é
chegada a hora de checar se é necessária alguma interrupção. Neste
momento, você também pode desempenhar quaisquer tarefas que
necessitam ser sincronizadas com o relógio do sistema:

if(Counter<=0)
{
/* checa por interrupções e faz outra emulação de hardware */
...
counter+="InterruptPeriod;"
if(exitrequired) break;
}

A seguir, uma lista curta de coisas que você pode fazer com a
declaração if():

Checar se o fim da tela é alcançado e gerar uma interrupção
VBlank se assim
Checar se o fim do scanline é alcançado e gerar uma interrupção
HBlank se assim
Checar por uma colisão de sprites, e gerar uma interrução, se
necessário
Atualizar os timers da emulação de hardware, gerar uma
interrupção se os timers expirarem
Refrescar a amostra/display de scanline
Refrescar o modo tela inteira
Atualizar som
Ler o estado do teclado/joysticks
etc.

Cuidadosamente calcule o número de ciclos que a CPU necessita para
cada tarefa, então use o menor número no InterruptPeriod, e junte
todas as outras tarefas nele ( elas não devem necessariamente
executar em toda expiração do contador ).

Note que nós não apenas designamos Contador=InterruptPeriod, mas
fizemos um Counter+=InterruptPeriod: ele fará o contador de ciclos
mais preciso, mesmo usando números negativos.

Também dê uma olhada na linha

if(ExitRequired) break;

Como fica muito custoso checar a saída em toda passagem do loop,
nós fazemos isto unicamente quando o Contador expirar: ele apenas
sairá da emulação quando você atribuir ExitRequired=1, não tomando
muito tempo da CPU.

Isto é tudo que eu tenho a dizer sobre emulação de CPU em C.

Fonte: EmulaBR

Kem kiseh cria um emulador me xama q eu ajudo :rindoxd:

________________
Pokémon Black (U)
Pokémon White (U)
Patch Pokémon B/W
Yukimaru
Yukimaru
Membro
Membro

Masculino Idade : 28
Alerta Alerta :
Como criar um Emulador Left_bar_bleue0 / 100 / 10Como criar um Emulador Right_bar_bleue

Data de inscrição : 07/08/2009


http://animegamemaniaco.blogspot.com/

Ir para o topo Ir para baixo

Como criar um Emulador Empty Re: Como criar um Emulador

Mensagem por G-Narly Ter 15 Set 2009 - 10:25

Vlws cara,eu tava afim de cria um emulador,eu tinha aprendido a cria software mais emulador e muito treta o.o
se eu for cria eu te aviso inton Wink

________________
Bafomê Owna [Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]
G-Narly
G-Narly
Membro
Membro

Masculino Idade : 28
Alerta Alerta :
Como criar um Emulador Left_bar_bleue0 / 100 / 10Como criar um Emulador Right_bar_bleue

Data de inscrição : 11/09/2009


Ir para o topo Ir para baixo

Como criar um Emulador Empty Re: Como criar um Emulador

Mensagem por Yukimaru Ter 15 Set 2009 - 11:22

Tomara q crie, com Wi-Fi Exclamação

________________
Pokémon Black (U)
Pokémon White (U)
Patch Pokémon B/W
Yukimaru
Yukimaru
Membro
Membro

Masculino Idade : 28
Alerta Alerta :
Como criar um Emulador Left_bar_bleue0 / 100 / 10Como criar um Emulador Right_bar_bleue

Data de inscrição : 07/08/2009


http://animegamemaniaco.blogspot.com/

Ir para o topo Ir para baixo

Como criar um Emulador Empty Re: Como criar um Emulador

Mensagem por vasco3000 Seg 21 Set 2009 - 19:20

yukimaru eu tenho que fazer um projecto de grupo...e queria fazer um emulador...gostava de fazer um emulador do gameboy ou do gameboycolor para o pc...é muito complicado? [Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]

________________
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link]
vasco3000
vasco3000
Membro
Membro

Masculino Idade : 31
Alerta Alerta :
Como criar um Emulador Left_bar_bleue0 / 100 / 10Como criar um Emulador Right_bar_bleue

Data de inscrição : 07/09/2009


http://www.flashbunda.blogspot.com

Ir para o topo Ir para baixo

Como criar um Emulador Empty Re: Como criar um Emulador

Mensagem por Yukimaru Seg 21 Set 2009 - 19:24

Nem sei, eu num "intendu" nd de programação, eu soh copiei e colei de um site....

________________
Pokémon Black (U)
Pokémon White (U)
Patch Pokémon B/W
Yukimaru
Yukimaru
Membro
Membro

Masculino Idade : 28
Alerta Alerta :
Como criar um Emulador Left_bar_bleue0 / 100 / 10Como criar um Emulador Right_bar_bleue

Data de inscrição : 07/08/2009


http://animegamemaniaco.blogspot.com/

Ir para o topo Ir para baixo

Como criar um Emulador Empty Re: Como criar um Emulador

Mensagem por Swellow_Blastoise Ter 22 Set 2009 - 21:53

Não li tudo, mais deve ajudar muito pra quem quer criar emulador.

________________
[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]
Swellow_Blastoise
Swellow_Blastoise
Membro
Membro

Masculino Idade : 26
Alerta Alerta :
Como criar um Emulador Left_bar_bleue0 / 100 / 10Como criar um Emulador Right_bar_bleue

Data de inscrição : 02/01/2009


http://poke360-new.blogspot.com

Ir para o topo Ir para baixo

Como criar um Emulador Empty Re: Como criar um Emulador

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