GideonZ / 1541ultimate

Official GIT archive of 1541 ultimate II sources
GNU General Public License v3.0
173 stars 45 forks source link

Feature request: a pseudo C128 64 mode configuration option #301

Open Jusalak opened 1 year ago

Jusalak commented 1 year ago

I tried the Turbo Enable bit on U64 and found that it already works as the 2MHz bit of C128.

It immediately came to mind whether a configuration option could be implemented which would make U64 to imitate the 64 mode of a C128. The 2Mhz trick is implemented by some programs when the raster is in the upper or lower border area. The only question would be to fool programs to deduce they are running on a 64 mode of C128. VICIIe registers $d02f and $d030 of C128 are commonly used to detect this. Could C128 behaviour of these registers could be emulated by a configuration option? C128 extra keys are mapped to $d02f (if wished, could be implemented using USB keyboard), and $d030 has the turbo bit and test bit, the latter bit could be simply ignored (as does VICE).

C128 second RAM bank, MMU and Z80 are not accessible in the 64 mode. The only other major difference is the C128 VDC at $d600. Implementation is obviously unrealistic of course, so could be simply omitted (some 64 mode programs use the VDC display memory as a memory expansion, so memory copy commands between VDC and C64 memory would already be something).

But disregarding the VDC, otherwise a C128 64 mode seems only a few steps away, and would be nice as such.

Jusalak commented 11 months ago

C128 steals some cycles when 2MHz/1MHz is made. I made a comparison of timings U64 2 MHz turbo mode (setting: TurboEnable Bit/2 MHz) with a C128 64 mode, along with emulators VICE (x128) and Z64K. Z64K gives the same result as real hardware (bottom colour change at position 26), but x128 and U64 run a bit faster than C128 in 64 mode (bottom colour change more to the left (position 22)). Interestingly, U64 and x128 give the same result.

` * = $c000 sei ;set up raster interrupt lda #$7f sta $dc0d lda $d01a ora #$01 sta $d01a lda $d011 and #$7f sta $d011 lda #$32 sta $d012 lda $d019 sta $d019 lda #<interrupt sta $0314 lda #>interrupt sta $0315 lda #$02 sta $d020 cli wait: jmp wait rts

interrupt ;interrupt handler lda $d020 and #$0f cmp #$02 beq _int2 lda #$32 sta $d012 lda #$ff sta $d019 lda #$01; spend some time switching between 1 and 2 MHz sta $d030 nop nop nop nop lda #$00 sta $d030 nop nop nop nop
lda #$01 sta $d030 nop nop nop nop lda #$00 sta $d030 nop nop nop nop lda #$01 sta $d030 nop nop nop nop lda #$00 sta $d030 nop nop nop nop lda #$01 sta $d030 nop nop nop nop lda #$00 sta $d030 nop nop nop nop lda #$01 sta $d030 nop nop nop nop lda #$00 sta $d030 lda #$02 sta $d020 jmp $ea7e _int2: ;the other line lda #$fc sta $d012 lda #$ff sta $d019 lda #$05 sta $d020 jmp $ea31 `

z64k2mhzraster vice2mhzraster 2mhzrastertiming.zip

GideonZ commented 11 months ago

Excellent find! I am more curious what happens AFTER that.. e.g. when changing from red to green and back or other colors. Does the real hardware become slower with every I/O cycle, or only when the switch occurs? How about cycles in between? A two cycle nop, a three cycle nop, etc.

Jusalak commented 11 months ago

A quick test showed that U64 timings are close to x128, but U64 is a bit ahead. With 2 MHz consumes more cycles on I/O-operations (clock stretching) and so consumes more cycles (Z64K matches real hardware). rastercolortest.zip z64krastercolortest x128rastercolortest

Jusalak commented 7 months ago

With U64 configuration options

Turbo Control: TurboEnable Bit CPU Speed: 2 MHz Badline Timing: Disabled

The demo Insomnia V1.1 ( https://csdb.dk/release/?id=2778 ) recoginizes the CPU as 8502

insomnia1

and the following part also runs noticeably faster:

insomnia2

For another demo, Desert Dream ( https://csdb.dk/release/?id=48039 ) this trick to tweak CPU detection does not work but is recognized as 6510.