PCEngineFans.com - The PC Engine and TurboGrafx-16 Community Forum

Tech and Homebrew => Turbo/PCE Game/Tool Development => Topic started by: Bonknuts on May 05, 2016, 04:46:11 PM

Title: BRAM Library
Post by: Bonknuts on May 05, 2016, 04:46:11 PM
I know there are some existing libs out there for BRAM support (HuC), but I've written a set of my own. I'm just cleaning everything up and reducing the code/data/bss/zp footprint. This is mostly for Hucard projects, but it should be compatible with any CD project as well.

 I tried to offer a little more support than what the syscard bios funcs provided. I know mednafen had an option to allow up to 8k of BRAM. So I added compatibility for that, as well as upgrading the BRAM header to 8k size. BRAM doesn't mirror, so it should work in theory. IIRC, Ryphecha said one game didn't like it (but only one). I know people have been talking about making BRAM boosters for their systems, so would work with that - if that ever comes to pass (larger than 8k).
 
 I going to do some tests over the next couple of days and then I'll release the lib. I would definitely appreciate feedback on it (suggested support, interfacing, etc).




Edit: (old)
Ok, I was wondering if anyone out there with some experience with bram interfacing could help out?

 I have Dragon Warrior for the PCE that I promised to release for Bernie, but I don't want to release it without BRAM support. I have very-very little time, so I'm seeing if anyone else could help out with the explanation of how to interface with it (the save file interfacing)? I also remember someone (Ccovell?) saying that HuC had a bug in one of its support functions.

 Anyone interested in helping out?
Title: Re: BRAM support
Post by: Bonknuts on May 05, 2016, 08:18:22 PM
So, here's the info I gathered so far:

 The bram entries are made up of ID num + text header; the FCB. The BRAM search function has a pointer to this ID in BX (ID for compare is in local memory). I'm not quite sure what _AL is (number of file from top=1), but I'm guessing that's the number of instances of this ID string?

 So it appears BRAM Write is also for creating new files as well as updating existing ones.

 So something like BRAM search (pointer, instance). If exists (call $1D returns $00), then update it (call $1B with pointer to data and ID), if not - check for free memory (call $19 returns amount in CX). If enough, write update (call $1B with pointer to data and ID).

 Edit: Also, I'll need some brave souls to try out this Dragon Warrior BRAM stuff. Any takers?
Title: Re: BRAM support
Post by: MooZ on May 05, 2016, 11:31:40 PM
Dude, I'm knee deep into BRAM atm :)
The BRAM starts with a 16 bytes header.[ul][li]00-03 - Header tag (equals to "HUBM")[/li][li]04-05 - Pointer to the first byte after BRAM storage[/li][li]06-07 - Pointer to the next available BRAM slot (first unused byte)[/li][li]08-0f - Reserved (set to 0).[/li][/ul]A BRAM entry is formatted as follow:
[ul][li]00-01 - Entry size. This size includes the 16 bytes of the entry header[/li][li]02-03 - Checksum. The checksum is the sum of the entry bytes starting from byte #4 (i.e all bytes except the entry size and checksum). The value stored is the opposite of the computed checksum. This way the consistency check only consists in adding the stored checksum and the newly computed one. If this sum is 0, the entry is valid[/li][li]04-0f - Entry name.[ul][li]00-01 - Unique ID[/li][li]02-0b - ASCII name padded with spaces[/li][/ul][/li][/ul]
If I understood what was written in the Develo Book, the bm_files routine of the system card fetches the nth entry (n stored in _al). _bx stores the address where the entry information will be stored (id,name,size). At the end _si will contain the address of the matching entry.
Title: Re: BRAM support
Post by: nodtveidt on May 06, 2016, 12:13:03 AM
The bug was/is in bm_delete().
Title: Re: BRAM support
Post by: ccovell on May 06, 2016, 01:24:51 PM
I think there's a HuC/MKit library interface in my BRAM manager that you can use. 

Also, one thing I suspect is that the HuC BRAM_Detect / Unlock code may be faulty (at least the version that I have.)  It writes $80 to $1807, when it really needs to write $48,$75,$80 to that register.  CD systems work with the faulty code, but TennoKoe2s don't.
Title: Re: BRAM support
Post by: Bonknuts on May 06, 2016, 04:21:22 PM
I think there's a HuC/MKit library interface in my BRAM manager that you can use. 

Also, one thing I suspect is that the HuC BRAM_Detect / Unlock code may be faulty (at least the version that I have.)  It writes $80 to $1807, when it really needs to write $48,$75,$80 to that register.  CD systems work with the faulty code, but TennoKoe2s don't.

 Ohh, that's good to know. For DW, I'll be using the syscard functions, but for the hucard version and two other nes2pce hucards, I'll need to directly access bram.
Title: Re: BRAM support
Post by: Bonknuts on May 07, 2016, 07:17:19 AM
Dude, I'm knee deep into BRAM atm :)
The BRAM starts with a 16 bytes header.[ul][li]00-03 - Header tag (equals to "HUBM")[/li][li]04-05 - Pointer to the first byte after BRAM storage[/li][li]06-07 - Pointer to the next available BRAM slot (first unused byte)[/li][li]08-0f - Reserved (set to 0).[/li][/ul]A BRAM entry is formatted as follow:
[ul][li]00-01 - Entry size. This size includes the 16 bytes of the entry header[/li][li]02-03 - Checksum. The checksum is the sum of the entry bytes starting from byte #4 (i.e all bytes except the entry size and checksum). The value stored is the opposite of the computed checksum. This way the consistency check only consists in adding the stored checksum and the newly computed one. If this sum is 0, the entry is valid[/li][li]04-0f - Entry name.[ul][li]00-01 - Unique ID[/li][li]02-0b - ASCII name padded with spaces[/li][/ul][/li][/ul]
If I understood what was written in the Develo Book, the bm_files routine of the system card fetches the nth entry (n stored in _al). _bx stores the address where the entry information will be stored (id,name,size). At the end _si will contain the address of the matching entry.

 This seems easy enough. I should be able to write my own interface code.

 So what about the linked list system? Is there a WORD pointer at the end of an entry?
On that note: does the system card take care of defragmenting the entries?
Title: Re: BRAM support
Post by: TheOldMan on May 07, 2016, 08:19:19 AM
Quote
So what about the linked list system? Is there a WORD pointer at the end of an entry?

Don't believe so. It adds up the entry sizes. Recognizes list end by comparing to next available byte.

Quote
On that note: does the system card take care of defragmenting the entries?

<lol>. No, I don't think it does.
Title: Re: BRAM support
Post by: TheOldMan on May 07, 2016, 08:40:57 AM
Quote
On that note: does the system card take care of defragmenting the entries?

I take my comment back. I just checked, and it looks like it shifts the directory/data blocks backwards, over writing the old data, and adjusts the available pointer.

Must have been thinking of the HuC version....
Title: Re: BRAM support
Post by: Bonknuts on May 08, 2016, 07:12:30 AM
Quote
On that note: does the system card take care of defragmenting the entries?

I take my comment back. I just checked, and it looks like it shifts the directory/data blocks backwards, over writing the old data, and adjusts the available pointer.

 Cool. I think I have all the info that I need (and it all checks out from looking at an existing near full bram file in hex editor). For the hucard libs I'll make, I'll be sure to reorganize the blocks if I add a delete option.
Title: Re: BRAM support
Post by: Arkhan on May 09, 2016, 03:09:10 PM
Quote
On that note: does the system card take care of defragmenting the entries?

I take my comment back. I just checked, and it looks like it shifts the directory/data blocks backwards, over writing the old data, and adjusts the available pointer.

Must have been thinking of the HuC version....


^^^^^ Yeah
Title: Re: BRAM Library
Post by: Bonknuts on May 19, 2016, 03:05:31 PM
Updated the main post. I'll be posting the library and any updates to it in this thread.

 Note: I'm using fast 16bit compares (cmp+sbc), but man.. that inverse logic of the carry flag always trips me up :/
Title: Re: BRAM Library
Post by: Arkhan on May 19, 2016, 07:44:41 PM
Updated the main post. I'll be posting the library and any updates to it in this thread.

 Note: I'm using fast 16bit compares (cmp+sbc), but man.. that inverse logic of the carry flag always trips me up :/

I'm over here writing z80 and laughing at you.

Title: Re: BRAM Library
Post by: Bonknuts on May 19, 2016, 08:21:33 PM
Haha, you can keep that z80. I'm not a fan.
Title: Re: BRAM Library
Post by: Bonknuts on May 27, 2016, 10:13:09 AM
Ok. Preliminary BRAM support tested out fine. I tried to cover as much safety and bounds checks as I could (not sure how much the sys card handles). Lots of error reporting (more than sys card functions, and more detailed/specific). I don't have as fully featured set as the sys card ones (specifically for partial updates to an entry vs full updates/writes), but they work out great so far. I'll probably post an example suite, but it's more for musings than anything else at this point. Currently implementing this BRAM lib into Dragon Warrior.
Title: Re: BRAM Library
Post by: Bonknuts on May 27, 2016, 02:34:42 PM
Seems I'm running into a problem using the same BRAM libs from a CD project. Looking at the emulator, it's not unlocking bram. It works fine as a hucard project and the exact same routines. Is the emulator looking for something specific to CD games? Is there some different hardware unlock process for the CD unit or sys card that the emulator is looking for?
Title: Re: BRAM Library
Post by: ccovell on May 27, 2016, 03:54:27 PM
Who knows?  Are you banking in BRAM to an "oddball" location?  Did you try it on a real CD system yet?
Title: Re: BRAM Library
Post by: Bonknuts on May 27, 2016, 05:23:22 PM
No. I stuck with the system card protocol (logical address range, etc), as well as used Neutopia as a guide. Even did the long string to port $1807 instead of just $80. I think it might be an emulator thing. I haven't tried it on the real system yet.

 Guess I'll just switch over to using the sys card routines for the CD project, for now. I wanted to use my own lib because it's faster and cleaner than switching to MPR1, MPR7, and maintaining two stack pointers (as well as different VDC IRQ routines for each).
Title: Re: BRAM Library
Post by: TheOldMan on May 27, 2016, 06:13:51 PM
Silly question: Did you format the BRAM? I vaguely remember having to do that to create the BRAM file for <Mednafen?> Look and see if theres a 2K file in with the emulator stuff.

Also, do you drop to low-speed mode?
Title: Re: BRAM Library
Post by: Bonknuts on May 27, 2016, 06:30:59 PM
Yeah. That's the first function that is called. Check for valid header, format if absent. Yup, in low speed and interrupts disabled (extra caution). I mean, everything that I did for the hucard project that worked fine in mednafen, now appears to do nothing in the CD project for mednafen. I'm assuming the emulator must have some other check or such for its bram emulation code when in CD mode.
Title: Re: BRAM Library
Post by: TheOldMan on May 27, 2016, 07:12:20 PM
Quote
Seems I'm running into a problem using the same BRAM libs from a CD project.

It seems to me that if it works for a Hucard project, it should work for a CD project.
The only difference might be where the routines are located. I know the syscard version
is in the $00 bank, and mapped in at page 7 ($e000-$ffff). Possibly something is un-mapping your
routines / data. Or the emulator won't unlock BRAM from any other page.

[The system card routines use indirects to save to BRAM, since the data-to-save could be anywhere in the cpu address space. And the same for BRAM, iirc.]
Title: Re: BRAM Library
Post by: dshadoff on May 28, 2016, 12:34:10 AM
Is the BRAM function on the CD project your own function, or the CDROM card's function ?

I seem to recall ccovell identifying a more complex 'unlock' requireement several years ago... if I recall correctly, it needs a 3-write unlock sequence rather than 1-write.

Of course, this only applies if you are writing your own.  In HuC projects, the library automatically chooses between HuC code and CDROM card functions based on the target type.

-Dave
Title: Re: BRAM Library
Post by: ccovell on May 28, 2016, 02:10:59 AM
I seem to recall ccovell identifying a more complex 'unlock' requireement several years ago... if I recall correctly, it needs a 3-write unlock sequence rather than 1-write.

It's on the 1st page of this same thread, in fact.
Title: Re: BRAM Library
Post by: Bonknuts on May 28, 2016, 06:20:40 AM

Is the BRAM function on the CD project your own function, or the CDROM card's function ?

I seem to recall ccovell identifying a more complex 'unlock' requireement several years ago... if I recall correctly, it needs a 3-write unlock sequence rather than 1-write.

Of course, this only applies if you are writing your own.  In HuC projects, the library automatically chooses between HuC code and CDROM card functions based on the target type.

-Dave
Yeah, it's my own BRAM code (for both hucard and CD project). I definitely took note of the 3 byte sequence Chris mentioned and I'm using it.


Quote
Seems I'm running into a problem using the same BRAM libs from a CD project.

It seems to me that if it works for a Hucard project, it should work for a CD project.
The only difference might be where the routines are located. I know the syscard version
is in the $00 bank, and mapped in at page 7 ($e000-$ffff). Possibly something is un-mapping your
routines / data. Or the emulator won't unlock BRAM from any other page.

[The system card routines use indirects to save to BRAM, since the data-to-save could be anywhere in the cpu address space. And the same for BRAM, iirc.]

Actually, yeah. On the hucard project, I'm doing the bram access from bank $0 and MPR 7. And in the CD project the bram code is in bank $69 and MPR 2. I'll MPR7 and see if that has any effect.
Title: Re: BRAM Library
Post by: TheOldMan on May 28, 2016, 09:41:27 AM
Quote
And in the CD project the bram code is in bank $69 and MPR 2. I'll MPR7 and see if that has any effect.

Hunh? MPR2 is the $4000 cpu range, iirc.  I'd have to trace through that stuff again, but I think thats actually where the BRAM 'appears' (I could be wrong, though)

Can you re-build the HuCard project as a cd, and see if it works? That will let you know if its a bank placement problem.
Title: Re: BRAM Library
Post by: TheOldMan on May 28, 2016, 01:04:07 PM
Quote
MPR2 is the $4000 cpu range, iirc.

My bad. I was just looking at something else, and noticed the syscard bram functions
save the entire memory layout. And then map actual BRAM data to MPR4 ($8000 range).
Title: Re: BRAM Library
Post by: Bonknuts on May 29, 2016, 09:10:53 AM
Yeah, $8000 range.

Ok, so I just tried it with bank $69 in mpr7 and bank $f7 in mpr4. Still no luck. I really think this is an emulator issue. Guess I'll just stick with sys card routines for CD projects. The BRAM lib code work for hucard projects, so I guess it's not a total loss.
Title: Re: BRAM Library
Post by: TheOldMan on May 29, 2016, 09:34:53 AM
Quote
Ok, so I just tried it with bank $69 in mpr7 and bank $f7 in mpr4.

Okay. One more silly observation, then I'll leave it alone.
As I was tracing through the routines, I noticed that the bram re-lock routine turned the interrupts on.
So I went back and checked, and the bram unlock routine turns them off before going to low speed mode and unlocking bram.


[That's why one of the routines does some processing og the interrupts on it's own, I think. ]
Title: Re: BRAM Library
Post by: Bonknuts on May 29, 2016, 09:46:43 AM
It's definitely an emulator thing with mednafen. I switched over to using the sys card bram routines instead, and stepping through the code - it won't show any changes to bram (bm_format). So something with the emulator itself when running a CD game. Because stepping through BRAM code (my own, or an official hucard), in the emulator works find with hucards. It's like one of those quantum physics things; observing it changes the behavior ;>_>

Quote
As I was tracing through the routines, I noticed that the bram re-lock routine turned the interrupts on.
So I went back and checked, and the bram unlock routine turns them off before going to low speed mode and unlocking bram.
Yeah, I followed that procedure. I figured it was extra safe guards when accessing BRAM - because handling save data is pretty important. Though I do the PHP, SEI, CSL and CSH, PLP. Just in case any higher up functions already had interrupts disabled.   
Title: Re: BRAM Library
Post by: Bonknuts on May 29, 2016, 10:53:21 AM
Also, the CDREAD routine is annoying. I can only read in as many free banks as I have logical address range for (32k at a time). Loading in 256k results in multiple calls to CDREAD. I'm using the docs from syscard 1.0. Is there an update to the CDREAD routine with more parameters?

I don't want to waste a full 8k just to use the updated CDREAD lib routine I ripped from Seiya monogatari.
Title: Re: BRAM Library
Post by: TheOldMan on May 29, 2016, 11:10:55 AM
Quote
It's definitely an emulator thing with mednafen. I switched over to using the sys card bram routines instead,...

That sounds so damn familiar...I wish I could remember what we did to fix it...

First, check your mednafen.cfg file, and make sure its set up for bram saves; I vaguely recall if you don't specify a path for something, it won't actually save to a file.
Second, delete any old bram files you find. I do remember everytime I changed the cd image, mednafen created a new bram file (empty of course) with a different name. I believe the name was based on a hash of the code, and if things in the iso changed, you got a new save file.
Other than that ask the mednafen author what's going on / if he has any ideas. He's a pretty ok guy explaining why things do what they do. And if it's really an emulation problems, he does get it fixed.

Quote
Also, the CDREAD routine is annoying. I can only read in as many free banks as I have logical address range for (32k at a time)

The syscard 3.0 (?) CD_READ uses DH as a read type; the nice (or not) thing is you can specify an MPR bank to use for the read, and it is capable of filling consecutive banks for you.
And I -think- it may even load partial banks if the length isn't a multiple of 4 sectors.

Somewhere around there there used to be a HuCD7_final.pdf file that had the details on how the bios did things; not sure if it was 2.0 or 3.0, but the things it says do work on a 3.0 card.

That's how we figured out how to do MML :)
Title: Re: BRAM Library
Post by: Bonknuts on May 29, 2016, 11:19:44 AM
Yeah, I set _DH to the MPR page and put the starting bank in _BL. Maybe I missed something. I'll give it another try. It seems weird that they wouldn't allow all 256k to be loaded in a single pass (#$80 sectors).
Title: Re: BRAM Library
Post by: Bonknuts on May 29, 2016, 11:25:32 AM
Somewhere around there there used to be a HuCD7_final.pdf file that had the details on how the bios did things; not sure if it was 2.0 or 3.0, but the things it says do work on a 3.0 card.

 I have it. It's listed as CD-ROM BIOS ver 1.00
Title: Re: BRAM Library
Post by: Bonknuts on May 29, 2016, 11:55:59 AM
Ok. I tracked down the problem with BRAM code. For some reason, mednafen won't unlock BRAM if you write "Hu",$80 to port $1807 if the emulator is in CD mode. It only works if you write only $80 to the port. So definitely an emulator thing. And the other thing that I noted; you can't see the contents of BRAM while you're stepping through the routine in the debugger if the emulator is in CD mode. For hucard mode, this isn't an issue.

 So it was a two fold problem. I was able to mix and match sys card and my own routines now, in a CD project.
Title: Re: BRAM Library
Post by: TheOldMan on May 29, 2016, 12:42:12 PM
Quote
Ok. I tracked down the problem with BRAM code.

Good to hear. Now, when can we expect Dragon Warrior?
Title: Re: BRAM Library
Post by: TheOldMan on May 29, 2016, 01:18:23 PM
Quote
Yeah, I set _DH to the MPR page and put the starting bank in _BL.

lda    #4    ; $8000 range / sta    _DH  /  lda  #80    /sta BL    kinda thing?

As I found out, there's a gap in page numbers...so it probably can only load 64K at a time.


[Syscard 3.0 banks are at $60-$6F, iirc. Then you jump to $80-$8F for 'stock' pages.
 I could be wrong though, with the ranges. I just remember they aren't consecutive.]

Title: Re: BRAM Library
Post by: elmer on May 30, 2016, 04:11:20 AM
Ok. I tracked down the problem with BRAM code. For some reason, mednafen won't unlock BRAM if you write "Hu",$80 to port $1807 if the emulator is in CD mode. It only works if you write only $80 to the port. So definitely an emulator thing.

Do you have a Mednafen patch for that, or are you working around it in your PCE test-code?
Title: Re: BRAM Library
Post by: Bonknuts on May 30, 2016, 08:16:57 AM
I ended up using an .ifndef for an assembler variable/argument. Declaring _CDPROJ switches to the different unlock code.
Title: Re: BRAM Library
Post by: Bonknuts on June 02, 2016, 09:12:40 AM
Just wanted to say that I started real system tests, since ironing out the problems with the emulator, and everything seems to work as it should (the custom bram lib). And as expected, the real CD unit doesn't care what's written to port $1807; only the last byte being $80. So that's totally a mednafen thing.
Title: Re: BRAM Library
Post by: ccovell on June 02, 2016, 11:23:53 AM
[Syscard 3.0 banks are at $60-$6F, iirc. Then you jump to $80-$8F for 'stock' pages.
 I could be wrong though, with the ranges. I just remember they aren't consecutive.]

Are you sure about this?  Isn't (S)CD RAM consecutive from bank $68-$87, with $80-$87 being standard CD RAM?
Title: Re: BRAM Library
Post by: dshadoff on June 02, 2016, 11:40:18 AM
[Syscard 3.0 banks are at $60-$6F, iirc. Then you jump to $80-$8F for 'stock' pages.
 I could be wrong though, with the ranges. I just remember they aren't consecutive.]

Are you sure about this?  Isn't (S)CD RAM consecutive from bank $68-$87, with $80-$87 being standard CD RAM?

I'm with Chris on this... I'm certain that the "additional" memory goes to $7F, to make memory contiguous.

Dave
Title: Re: BRAM Library
Post by: TheOldMan on June 02, 2016, 04:41:05 PM
Quote
I'm certain that the "additional" memory goes to $7F, to make memory contiguous.

Okay. Being wrong is part of learning.
I have a hard enough time remembering things, anyway. (At least since I turned XX)

So, to do this the card either has a 128K RAM + 64 K RAM + 64K ROM and a decoder sith some glue chips, or 3 * 64K RAM + 64K ROM + decoder....
Hmm. must have been a pain to get wired.

And the bios converts number-of-sectors to read to number-of-bytes to read, which is where the 64K limit comes in. Got it.
<Now, can it be fixed.....>
Title: Re: BRAM Library
Post by: TheOldMan on June 02, 2016, 04:44:33 PM
<edit>
256 K ROM
(16+15 = 31 * 8 = 256K)
Title: Re: BRAM Library
Post by: Mednafen on June 08, 2016, 02:41:13 PM
Just wanted to say that I started real system tests, since ironing out the problems with the emulator, and everything seems to work as it should (the custom bram lib). And as expected, the real CD unit doesn't care what's written to port $1807; only the last byte being $80. So that's totally a mednafen thing.

I can fix a bug if you provide a test program with accompanying source code.