MP08E Emulator Source Code

Hello everyone, here is the source code of the emulator introduced during my workshop concerning emulators. I waited almost two weeks to publish the code in order to let people to try to build it by themselves.

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MP08ALib;
 
namespace MP08AEmu
{
    public enum STATUS_FLAGS { EQUAL = 0, GREATER = 1, LOWER = 2 };
 
    public class MP08E : ICPU
    {
        byte[] memory = new byte[0x100];
 
        protected byte AC;
        protected byte[] dataRegisters = new byte[0x10];
        protected byte flags;
        protected byte PC;
        protected byte latch;
 
        public byte[] GetMemory() { return memory; }
 
        public void LoadMemory(byte[] buffer)
        {
            for (int i = 0; i < buffer.Length; i++)
                this.memory[i] = buffer[i];
        }
 
        public void Reset()
        {
            this.AC = 0;
            this.flags = 0;
            this.PC = 0;
            this.latch = 0;
            dataRegisters = new byte[0x10];
        }
 
        public void Step()
        {
            byte opcode = (byte)((memory[this.PC] >> 4)  & 0xF);
            byte imm4 = (byte)(memory[this.PC] & 0xF);
            byte imm8 = (byte)(memory[(this.PC + 1) & 0xFF]);
            bool jmp = false;
 
            switch (opcode)
            {
                case 0x0: break;																	            /* NOP */
                case 0x1: this.AC = memory[++this.PC]; break;                                                   /* LOADLIT */
                case 0x2: this.AC = dataRegisters[imm4]; break;									                /* LOADREG */
                case 0x3: dataRegisters[imm4] = this.AC; break;									                /* STORE */
                case 0x4: this.AC++; break;                                                                     /* INC */
                case 0x5: this.AC--; break;	                                                                    /* DEC */
                case 0x6: this.AC = latch; break;		            							                /* IN */
                case 0x7: this.latch = this.AC; break;									                        /* OUT */
                case 0x8: Compare(this.AC, imm8); this.PC++; break;									            /* COMPLIT */
                case 0x9: Compare(this.AC, dataRegisters[imm4]); break;									        /* COMPREG */
                case 0xA: if (GetBit(flags, STATUS_FLAGS.EQUAL)) { this.PC = imm8; jmp = true; } break;			/* JE addr */
                case 0xB: if (GetBit(flags, STATUS_FLAGS.GREATER)) { this.PC = imm8; jmp = true; } break;		/* JG addr */
                case 0xC: if (GetBit(flags, STATUS_FLAGS.LOWER)) { this.PC = imm8; jmp = true; } break;			/* JL addr */
                case 0xD: this.PC = imm8; jmp = true; break;									            	/* JMP addr */
                case 0xE: this.AC = (byte)(this.AC + dataRegisters[imm4]); break;				                /* ADD reg */
                case 0xF: this.flags = 0; break;				                                                /* CLEAR */
            }
 
            if (!jmp)
                this.PC++;
        }
 
        public bool GetBit(int value, int bit) { return (((value >> bit) & 0x1) == 1); }
        public bool GetBit(int value, STATUS_FLAGS bit) { return GetBit(value, (int)bit); }
 
        public int GetRegister(int reg, int datareg = 0)
        {
            switch (reg)
            {
                case 0: return this.PC;
                case 1: return this.AC;
                case 2: return this.flags;
                case 3: return this.latch;
                case 4: return this.dataRegisters[datareg];
 
                default:
                    return -1;
            }
        }
 
        public void Compare(int ac, int value)
        {
            MP08ALib.Utils.SetBit(ref flags, 0, ac == value);
            MP08ALib.Utils.SetBit(ref flags, 1, ac > value);
            MP08ALib.Utils.SetBit(ref flags, 2, ac < value);
        }
    }
}

MPNESemu 1.0.0.254 Alpha released

Featured

Hello world! For the past three weeks I’ve been working on this new exciting project – a NES emulator. The NES (Nintendo Entertainment System) or Famicom (as it’s called in Japan) is a third generation video console from the 80s. It uses a CPU based on the famous 8-bit 6502 and it runs at about 1.7 MHz. It addresses up to 64Kb of RAM. The games have a resolution of 256×240 pixels (with up to different 25 colors on the screen at the same time) and the platform outputs a composite video signal. This signal is generated by the Picture Processing Pnit (PPU).

This version of my emulator is still very unstable and only few games work with it. Only some of the games that do not use memory mappers work fine, like for instance Pacman, Mario Bros and Donkey Kong. Super Mario Bros (one of my favorite games of all time) is playable but it’s kinda buggy! No sound emulation yet!

At this moment, you can only play with one control, the keys are Up, Down, Right, Left, Z, X, S, Enter (Return).

You are free to download and test it out! But remember: it’s still an alpha version, so don’t expect too much. :)

Download Here

Super Mario Bros

Super Mario Bros

Pacman

Pacman

Donkey Kong

Donkey Kong