snes9xgit / snes9x

Snes9x - Portable Super Nintendo Entertainment System (TM) emulator
http://www.snes9x.com
Other
2.69k stars 463 forks source link

Request: 256kb SRAM. #714

Open Myself086 opened 3 years ago

Myself086 commented 3 years ago

I am working on a NES emulator for SNES and the next update will support up to 256kb SRAM. Snes9x supports up to 128kb. Most of my users reported using Snes9x as their SNES emulator of choice for trying out my NES emulator. 128kb doesn't completely break my NES emulator because this extra space is only used for dynamic memory allocation.

I have tested SRAM on multiple SNES emulators. 256kb is the most amount I've seen and is somewhat common.

qwertymodo commented 3 years ago

I don't believe Snes9x is limited to 128kb. Looking at the higan db, there are over 30 SNES games with 256kb of SRAM, and there are several SuperFX games with 512kb, all of which are supported. Are you properly setting the SRAM size byte in the internal header?

Myself086 commented 3 years ago

It may be an issue with HiROM then?

I tested sizes 4 to 10 (16kb to 1mb) on various emulators and this one defaults to 128kb when set to anything higher. Some emulators/devices that passed size 8 (256kb) test are: Bsnes, Mesen-S, SD2SNES.

Here are the ROMs I made for testing SRAM Snes SRAM test.zip

What the test does:

EDIT: I meant kilo bytes, not kilo bits.

qwertymodo commented 3 years ago

Interesting. It seems like SRAM is getting properly mapped everywhere it should for HiROM, so I'm not sure what's going on: https://github.com/snes9xgit/snes9x/blob/master/memmap.cpp#L2815

snes9x_hirom_256k_sram

Myself086 commented 3 years ago

I meant 256 kilo bytes. Open test 8 in the zip. I tested on v1.60 and I only got 1 row of O's when it should be 2 rows. Tests 9 and 10 also show only 1 row of O's.

image image

qwertymodo commented 3 years ago

Do you have the source code for that test ROM handy? It looks like something is wrong with the test, bsnes+ won't even display anything at all. Also, minor aside, the .smc file extension is meant to denote Super MagiCom files, which include an additional copier header at the beginning. Proper unheadered ROMs like the ones you're generating should use the .sfc extension instead.

Myself086 commented 3 years ago

Bsnes+ v05 (non-accuracy) shows the following for me:

Test 8 on regular Bsnes works fine.

I do have the source code but I'm using a private assembler that I have yet to release. Do you still need it?

It looks like the black screen only happens with the accuracy version. I'll fix that real quick.

Myself086 commented 3 years ago

Fixed Snes SRAM test.zip

qwertymodo commented 3 years ago

It's been awhile since I've touched any of the memory mapping code, so it might be helpful to see the code as well as viewing the results on screen. I'm not worried about it targeting a private assembler, since you already provided binaries.

qwertymodo commented 3 years ago

Ok, I see where the problem is (at least part of it). We are hard-coding a 128Kbyte limit on SRAM size. Here it is when saving the .srm file: https://github.com/snes9xgit/snes9x/blob/master/memmap.cpp#L2043 but obviously it's also happening somewhere else too, because it affects the mapping at runtime, even before the .srm file is created.

Myself086 commented 3 years ago

Here's the only part of my code accessing SRAM.

Assembler symbol meaning: $ address instead of hex . 1 byte _ 2 bytes = 3 bytes

Low bank refers to 0x00-0x3f High bank refers to 0x80-0xbf

    .mx 0x00
    .func   Main
Main:
    rep #0x30
    .local  =addr, .dummy, _temp

    // Write unique data to each SRAM bank
    lda #0x7ffe
    sta $.addr+0
    ldx #0x0000
b_loop:
        // Low bank
        txa
        eor #0x000f
        ora #0xf000
        sta $.addr+2
        sta [$.addr]

        // High bank
        ora #0xf080
        sta $.addr+2
        sta [$.addr]

        // Next
        inx
        cpx #0x0040
        bcc $-b_loop

    // Test banks
    ldy #0x003f
b_loop:
        // Low bank tile offset
        tya
        and #0x00f0
        sta $.temp
        tya
        clc
        adc $.temp
        asl a
        adc #0x0210
        tax

        // Test low bank
        tya
        ora #0xf000
        sta $.addr+2
        eor [$.addr]
        bne $+b_else
            lda #79     // O
            bra $+b_1
b_else:
            cmp #0x0100     // Test second byte
            bcc $+b_else2
                lda #88     // X
                bra $+b_2
b_else2:
                lda #61     // =
b_2:
b_1:
        sta $=Var_TileMap,x

        // High bank tile offset
        txa
        clc
        adc #0x0180     // 6 more lines under low
        tax

        // Test high bank
        tya
        ora #0xf080
        sta $.addr+2
        eor [$.addr]
        bne $+b_else
            lda #79     // O
            bra $+b_1
b_else:
            cmp #0x0100     // Test second byte
            bcc $+b_else2
                lda #88     // X
                bra $+b_2
b_else2:
                lda #61     // =
b_2:
b_1:
        sta $=Var_TileMap,x

        // Next
        dey
        bpl $-b_loop
qwertymodo commented 3 years ago

Yeah, there are a whole bunch of places where maximum SRAM size is assumed. Even some places like in netplay where it's set to 64Kbyte max: https://github.com/snes9xgit/snes9x/blob/master/server.cpp#L1172

So, this seems... very wrong. If I'm reading the memory map correctly, LoROM can have as much as 448Kbyte SRAM mapped from $70-7D:$0000-7FFF, and HiROM can have up to 256Kbyte SRAM mapped $20-3F:$6000-7FFFF

I have a fix that produces the right results in your test ROM, but I need to do some further testing to confirm it doesn't break anything else. I should probably also look into the LoROM mapping while I'm at it, because there's no way we're properly supporting the full range there.

qwertymodo commented 3 years ago

I went ahead and pushed my changes. These affect some fairly low-level mapping code, so I really hope this won't break anything. Once the CI builds complete you should be able to download test builds here:

32-bit 64-bit