Video Game custom chips reverse-engineered from silicon.
A few other people do this too, but these are from me :3
Custom chips reverse-engineered from silicon
License: GNU General Public License v2.0
It looks like signal W31 will enable register writting. But it is not clear when the register data can be read by the M68K. It looks like registers 1 and 0 can be read (and 0xd 0xe during test) but what triggers that read? Is it W31 paired with the CPU read signal?
I think that the polarity, or maybe just the label polarity, for PIN_CSX signals is the other way around.
The way it is now, when the enable signal N18 is low, all PIN_CSX will be asserted. I think it makes sense for the labels to be the other way around: /PIN_CSX at the output of the NAND and PIN_CSX at the inverter output.
I also suggest to rename N18 to PIN_CS_EN
PINS_AD_DIR on page 9 seems undriven.
These are important signals whose driver has not been labelled
RES2
RES3
CLK4
For banks 0,1, 4, 5, 6 and 7, PIN_A2_IN is used for generating the CS signal, whereas for banks 2 and 3, PIN_A16_IN is used. I don't think the system can work if A2 is used. Indeed, I have tried modifying the code so A2 is checked:
for( aux=0; aux<8; aux=aux+1 ) begin
case( mmr[ {1'b1, aux[2:0], 1'b0 } ][1:0] )
0: active[aux] = { addr[23:17], aux==2 || aux==3 ? addr[16] : addr[2] } == mmr[ {1'b1, aux[2:0], 1'b1 } ]; // 64 kB
1: active[aux] = addr[23:17] == mmr[ {1'b1, aux[2:0], 1'b1 } ][7:1]; // 128 kB
2: active[aux] = addr[23:19] == mmr[ {1'b1, aux[2:0], 1'b1 } ][7:3]; // 512 kB
3: active[aux] = addr[23:21] == mmr[ {1'b1, aux[2:0], 1'b1 } ][7:5]; // 2048 kB
endcase
end
You can see it in the case option 0. I tried several games but none booted. I think it must be PIN_A16_IN for all of them.
While simulating your models for this pair of chips, I found that the master chip starts the scaling count on SPR_ZX_ACC before the drawing part starts rendering. So the CARY signal gets a bit ahead of time. Not only that, but the SPR_ZX_ACC loads the next sprite data before the current one is completely rendered, which has the effect of potentially missing some CARY assertions for the last few pixels.
The whole file with the waveforms is here.
Whether this is the real behavior or just some logic missing between these two parts, I don't know. But I thought it was worth mentioning it, in case you have seen funny behaviour related to the scaling logic.
These are the simulation files:
The / bar on top of DTACK_SEL signals is wrong on page 12. At the output of inverter M85, it should be /DTACK_SEL0, and then DTACK_SEL0 at the output of S99. Then the signals at the input of S105 (same page) should have the / swapped too. Otherwise, the comment on top of S105 does not hold true. As it is now, the S105 output is 1-clock delay for DTACK_SEL=3, for instance.
I am debugging weird sprite glitches on Aliens. They seem to be related to how the sprite DMA logic works. What I get from your RE research is that at the VB edge the active-low DMA enable register is latched (bit 4 of REG0), and from that moment on, the DMA triggers: an internal RAM buffer is cleared and then filled with the relevant sprite data for the next frame.
But Aliens sets REG0[4] high right after the VB interrupt and it starts writting to the sprite RAM soon after. According to the RE schematics/verilog, it looks like REG0[4] is ignored after the VB edge, which means that the DMA will run side by side with the CPU writting to the memory. The effect is that occasionaly corrupted data is shown on screen.
The waveforms show how REG0[4], called obj_enb in the sim, is always set for each sprite RAM update cycle. Check out the orange (CPU writes to sprite RAM) and red (obj_enb) waveforms. Also notice how the sprites are only updated every other frame.
obj_enb is set low again some 375us before the end of the blanking period. That's too short to copy the data to the internal buffer as just clearing the buffer takes 341us. Maybe the clearing can occur in parallel but copying the new data must wait for obj_enb to be low again? That would make more sense than leaving the old sprite data in the buffer and drawing it again.
So I do not know what is going on at the moment, but it looks weird. Maybe the flip flops you shown are actually level-enabled latches and the logic works in a different way?
Naming is wrong.
I am looking into the sprite issues of TMNT and noticed that the line buffer switches much too late, after the first sprite has already started rendering.
The PAIR (AN106) signal is generated from the delayed nNEWLINE signal (NEWLINE_DELAY[6]) and then even more delayed to AN15_DELAY[4]. These delays causes PAIR to toggle on HCNT 43 while the first sprite starts rendering at HCNT 35.
IMO the PAIR signal should toggle immediately when nNEWLINE goes low so I don't understand these delays.
The HV counters and nNEWLINE signal are already delayed by 8 pixels compared to K051960 because of HVIN_DELAY. If this wasn't the case then I could understand why the PAIR signal is delayed.
I have looked at the schematics but they seem to match the Verilog for these signals.
pin_br_out appears as a fixed low, which would stop the M68000 forever as that is the bus request signal.
The /pin_br_en doesn't go anywhere either.
A similar story applies to BGACK.
We are extracting the schematics for the SEGA System 18 PCB. We've found that the way signals go to the JAMMA connector seem to have RED and GREEN swapped with respect to the schematic you made below. I wonder whether it is updated, or whether there is some room for doubts about it. Thanks.
https://github.com/furrtek/VGChips/blob/master/Sega/315-5242/315-5242_schematic.png
COUNTER3 and COUNTER2 outputs are labelled as CK24/xx, which seems to suggest a clock divider. This actually seems to be a pixel counter. COUNTER2 is the LSB, COUNTER3 is the MSB. It counts from $40 to $FF, a total of 192 H0 counts, which is 384 pixels.
I think that a line is made of 384 pixels, and that the pixel clock is 6MHz, (384/6MHz=64us, the expected value for the line period).
So this counter divides the line in two parts. I suggest renaming the outputs to
CK24/32 -> HN1
CK24/64 -> HN2
CK24/128 -> HN3
CK24/256 -> HN4
CK24/2 -> HN5
CK24/4 -> HN6
Q2 (unlabelled) -> HN7
CK24/16 -> HN8
I think this change will help understand the blanking shift register among other things. As HN8 (CK24/16) is its input.
Maybe we could just keep COUNTER3/2 as the cell name, but give the instances a more meaningful name too.
I suggest renaming these signals:
W10 -> SCR_SEL selects the scroll pixel over the sprite one
CC39 -> SPR_AREA (marks the part of the screen where sprites are allowed)
Hi, would it be possible from the logic of the circuit to extract the values of the video signal to generate a modeline, the porches, the sync pulses the pixelclock etc etc?
It would be very interesting to generate video modes for CRT emulation projects.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.