|
Post by lunchbox on Feb 11, 2015 10:07:24 GMT -5
SO i looked around and from my understanding the Internal battery backed memory in the sega cd is known as BRAM? if this is the case, i saw a few places it was said that it would not be implemented due to the fact that it wasn't known how it works. Is this still the case across the homebrew community? Id REALLY love the ability to use sega-cd internal bram to hold a few variables for save games like unlocked items or points and name ect and unlocked levels.
If BRAM is indeed not ever going to be supported is there any other method that could be used? Sega cd Ram Backup cart im guessing would be the next step?
|
|
|
Post by lunchbox on Feb 12, 2015 0:15:49 GMT -5
|
|
|
Post by lunchbox on Mar 9, 2015 16:49:06 GMT -5
Does anyone have something like this implemented for bex? I only ask because id rather not go down the path of trying to make the above code work if someone already has something working that they might share.
|
|
|
Post by nathan999 on Jul 17, 2015 2:43:18 GMT -5
I've made experiments and it's relatively easy to write to the BBRAM, just check this simple code:
[
|
|
|
Post by nathan999 on Jul 17, 2015 2:46:51 GMT -5
I've made experiments and it's relatively easy to write to the BBRAM, just check out this simple code:
'' SRAM test!
option SEGACD Const #BASEBBRAM = &H600000
' Read 3 values from BBRAM... PRINT "READING 3 VALUES FROM BBRAM" Print BBRamRead(0) Print BBRamRead(1) Print BBRamRead(2) Print "WRITING 3 VALUES TO BBRAM" BBRAMWrite 0, 22 BBRAMWrite 1, 33 BBRAMWrite 2, 44 Declare Function BBRamRead(offs&) Return Peek(#BASEBBRAM + 1 + offs& + offs&) End Function
Declare Sub BBRamWrite(offs&, val%) Poke &H7FFFFF, 1 ' Write enable Poke #BASEBBRAM + 1 + offs& + offs&, val% Poke &H7FFFFF, 0 ' Write protect End Sub
This works. The first time it will read/print 0, 0, 0; then write 22, 33, 44. Then you reset the emulator (I use Kega Fusion), run it again, and it reads/prints 22, 33 44.
Problem is, there has to be any kind of already established format for binary blocks writen to the bram, so you can search for free space and not corrupt already existing saves. I can't find anything about this subject anywhere. I'll study the code provided above and do some tests in case I can figure out what's going on.
|
|
|
Post by nathan999 on Jul 17, 2015 4:09:34 GMT -5
I've examined the code (Sonic 1 for Sega CD) further and it seems that everything is achieved calling the Sega CD BIOS. My time is scarce, but maybe I can make a simple savegame handler. But don't expect anything anytime soon.
|
|
|
Post by nathan999 on Jul 17, 2015 5:04:36 GMT -5
This is what I've come up with, but it doesn't work.
I have to investigate this further. I know that the main CPU and the SUB CPU have different addressing maps, maybe that's the problem. I'm using main CPU addresses and this may need adjustment.
'' BRAM test! '' Will attempt to use SEGACD BIOS (somehow) ' Code has been generated using "Sonic 1 for Sega CD" as a basis & reference.
option SEGACD
Const #BASEHEADER = &HFFFFA0 Const #BASEDATA = &HFFFF00
' BIOS entry point: ' _BURAM EQU $00005F16 ' BIOS functions: ' BRMINIT EQU $0000 ' BRMSTAT EQU $0001 ' BRMSERCH EQU $0002 ' BRMREAD EQU $0003 ' BRMWRITE EQU $0004 ' BRMDEL EQU $0005 ' BRMFORMAT EQU $0006 ' BRMDIR EQU $0007 ' BRMVERIFY EQU $0008
' For VANE engine, we need to save 128 flags ' plus some other data. ' It seems that SEGA CD BURAM blocks are 32 bytes. ' So we need 1 block 'header' and 4 blocks 'flags' ' For the tests, let's imagine we have everything ' set up in a buffer in main RAM in &HFFFF00 ' We also need the 'header' somewhere, that's ' 11 chars - game name ' 1 byte 0 ' 1 byte 0 - block size is $20 bytes ' 1 byte 5 - block count. ' Header will be at $HFFFFA0 ' To call a BURAM BIOS function you move ' the function code to d0, then jsr _BURAM ' write some data Print "WRITE HEADER" writeHeader Print "WRITE DATA" writeData 'Print "CLEAR DATA" 'clearData Print "SHOW DATA" showData Print "INIT" buramInit Print "SAVE" buramSave Print "LOAD" buramLoad Print "SHOW DATA" showData Print "OK" Declare Sub showData For i&=0 to 31 Print Peek(#BASEDATA + i&);" "; Next i& Print End Sub Declare Sub writeHeader Reload headerData For i& = 0 To 13 Read d% Poke #BASEHEADER + i&, d% Next i& End Sub Declare Sub writeData For i& = 0 To 159 Poke #BASEDATA + i&, i& Next i& End Sub
Declare Sub clearData For i& = 0 To 159 Poke #BASEDATA + i&, 0 Next i& End Sub
' Init. Supposedly you have to call this first. ' For some reason it needs 640 bytes of scratch data. ' Okay. Declare Asm Sub buramInit ; #BASEHEADER == &H00FFFFA0 ; a0 pointer to $640 bytes scratch data. move.l #$00FFFFA0 - 1600, a0 ; a1 pointer to 12 bytes string buffer move.l #$00FFFFA0 - 1600 - 12, a1 ; d0 API function #0, INIT move.w #0, d0 ; Call BIOS jsr $00005F16 ; cs means not formatted... bcs.w BRAM_Format bra BRAM_Init_End BRAM_Format: ; d0 API function #6, FORMAT move.w #$6, d0 ; Call BIOS jsr $00005F16 BRAM_Init_end: End Sub ' Save needs a pointer to the header, and a pointer ' to the data itself. Declare Asm Sub buramSave ; #BASEHEADER == &H00FFFFA0 ; #BASEDATA = &H00FFFF00 ; a0 pointer to header (file name, header data) move.l #$00FFFFA0, a0 ; a1 pointer to save data (enough data, 5 blocks as described) move.l #$00FFFF00, a1 ; d0 API function #4, WRITE move.w #$4, d0 ; Call BIOS jsr $00005F16 End Sub
' Load needs a pointer to the header, and a pointer ' to the data itself Declare Asm Sub buramLoad ; #BASEHEADER == &H00FFFFA0 ; #BASEDATA = &H00FFFF00 ; a0 pointer to header (file name, header data) move.l #$00FFFFA0, a0 ; a1 pointer to save data (enough data, 5 blocks as described) move.l #$00FFFF00, a1 ; d0 API function #3, READ move.w #$4, d0 ; Call BIOS jsr $00005F16 End Sub
headerData: Data $45,$53,$50,$5F,$54,$49,$45,$5F,$52,$5F,$5F Data 0, 0, 5
I'm only posting this in case somebode seems something.
|
|
|
Post by nathan999 on Jul 23, 2015 2:34:45 GMT -5
Despite the lack of interest, this is interesting for me, so I've been researching futher. I'm calling the API using the right entry points, but it seems that I'm not passing the parameters right. I'm starting to believe that the registers involved are the second 68000 registers, not the main one's. There seems to be a gate array to communicate both processors.
With this knowledge in mind, I'll try to re-read the sources and try to understand how this all works.
|
|
|
Post by lunchbox on Jul 23, 2015 16:16:26 GMT -5
Despite the lack of interest, this is interesting for me, so I've been researching futher. I'm calling the API using the right entry points, but it seems that I'm not passing the parameters right. I'm starting to believe that the registers involved are the second 68000 registers, not the main one's. There seems to be a gate array to communicate both processors. With this knowledge in mind, I'll try to re-read the sources and try to understand how this all works. Nice!!! I'm certainly interested in it. i havnt had a bunch of time to follow lately but with some progress being made, im following now!! Ive been super busy myself writing code for another console but when i have some time i might be able to lend a hand in this project.
|
|
|
Post by nathan999 on Jul 28, 2015 7:15:30 GMT -5
Cool I am still clueless. The lack of proper documentation is overwhelming :-(
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jul 28, 2015 7:58:05 GMT -5
|
|
|
Post by lunchbox on Aug 9, 2015 11:31:47 GMT -5
Bump: Ive seen the docs myself but havnt played with anything in relation to them. Would be nice to enable the sub cpu and play around with that via bex too. Hell ultimately scaling via segacd would be awesome!! Also, cant mention scaling and segacd and not mention batman returns. Examples of how its done here in the SegaCD Batman returns source code.... www.shrigley.com/codearc/Batman_Returns_SegaCD_Project_Package.zip
|
|
|
Post by landeel on Oct 6, 2015 19:35:04 GMT -5
I'm very interested in this. Any news?
|
|
|
Post by lunchbox on Oct 26, 2015 9:12:16 GMT -5
Nathan, you make any headway on this? if not where did you leave off?
Maybe post what you were calling and see if we can debug this stuff here. Might need a snippet of asm to call or or something. I would assume if the sub cpu registers are being referenced that something has to be toggled prior to being able to read them.
|
|
|
Post by nathan999 on Oct 29, 2015 6:15:18 GMT -5
Sorry, I'm currently busy with completely different affairs. This is the code I was testing:
'' BRAM test! '' Will attempt to use SEGACD BIOS (somehow) ' Code has been generated using "Sonic 1 for Sega CD" as a basis & reference.
option SEGACD
Const #BASEHEADER = &HFFFFA0 Const #BASEDATA = &HFFFF00
' BIOS entry point: ' _BURAM EQU $00005F16 ' BIOS functions: ' BRMINIT EQU $0000 ' BRMSTAT EQU $0001 ' BRMSERCH EQU $0002 ' BRMREAD EQU $0003 ' BRMWRITE EQU $0004 ' BRMDEL EQU $0005 ' BRMFORMAT EQU $0006 ' BRMDIR EQU $0007 ' BRMVERIFY EQU $0008
' For VANE engine, we need to save 128 flags ' plus some other data. ' It seems that SEGA CD BURAM blocks are 32 bytes. ' So we need 1 block 'header' and 4 blocks 'flags' ' For the tests, let's imagine we have everything ' set up in a buffer in main RAM in &HFFFF00 ' We also need the 'header' somewhere, that's ' 11 chars - game name ' 1 byte 0 ' 1 byte 0 - block size is $20 bytes ' 1 byte 5 - block count. ' Header will be at $HFFFFA0 ' To call a BURAM BIOS function you move ' the function code to d0, then jsr _BURAM ' write some data Print "WRITE HEADER" writeHeader Print "WRITE DATA" writeData 'Print "CLEAR DATA" 'clearData Print "SHOW DATA" showData Print "INIT" buramInit Print "SHOW DATA" showData Print "SAVE" buramSave Print "CLEAR DATA" clearData Print "SHOW DATA" showData Print "LOAD" buramLoad Print "SHOW DATA" showData Print "OK" Declare Sub showData For i&=0 to 31 Print Peek(#BASEDATA + i&);" "; Next i& Print End Sub Declare Sub writeHeader Reload headerData For i& = 0 To 13 Read d% Poke #BASEHEADER + i&, d% Next i& End Sub Declare Sub writeData For i& = 0 To 159 Poke #BASEDATA + i&, i& Next i& End Sub
Declare Sub clearData For i& = 0 To 159 Poke #BASEDATA + i&, 0 Next i& End Sub
' Init. Supposedly you have to call this first. ' For some reason it needs 640 bytes of scratch data. ' Okay. Declare Asm Sub buramInit ; #BASEDATA = &H00FFFF00 ; a0 pointer to $640 bytes scratch data. move.l #$00FFFF00 - 1600, a0 ; a1 pointer to 12 bytes string buffer move.l #$00FFFF00 - 1600 - 12, a1 ; d0 API function #0, INIT move.w #0, d0 ; Call BIOS jsr $00005F16 ; cs means not formatted... bcs.w BRAM_Format bra BRAM_Init_End BRAM_Format: ; d0 API function #6, FORMAT move.w #$6, d0 ; Call BIOS ;jsr $00005F16 BRAM_Init_end: End Sub ' Save needs a pointer to the header, and a pointer ' to the data itself. Declare Asm Sub buramSave ; BRAM_Enable bsr m_SubUnHalt ; #BASEHEADER == &H00FFFFA0 ; #BASEDATA = &H00FFFF00 ; a0 pointer to header (file name, header data) move.l #$00FFFFA0-$180000, a0 ; a1 pointer to save data (enough data, 5 blocks as described) move.l #$00FFFF00, a1 ; d0 API function #4, WRITE move.w #$4, d0 ; Call BIOS jsr $00005F16 End Sub
' Load needs a pointer to the header, and a pointer ' to the data itself Declare Asm Sub buramLoad ; BRAM_Enable bsr m_SubUnHalt ; #BASEHEADER == &H00FFFFA0 ; #BASEDATA = &H00FFFF00 ; a0 pointer to header (file name, header data) move.l #$00FFFFA0-$180000, a0 ; a1 pointer to save data (enough data, 5 blocks as described) move.l #$00FFFF00, a1 ; d0 API function #3, READ move.w #$3, d0 ; Call BIOS jsr $00005F16 End Sub
Declare Asm Sub haltStuffContainer m_SubHalt: move #$2700,sr bset #1,($A12001).l beq m_SubHalt rts
m_SubUnHalt: bclr #1,($A12001).l bne m_SubUnHalt rts End Sub
headerData: Data $45,$53,$50,$5F,$54,$49,$45,$5F,$52,$5F,$5F Data 0, 0, 5
Maybe you can build upon this simple foundations?
|
|