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

Eletronics course slides

Hey everybody! In the last two weeks I gave two sessions of an electronics course organized by HackerSchool at the Alameda campus of the Instituto Superior Técnico. The slides were written in portuguese, but I decided to post them here anyway.

[scribd id=176813115 key=key-1r0mfadyaehf061xy3v4 mode=scroll]

[scribd id=176813926 key=key-1r0mfadyaehf061xy3v4 mode=scroll]

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);
        }
    }
}

Amani64 – 7400 Contest Prize

Hey everyone! A few weeks ago I received my prize for being among the 2nd place winners of the 7400 Contest. If you remember, I built a frequency counter  using CMOS chips from the 74(HC)00 and 4000 families. I received an Amani64 CPLD board kit. I never really worked with a CPLD before so I definitely need to try this out! The board came in the form of a kit, so I had to manually assemble everything. Here are some pictures.

Amani 64 Kit

Amani 64 Kit

Amani 64 Assembled

Amani 64

 

CMOS Frequency Counter – 7400 Contest Entry

I’ve wanted to create a frequency counter using logic chips for some time, but I never really got the chance to do it, mainly because nowadays there are micro-controllers that one can use in replacement of all these old chips. I heard of the 7400 Contest only 2 weeks ago and thought that it was the perfect excuse for me do build this machine!

The project consists of a frequency counter that uses only old-school CMOS chips: 4511 display drivers, 4029 decade counters a 4521 24-stage frequency divider and a 4011 chip with 4 NAND gates. The frequency counter counts from 1 Hz to 1 MHz (999.999 KHz)

CMOS Frequency Counter

CMOS Frequency Counter

 

This circuit can be understood by thinking about two separate blocks: the counting block, and the control block. The counting block consists of 6 4029 counters and 4511 display drivers. The terminal count pin of each counter is the clock input of the next counter. Each counter counts to 10 and as there are 6 counters, we can get a maxim count of  1.000.000 Hz, or 1 MHz. The control block takes care of the signals to control the chips in the counting block. Frequency is by definition “cycles per second”. In order to count a frequency, we must count during one second, latch the count to the displays and reset the counter to start counting again. The 4521 chip is dividing a frequency of 4.194304 MHz in order to get a frequency of 0.5 Hz (with a 50% duty cycle). During the first second the clock is HIGH and the counters are counting. As soon as the clock goes down, the RC circuit used together with the 4011 with the NAND gates triggers a quick signal that will latch the displays, and after that happened it triggers another very quick signal do reset the counters (as 4029 chips don’t have a master reset pin, I’m using a parallel load of 0 as an asynchronous reset). In the next second, the counters start counting again. I’d like to thank timescope for helping me out with this solution in the controlling signals.

This circuit was designed to be flexible, so the signal input is directly connected to the clock input pin of the first counter. This allows this circuit to be extended. If you want it to count frequencies of non-CMOS logic level signals, you can use external circuitry to convert the levels. You also can (or should) use a small transistor so that the input signal current is not drawn from the signal itself. If you want to turn this counter into a 1 KHz – 1 GHz counter, you can design a prescaler to divide the frequency by 1000 and then feed the output to the input of this circuit.

CMOS Frequency Counter Schematics

CMOS Frequency Counter Schematics

 

Notes:

  • In the schematics, where it says “Carry in”, it’s actually “Count Enable”. This is a bug from gschem!
  • If you want to build this circuit in a breadboard, be careful with the 4521 part of the circuit. In order to start the oscillator, the 2 capacitors must have different capacitance. Now, the breadboard as a lot of capacitance (and even inductance) between its tracks – this is why breadboards are awful in high-frequency applications. So you need to try different solution in order to get the circuit to oscillate. Sometimes it will oscillate in a breadboard even without any capacitor!
  • Even if it’s not featured in the schematic diagram, you should add a weak pull-down resistor in the external singal input that you want to measure in order to keep a logic LOW even when there is nothing connected. If you don’t do this, the screens will show random values because the clock pin of the first counter is floating. I used a 1 MegaOhm resistor.
  • Do not forget to add a 100nF capacitor between the supply pin of every chip and ground. This is very important to mantain stability (and not only in this circuit, but in every circuit you may build that uses these “logi” chips).
  • The resistors used in the displays are all 330R resistors. There are people who insist to use only a common resistor per display – this works, but will significantly reduce the life of the display, and may overheat the board because sometimes there will pass more current through one of the LED’s (for example, there will be more current passing through the lit LEDs when a display shows the number 1 then when it shows the number 8. In order to have a good design, you need to use a resistor for each segment, or a total of 42 resistors.
  • Even though CMOS chips are a bit more flexible with the supplied voltage than the older TTL ones, this circuit was created to work with a stable 5V supply, sou you can use a 7805 voltage regulator in order to create the right voltage output.
  • All the tones in the video used to test my frequency counter were generated by the Arduino’s tone() function.