Git Product home page Git Product logo

dmg-cpu-inside's Introduction

DMG-CPU-Inside

This repo contains an annotated overlay for the Nintendo Game Boy DMG-CPU-B chip die and the extracted schematics.

DMG-CPU-B die vector overlay

This was done manually with only a few automated checks so THERE'S A HIGH RISK OF ERROR. I'm in no way responsible if you made someone's life depend on this and it fucked up.

What is done:

  • All APU logic.
  • All PPU logic.
  • All I/O and timer logic.
  • All DMA logic.
  • All interrupt logic.
  • Various stuff used for testing/debugging.

What isn't done:

  • CPU. Why: it's a standalone core which doesn't use the standard cell topology. Visibility isn't good enough and it's too complex for me, sorry.
  • Clock complements. Why: They don't affect functionality. Only required because the DFF cells need a clock and its complement to work.
  • Some analog parts. Why: Poor visibility, lazyness.
  • Some cell groups related to embedded ROM and RAM blocks. Why: They don't affect functionality.

How to use

Just read the schematics :)

If you want to use the overlay:

  • Get Inkscape
  • Download the die picture from Digshadow
  • Resize it to 8000px wide if you're using Inkscape 0.92.2, otherwise it may freeze
  • Download the SVG overlay
  • Open the overlay in Inkscape, import the die picture (chose link, not embed), stick it under the overlay layers, align it and lock it in place
  • Have "fun"

Notes

Nets named FROM_CPU* and TO_CPU are connected to the CPU core but are not clearly identified. Many of them are trigger and acknowledge signals for interrupts. Others might be state indicators like the Z80 /M1 or HALT.

Some DFF clock polarities have to be verified.

The parallel-in-serial-out shift registers used for the serial link and video rendering are made of chains of set-reset-capable DFFs. Their loading logic require a lot of cells and seem complex, but in the end it forms something quite simple.

Rather than using multiplexers, many internal busses are instead tri-state capable. The "TRIBUFFER" cells are extensively used for this.

Mysteries

  • Bit 4 and 5 of FF26 (NR52) can be written to.
    • Bit 4 sets NET03 (APU test mode ?).
    • Bit 5 allows software clocking of the CH1 sweep timer when NET03 is high.
  • Bit 0 of FF23 (NR44) can be read. It relates to the CH4 prescaler.
  • The current wave RAM address can be read in bits 4~0 of FF1C (NR32) when NET03 is high.
  • The whole chip can be made a slave for an external CPU by using the test pins. This was already discovered by @Gekkio and maybe others.
  • Probably other things I missed...

PAQ (Potentially Asked Questions)

  • Why ?

It is well known by emulator authors that the Game Boy is full of quirks. Knowing exactly how and when signals change can help reaching perfect accuracy.

  • Why are the schematics not in an editable format ?

Because I used proprietary CAD software for speed and I didn't finish making the converter for the KiCAD format. I hope to be able to do that soon.

  • What's up with the cell labels ?

They're random, unique names. The first letter corresponds to the column they're in on the silicon die.

  • Many small lines aren't traced, why ?

I didn't bother tracing branching lines when their end point was near enough to see it on my 15" screen at the zoom level I used. They're reported on the schematic, of course.

  • Why are there copies of logic blocks providing identical functions ?

It's a way to trade off die space for speed, it seems weird but it's useful. Look up "logic duplication".

  • I found a mistake, how can I report it ?

Until I get the files exported in KiCAD format, please open an issue and describe what's wrong (cell name, net name, position on die, ...).

  • How did you know which cells did what ?

I had to take guesses. Inputs and outputs are easily identified and the cell size gives some clues. When connections are made on the schematic, it becomes quickly obvious when a guess is wrong. Check out the cell zoo.

  • How long did it take ?

Identifying the cells, isolating them, tracing the connections and the schematics took 191 hours.

If you find it worth it, I accept donations through Paypal: paypal.me/furrtek

Thanks to Gekkio, Tanjent and Kevin Murphy for the help.

dmg-cpu-inside's People

Contributors

furrtek avatar nwsm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dmg-cpu-inside's Issues

Wrong labels for address pins

In the top right corner of page 8, the !OUT and OUT inputs of the PIN_BI cell of A3 receive the signals A0_A and A0_B respectively. It should be A3 for A3, not A0. Furthermore A0_B doesn't exist, it is labelled A0_D where it's driven. I assume A and D stands for assert and deassert? (Funny enough, there is A1_B and A2_B, though.)

I suggest renaming the pin cell inputs !OUT to !SET and OUT to RESET. And then also renaming the signals A0_A to !A0_SET and A0_D to A0_RESET or something similar. This would make things more clear, I think.

CUFE is an "NAO3"

image

C = 1 forms A NAND B, while C = 0 pulls OUT to VCC. Thus, we're looking at !((A & B) | C), or a NOT-AO3.

FF00WR is active low

FF00WR generated on page 10 by ATOZ is an active low signal. It should be called !FF00WR. It is used on page 5.

NOKO

Entrée 3 = V3
Entrée 4 = V0
Il faut aussi modifer 147 en 153 dans le commentaire.

Label FROM_CPU5 is wrong; it's going TO the CPU

The net with the label FROM_CPU5 is not driven by the CPU. It is driven by BUFA and BYLY on page 1. It is connected to an input of the CPU and to inputs of the following gates: BOLO, BYDA, ANUJ, LAVO, MUZU and DECY.

Input 2 of SOBY is not CPU_WR, it comes from TUTU

In the top left of page 8 the second input of SOBY is labelled CPU_WR?, but it should be labelled TUTU, because it is connected to the output of TUTU on page 7 ("FF50" block). The signal from TUTU also connects to the CPU.

P10-P13

Sortie de KOLE connectée à P10_A.
Sortie de KYTO connectée à P11_A.
Sortie de KALE connectée à P13_D.

LYXE wrongly connected to LORU

On page 4, the first input of OR gate LYXE should be connected to the output of AND gate LAVY, not to LORU.

(Also, not really in issue, I noticed that the numbering of the inputs of LAVY is swapped: Input 1 is connected to CPU_WR2 and input 2 to FF46.)

SUKO/AOI_MUX_4 is not a mux

SUKO/AOI_MUX_4, found in STAT (21_VIDEO_CONTROL.png) is not a mux. It's possible, by design, to set more than one of its enabled signals to 1 (B0 together with any of B1-B3), so at the very least it's not used as a mux.

The "audio output" of channel 2 is not labelled

On page 15, there are no labels on the outputs of the four gates that produce the channel's output. For channel 1&4 those outputs are labelled CHn_OUTb (n=channel#, b=bit#). I would suggest bringing those gates in a ascending or descending order and label them like this:

  • AMOV: CH2_OUT3
  • ASOG: CH2_OUT2
  • ANYV: CH2_OUT1
  • ANAN: CH2_OUT0

Unlabeled CPU clock inputs

In the top left corner of page 1, there are four pairs of inverters. Namely:
BUFA and BYLY,
BOLO and BYDA,
BUDE and BEVA, and
BEKO and BAVY.

Each of those pairs drive a separate input of the CPU. There are no TO_CPU* labels indicating that. (I already mentioned BUFA and BYLY in #47.)

Knowing that they all drive clock inputs of the CPU explains why they show up in pairs: There may be a lot of gates inside the CPU that are driven by them.

TAME, TOMA

Sortie de TAME reliée à l’entrée 2 de TOMA uniquement.
Et donc, TOXE Q relié à TYFO D, TAME E2, TYTU E1 et TYNO E1.

AFUR and APUK have inverted clock input

I think that the DTFFs AFUR and APUK on page 1 trigger on the negative edge of ATAL_4MHZ. At least it must be the opposite edge that ADYK and ALEF are triggered on, because the clock/!clock signals are swapped in comparison.

P10, P11, P12 and P13 nets are mislabelled

On page 5, the output of KALE is wrongly labelled P13_C, it should be P13_D.
On the same page, the outputs of KOLE and KYTO are wrongly labelled P10_B and P11_B. They should be labelled P10_A and P11_A respectively.
P10_B, P11_B, P12_B and P13_B are all connected to each other directly at the IO ports. This connection is nowhere to be found in the schematics.

On page 2, the inputs of KERY all should have the _C suffix.

The label P10_B is widely used throughout the schematic. KOLE is not the driver of this net. KOLE drives P10_A as already mentioned above. I retraced the whole P10_B net but I wasn't able to find the actual driving cell.

There must be two types of tri-state driver cells; ones with high active and ones with low active enable inputs

If you look at page 36, the enable signal for the tri-state drivers in block "FF47 BGP" is !(CPU_RD2 && FF47), so they must be active when enable is low. Same goes for the tri-state driver HOPE on the top-right of page 9: !(CPU_RD && FF26)

On the other hand, on page 1 in block "FF04 DIV", the tri-state drivers are enabled by CPU_RD && FF04_FF07 && [...] (not inverted), so they are active when enable is high.

I marked on this picture how you can distinguish between those two types:
tawu_hope

I will report more tri-state drivers with low active enable signals in separate issues when I encounter them. Until you say stop. :)

TOBU Q

VONU D connecté à TOBU Q et non TOBU /Q.

Aussi, TOBU et VONU utilisent CLK5.

Window Map Lookup

SARY (Window Y Match) latch is clocked by TALU (1Mhz).
REJO = (SARY | INT_VLB | RESET_VIDEO2)

REJO is ANDed with Window X Match.

This would mean that the Window could be active during Vblank. It should probably be REJO = (SARY & ~(INT_VLB | RESET_VIDEO2))

Also SARY is only high for one line so there seems to be something missing to show the window on the following lines.

PYNU (Window active) = (NUNU | XOFO)
XOFO = ~(FF40_D5 & ~ATEJ & ~RESET_VIDEO)

This means it activates the Window when the Window is disabled by setting FF40_D5 to 0 which does not make sense.

PYNU is probably (NUNU & ~XOFO) which could be (NUNU & XACO)

Output of ATOK is missing a label that indicates where it is going

On page 18, the output of the inverter ATOK just ends in an arrow without a label. It is connected to the wave RAM. I believe it could be the low active output enable signal of the RAM (!OE), but I'm not 100% sure.

Please also see issue #12, otherwise you would likely disagree that the signal is low active.

Labels KUTU, KUPE, KUNU, (...) should reflect being driven by !Q output of FFs

On page 16 and 18 the nets labeled KUTU, KUPE, KUNU, KEMU, KYGU, KEPA, KAFO, KENO, KEJU, KEZA and JAPU are actually driven by the !Qoutputs of their respective counter cells. It would make things more clear -- especially on page 16 you can't see where the signals are coming from -- if the they were labeled like !KUTU or KUTU_!Q.

Signal !WAVE_RAM_RD should not be marked as low active

!WAVE_RAM_RD is generated on page 17 by the cell CAZU. It is inverted two times (by the NAND BENA and by CAZU), therefore it should be called WAVE_RAM_RD (without the line ontop).

It is used two other times on that page and one time on page 18.

Input 1 of NAXY is wrong

On page 4, input 1 of NOR gate NAXY is wrongly connected to Q output of LUVY. It should be connected to !PHI_OUT instead.

CAGE wrongly connected to VYPO

In the top right corner of page 6, CAGE is shown to have a connection to VYPO. This is not true.
In reality, the output of the inverter CAGE is only connected to the data input of DFF CUBA. There is no connection to VYPO. VYPO actually has P10_B as input.

Reports 17/11

Tanjent says:
-EJEX is an AND (confirmed)
-FYNO Q goes in EROX, not /Q (confirmed)
-ROLO and REFA are NANDs, not ANDs (confirmed)

All fixed, need to re-export PNGs.

Some "APU_WR" signals are labelled as "CPU_WR?"

I know this is pedantic and doesn't really change anything, because APU_WR and CPU_WR are basically the same signal with just a bit delay from the two inverters.
I followed the whole APU_WR net from its driver BOGY to confirm that the following cells that have an input labelled with CPU_WR? actually receive the signal APU_WR on that input:

BOPY
BOSU
BUPO
CAZE
COVU
DACO
DEBY
DEPU
DERY
DETA
DOSA
ENUF
EPYX
ETUC
EXUC
FOXE
GEJO
GERE
GETU
GOKO
HAGA
HAWU
HOSO
HUMO
JENU

Quelques corrections

Salut Furrtek. Je suis en train de simuler la partie PPU et j'ai trouve quelques erreurs dans les colonnes l-x et a-g:
-- tevo is or_3 and not nor_3
-- sacu is or_2 and not nor_2
-- tuvo is nor_3 and not or_3
-- ajep is nand_2 and not and_2
-- aver is nand_2 and not and_2
-- bota is nand_3 and not nor_3
-- bycu is nand_3 and not nor_3
-- care is and_3 and not or_3
-- xymu, besu, wusa, rejo, roxy, rupo, pynu, wuje and poky are NOR bistable and not or_2
-- lony and taka are NAND bistable and not and_2

NAND_BISTABLE
NOR_BISTABLE

En incluant tous ces changements, Je commence à voir le fonctionnement du PPU avec les 4 modes et aussi les accès mémoire sur 6 pixels au début suivi de 8 pixels. Je t'enverrai les fichiers vhdl une fois terminé, si ça t’intéresse.

Cells labelled "BUFFER?" could be just simple connections to the supply rails

In #21 I pointed out that that the net labelled P10_B is not driven by the cell KOLE like it is drawn in the schematic and that I couldn't find the actual driver. I think I found a simple answer for that issue. The cells that are labelled as "BUFFER?" in the schematic aren't any logic cells at all. (Except VAVE, see #22.) They are just simple connections to the supply rails (GND and VCC). The top connection is always GND, the bottom one always VCC:
supply

Here a few examples of things that can be driven by GND or VCC directly:

  • Bit 3 in register FF40 selects the address range of the background tile map.
    The possible ranges are $9800-$9bff and $9c00-$9fff. Bit 11 and 12 of those
    addresses are always 1. This perfectly fits with the net WEFE being connected
    to VCC, since it feeds into COXO and COVE on page 26, which drive those two bits.
    It makes no sense for WEFE to ever be something else than 1 in this location of
    the schematic.

  • On page 2 PESU drives the data inputs of the interrupt flag register. It makes sense for PESU being VCC, because then interrupts can clock in a 1 into their respective DFF3 at any time like they should be able to do.

  • On page 30 there are six DTFFs (XECU ... XADU) which don't need to be reset.
    Connecting VCC to their !RESET inputs makes sense here.

  • The IO pins on the right (P10, P11, P12, P13, SIN, SCK) have four connections each. I'm convinced those are from top to bottom:

    • !SET: 0 = "output: drive pin high"; 1 = "don't drive"
    • !PU: 0 = "enable ~22k pullup resistor"; 1 = "no pullup resistor"
    • IN: This is the input, so when the pin is undriven (!SET is 1 and RST is 0), then you can read the value that is externally put onto the pin (or by the pullup resistor).
    • RST: 0 = "don't drive"; 1 = "output: drive pin low"

    The !PU connections of the IO cells P10...P13 are all connected to the net labelled P10_B For this net being GND would make sense here, because those pins are normally inputs only. So having the pullup resistors enabled all the time seems reasonable. (The pullups go away when you power off the device, so they are indeed switchable!)

There are also some things that still confuse me though, like on page 25, in the top right corner, if RUNY is actually VCC, then this would mean that the tri-state drivers TAHY ... SEDU would always drive the data bus. Those are the bigger versions of tri-state drivers. Maybe they are not "power tri-states", maybe they are the opposite: Weak drivers. And they may be bigger because they contain two resistors.

There are two kinds of UNK3 cells: AND-OR and OR-AND

I spent some time staring at the metal and silicon layers of the following gates:

OR-AND ((A | B) & C)

image

When C is high, the inverter at the right of the cell is driven by A NOR B. When C is low, the path to GND from A NOR B is cut, and the input to the inverter is pulled high.

COHY, DUMO, DYBO, DAJU, DYLY, EHUJ, EFAK, and EGUV are all this type of cell.

AND-OR ((A & B) | C)

image

When C is low, the inverter at the bottom of the cell is driven by A NAND B. When C is high, the path to VCC from A NAND B is cut, and the input to the inverter is pulled low.

TYNU, LOXO, LAGU, BYHA, and WYJA are all this type of cell.

VAVE is an inverter

On page 21, VAVE is labelled as "BUFFER?". It is actually an inverter. This works because the tri-state drivers that are connected to VAVE have an active low enable input. The others, driven directly by TOBE, have an active high enable input. See #11. I think that was your dilemma that caused you to think VAVE can't be inverting.

CLKIN_A can't actually be a clock

On page 1 CLKIN_A is fed into UFOL which drives the !RESET_DIV signal. If CLKIN_A were a clock, then it would constantly reset the DIV register. I simulated the first page with icarus and if I feed in a clock on CLKIN_A it just messes up the 1 MHz clock BOGA1MHZ, giving it an irregular pattern. With some gate timing it even makes it a 5 MHz clock, because the clock coming from BUTO is a 1 MHz clock with very short high phases. You can align it just right so that those slim peaks fit in the middle of every fourth low phase of the 4 MHz coming from CLKIN_A.

I remember from my experimentation on a real device, when you stop the clock of the Game Boy, after some time the data or address bus (I can't remember precisely) suddenly stops driving. So there's a reset happening (at least a partial one) when the clock stops ticking. My guess is that this behavior is controlled by CLKIN_A, which is generated directly at the external CLK input pin. Maybe this small circuit there detects when the oscillator has stabilized.

The three places where CLKIN_A is used support that theory. Imagine CLKIN_A actually means CLK_IS_STABLE:

  • In the top center of page 1 the complement of CLKIN_A is or'ed with the clock coming from BUTO. So only when the "CLK_IS_STABLE" signal (aka. CLKIN_A) is high, the clock from BUTO can pass through the OR gate BYJU. As long as it is low, BOGA1MHZ just stays high, preventing it from ticking until the oscillator has fully stabilized after power up.
  • In the middle of page 1 its complement is obviously used for resetting DIV. Making it reset when the clock is not stable, so to say.
  • In the bottom right of page 1 its complement is again or'ed with the reset signal.

I would suggest renaming CLKIN_A to something like CLK_IS_STABLE and CLKIN_B to just CLK_IN. This would make things more clear.

Label FROM_CPU is wrong; should be !T1_T2

The gates APYS on page 5 and EFOP on page 9 each have the label FROM_CPU at one of their inputs. This label is wrong. It should be T1T2 with a line over T1 but not over T2:

__
T1T2

First input of GEDO is wrong

On page 18, the first input of the AND gate GEDO is wrongly connected to BUFY_256Hz. It should be connected to the Q output of the DTFF FEXU.

I noticed that the "length timer" circuit at the bottom of page 18 only had inputs, but not even a single output. This would render it useless. Now, with FEXU signaling GEDO it is able to disable the wave player after the length timer overflows.

AFER gets clocked by BOGA

On page 1, the clock input of AFER should be driven by BOGA, not BOMA. BOMA drives the inverse clock input though.
So in the schematic BOGA should either be connected directly to AFER, or the clock input should get a circle to indicate negative edge trigger.

Sprite X matchers

Thanks for your work creating the schematics.

It looks like the 6th from the left sprite X matcher WUNU and WOFO signals are reversed. WOFO is the output when count is 4 from the 0-A counter but it goes into reset instead of clk.

Also is it correct that OAM_A_D7-0 is XOR'ed with inverted H7-0? How does that work?

FF0F_RD and FF0F_WR are active low

FF0F_RD and FF0F_WR generated on page 7 by ROLO and REFA are active low signals. They should be called !FF0F_RD and !FF0F_WR. They are used on page 2.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.