mist-devel / mist-board

Core sources and tools for the MIST board
444 stars 81 forks source link

[C64] implement 2Mhz CPU speed for C128 running in C64 mode #101

Open nippur72 opened 5 years ago

nippur72 commented 5 years ago

there are some games (notably the new "Super Mario Bros") that are able to take advantage of the 2Mhz CPU speed that you can get when running the C128 in C64 mode.

I think it would be nice if we have this option in the MiST core too (e.g. "Enable 2Mhz 8502: Off;On;")

I tried to code it myself but got lost in the fine details of the state machine, sysCycleDef and the intricate jungle of enable signals. I thought it would be as easy as adding an extra CPU cycle, but of course it wasn't.

Summary of the 2Mhz mode:

When running at 2Mhz, the VIC-II can't cope with the new speed and displays garbage in the active area, but borders are ok. Games usually enable it during the blanking/border periods.

All other chips receive an effective 1Mhz frequency:

[...] the system employs an elaborate technique known as clock stretching, where the clock period is extended to create an effective 1-MHz rate for the portion of the clock cycle when the I/O chip is being accessed.

gyurco commented 5 years ago

It'll also affect SDRAM timings, not sure if the current controller can cope with that. Also it shouldn't clash with VIC II memory access, so if 2MHz is enabled, VIC II should be disabled. Then the VIC memory cycle can be used for the 8502.

harbaum commented 5 years ago

As far as i understand this would not need ram timing changes. Instead the cpu just also gets the vic memory slots assigned. The vic would then just display garbage while the cpu is running at 2 Mhz which also happens on the real c128 in c64 mode.

So in thery there shouldn't be many things to change. But i am not sure it's worth tje effort and even less the confusion this option may cause with many users.

gyurco commented 5 years ago

Yepp, probably it's enough to have a second cpuEnable together with enableVic, but set cpuHasBus to 1 in the VIC II cycle, too.

gyurco commented 5 years ago

Experimented with turbo mode, but at the end you have to switch back to 1 MHz mode if the CPU does IO to CIA, SID, etc... because at 2MHz these can miss reads and writes. And also have to adjust these peripherals CE (do the clock stretching). The result however was not very reliable, so at the end I gave up on this.

juri74 commented 5 years ago

i had a quick look at c128 schematics, looks like the cpu is always clocked at 2mhz, i have to verify this with an oscilloscope, the 2mhz line go to MMU too, then there are some logic chips that drive the RDY signal of cpu, i think that when in 1mhz mode the cpu is somehow halted for 1 cycle, so it is acting like is feeded with 1 mhz clock. i found this interesting article about pheriperal driving with 2mhz 6502 http://6502.org/mini-projects/rdy-generation/index.html

gyurco commented 5 years ago

Halting with RDY is not the same as giving it a 1 MHz clock, for example RDY doesn't stop a write cycle.

juri74 commented 5 years ago

ok i investigated a little further, the cpu is not actually clocked @2mhz forever, and when the cpu is "forced" @2mhz (for example using FAST command on c128) it do not stay @2mhz forever, the clock line return @1mhz during dynamic ram refresh and during i/o access. some interesting infos are found in C128 service manual (pag 33 and 34): http://zetaweb.org/web/manuals/C128%20Service%20Manual.pdf

gyurco commented 5 years ago

That make sense, actually that's what I deduced. But not trivial to implement.

gyurco commented 3 years ago

I finally added this feature. Looks like the 1541 doesn't work with it, I wonder if it's the same with a C128 - 1541 combo.