Jump to content
Sign in to follow this  
sage

AUDIN - reality and emulators

Recommended Posts

I just added AUDIn bank switching to my slideshow creator and all utilites.

To test it, I used a patched version of mednafen. Thus I can claim it works nicely on soft and hardware.

 

But now the questions:

handy (and all other emulators) use the lnx file format which has support for two "banks". But this switching is done by "cart strobes". Now, if you look at the PIN layout, ther is only one read and one write strobe.

So... Is there any usage of this feature in the emulators?

Is there any ROM (I am not aware of) which is using this feature?

 

If not, its only a two line modification of the emulators to use audin for switching the banks.

 

If not, what would a be a good way to save the AUDIN switch in the lnx header? There are still few bytes free.

adding two more banks? not really.

adding a flag?

Share this post


Link to post
Share on other sites

If not, what would a be a good way to save the AUDIN switch in the lnx header? There are still few bytes free.

adding two more banks? not really.

adding a flag?

The banksize in the header is just some really spaced apart values like $40, $80, etc. So it could be put in there to specify whether that strobe is one flat bank, or split up by AUDIN, etc.

I've been doing 2MB builds for maybe the past year with 1MB attached on each strobe, and AUDIN used to select the 512KB segment.

I think I stuck it under banksize $C0 in the LYX header (which was free), but this was only in a private build. I don't think any other software is using AUDIN for this except Alpine Games?

 

So maybe just some more banksize values in the header?

Share this post


Link to post
Share on other sites

If not, what would a be a good way to save the AUDIN switch in the lnx header? There are still few bytes free.

adding two more banks? not really.

adding a flag?

The banksize in the header is just some really spaced apart values like $40, $80, etc. So it could be put in there to specify whether that strobe is one flat bank, or split up by AUDIN, etc.

I've been doing 2MB builds for maybe the past year with 1MB attached on each strobe, and AUDIN used to select the 512KB segment.

I think I stuck it under banksize $C0 in the LYX header (which was free), but this was only in a private build. I don't think any other software is using AUDIN for this except Alpine Games?

 

So maybe just some more banksize values in the header?

 

I think there is no official game at all which is using audin OR second strobe.

 

The problem is more that you do not know if the pins are used for reades or writes.

 

Thus it would be more like a (three state) combination of the pins which select a block and determine if read or write?

Share this post


Link to post
Share on other sites

I think there is no official game at all which is using audin OR second strobe.

 

The problem is more that you do not know if the pins are used for reades or writes.

 

Thus it would be more like a (three state) combination of the pins which select a block and determine if read or write?

Out of the commercially released stuff, yes. Nothing uses AUDIN or /CART1. (Which is probably why there is a bug in Handy 0.93 where the data strobed by /CART0 is also loaded into /CART1, who would notice?)

So it would only be for new software.

 

But even if there are three states possible for cartridge access, there is one whole word dedicated to banksize in the LYX header. Only the following are used right now:

$0000- Empty

$0100- 64KB

$0200- 128KB

$0400- 256KB

$0800- 512KB

 

So these could be extended to include things like:

Value + 1: Uses AUDIN as an additional address line for that strobe for 2x banksize.

Value + 2: Bank is actually nonvolatile FRAM with AUDIN used as a chipselect

...etc.

Which keeps compatibility with old *.LNX stuff.

 

So additional checks are just needed when the emulator is accessing the cart for what type of hardware is there.

But I do not know what everyone is doing with their own software, so should we make a list here and establish some standard for these new values?

Share this post


Link to post
Share on other sites

 

So these could be extended to include things like:

Value + 1: Uses AUDIN as an additional address line for that strobe for 2x banksize.

Value + 2: Bank is actually nonvolatile FRAM with AUDIN used as a chipselect

...etc.

Which keeps compatibility with old *.LNX stuff.

 

So additional checks are just needed when the emulator is accessing the cart for what type of hardware is there.

But I do not know what everyone is doing with their own software, so should we make a list here and establish some standard for these new values?

 

If I interpret your comments correctly, you have ROMs with _four_ banks already. This it would not be that easy.

Example would be EOTB, which waits for a change of AUDIN (handshake from SRAM).

Question is, do we want to emulate that at all, or do we concentrate on things which are really useful? A save feature in the emulator is really the last thing which is needed.

Edited by sage

Share this post


Link to post
Share on other sites

If I interpret your comments correctly, you have ROMs with _four_ banks already. This it would not be that easy.

Example would be EOTB, which waits for a change of AUDIN (handshake from SRAM).

Question is, do we want to emulate that at all, or do we concentrate on things which are really useful? A save feature in the emulator is really the last thing which is needed.

If EOTB is the only game to use that type of cartridge, I do not see much point in emulating it.

The binary is not even publically available and I don't think any new software would use this save setup when EEPROM is cheaper and already supported in emulators.

 

So yes, I think useful things are more important at this time. All commercial games basically work, so we're only worried about what might get used in future software.

But it seems lots of games are being made right now, and I'm wondering if what's being put into their cartridges. So then we can extend the LNX header for cartridge types that are actually used.

Share this post


Link to post
Share on other sites

suggestion:

 

typedef struct
{
 UBYTE   magic[4];
 UBYTE   page_size_bank0_aud, page_size_bank0; // only the hi byte of the word
 UBYTE   page_size_bank1_aud, page_size_bank1; // only hi byte of word
 UWORD   version;
 UBYTE   cartname[32];
 UBYTE   manufname[16];
 UBYTE   rotation;
 UBYTE   spare[5];
}LYNX_HEADER_NEW;

Share this post


Link to post
Share on other sites

I prefer to keep the page sizes as they are now. But I would like to extend the system by using the spares.

 

The linker should concatenate the images into one lnx binary.

 

If the block size of the first bank is 1024 bytes and we use AUDIO as a 9th address line then the first ROM would be 512k.

 

But in the future we may also use a I2C latch for extending the address bits by 8 bits.

 

So I would dedicate the first spare to tell how many extra address lines the cart has.

 

spare[0] = number of extra address lines

 

The size of the 1st ROM in the lnx file is then BLOCKSIZE0 * 256 * (spare0 + 1)

 

The size of the 2nd ROM is not important as it is whatever is left over after the 1st ROM is defined.

 

The next spare could be used to define how CART0 and CART1 operates.

 

0 = CART0 is read strobe for ROM0, CART1 is read strobe for ROM1

1 = CART0 is read strobe, CART1 is write strobe

 

The third spare could describe how AUDIO I/O is used

 

0 = used only for EEPROM access

1 = used as a ROM selector

2 = used as an address pin

 

The fourth spare could tell the type of the EEPROM

0 = 93C46

1 = 93C66

2 = 93C86

 

I believe that this would allow us to describe all carts pretty well.

 

42Bastian addressing:

1024 bytes/block

AUDIO I/O used as ROM select pin

93C46 EPROM

 

EOTB:

2048 bytes/block ROM

64 bytes/block RAM

AUDIO I/O used as chip select

 

DevFlash by Karri:

2048 bytes/block R/W FLASH

CART1 used as write strobe

AUDIO I/O used as extra address line

 

SRAM developers cart:

1024 bytes/block SRAM

CART1 used as write strobe

 

Actually I have a new proto board being tested "Black Pearl":

2048 bytes/block FLASH

CART1 used as write strobe

5 extra address bits as I2C latch

Share this post


Link to post
Share on other sites

 

EOTB:

2048 bytes/block ROM

64 bytes/block RAM

AUDIO I/O used as chip select

 

ehm wrong. but doesnt matter.

 

the problem is, that even if you define a lot of bits, its still not clear how they function together.

Share this post


Link to post
Share on other sites

ehm wrong. but doesnt matter.

 

the problem is, that even if you define a lot of bits, its still not clear how they function together.

Chiming in on this for a bit.

I have implemented emulation for the EEPROMs 93LC46, -56, -66, -76, and -86. I ran into some of the same issues that are mentioned here. For example it was necessary to know how the pins of the Lynx where connected on the cartridge with extra things (e.g. EEPROMs).

 

I have discussed this with matashen and I now know that there are various combinations out there. The trick to find a way to "connect" the pins to other implementation:

protected override void Poke(RomCartMemoryBank bank, byte value)
{
 base.Poke(bank, value);

 ulong address = bank.GetAddress(this.shiftRegister, this.counter);
 bool a1 = (address & A1Mask) == A1Mask;
 bool a7 = (address & A7Mask) == A7Mask;
 Eeprom.Update(a7, a1); //, AuxiliaryDigitalInOut);
}

What I saw here was a hardcoded way to connect A1, A7 and AUDIO to the EEPROM pins.like is documented

CARD
// PORT               ----\/----	  93C46(SMD too)[/color]
// (18)  A7   --------| CS     |- +5V
// (11)  A1   --------| CLK    |- NC
//                +---| DI     |- NC
// (32) AUDIN ----+---| DO     |- GND
//                    ----------

What I see you guys mention is other ways of how strobe lines CART0 and CART1 are connected to different pieces of hardware.

 

So, the bottom line is that there are some different pieces of code needed to accommodate the variations of things at hand. There are numerous ways on how this can be realized. Then there's the current question of how to administer this inside a LNX header.

My two cents are that the implementation and administration go hand in hand. I would really like to think about how the implementation model will be and then choose LNX header layout.

Here are some suggestions of the implementation model with consequently following header info.

  1. Parametrized
    The way things are connected is limited in flexibility, but parametrized. The LNX header contains the parameters.
  2. Plugin
    The different implementations are separated from the main emulator core and are plugged in by a well defined interface.
    The LNX header contains a reference to the plugin to use.
  3. Mixture of both the above.
    Some parts of the different implementation is by plugins, but other parts are "hardcoded" with parameters. The header contains parameters and plugin.

Thoughts?

 

BTW, matashen also mentioned that AUDIN is short for Auxiliary Digital InOut instead of having anything to do with audio.

Edited by LX.NET

Share this post


Link to post
Share on other sites

I agree.

 

it might be easier to hardcode the different variants than to come up with the ultimate flexible solution.

Share this post


Link to post
Share on other sites

Same opinion.

 

At link time the cc65 tools have all this knowledge. Whatever we define I would like to fill in the header automatically to get the parameters right.

 

Currently the cc65 linker knows a lot of the cart wiring at link time by examining which labels have been defined

__BLOCKSIZE__

_lynx_eeread_93c46

_lynx_eeread_93c66

_lynx_eeread_93c86

 

AUDIN use as extra address line or rom select is not implemented in the cc65 tools - yet.

Share this post


Link to post
Share on other sites

O.k. to sum up my thoughts a bit:

 

status:

a) handy support for two banks with two strobes is fucked up, as it uses the same strobe for read and write while having no read/write switch. thus its mainly useless for writing to some sram. nevertheless, no cartridge supports it anyway.

b) handy does have support for two bank reading.

c) handy does not have support for audin bank switching (or adress line extension, call it as you wish)

d) audin can also not be used as read/write switch nor can it be used as input (well, it can but there is no signalin on it) woueld be needed for EOTB

 

We want to change the format such that we can

a) keep compability with existing format

b) support all (existing) read only cartridges

c) extend the format to support bank switching by audin while keeping support for two ROM strobes

d) have support for i2c eeproms

e) have support for a future adress line extension by i2c

 

thus to have the simplest solution first, I would add support for audin bank switching, which would not break anything and uses only 1 additional bit in the header.

This would at least allow now for testing 2MB cartridges read only in the emulation. (bank switch by audin, having both strobes for CS on two eproms).

 

thus:

Use the first unused byte as a "TYPE".

type 0: audin not used (compatibility)

type 1: audin used for bank switching

type 2-255: undefined

 

for the data part the following applies then:

bank0 with given size (strobe 0)

bank1 with given size (stribe 1)

bank2 with strobe 0 audin high (if type=1), same size as bank0

bank3 with strobe 1 audin high (if type=1), same size as bank0

 

How you handle the switching of banks in the software and how to create the directory or whatever in your rom is completely independent from that.

 

PS: Yes I have now 2MB slideshows :-)

Share this post


Link to post
Share on other sites

What I still do not grasp completely is how the real hardware deals with this. I strongly believe that the emulator (Handy or otherwise) should resemble the actual implementation in electronics. Otherwise there will be a disconnect between the real Lynx and its emulator, which is not handy in my book (pun intended).

 

The way I see it is that the Lynx console does not change. The carts that you insert do change. So, the way the 65SC02 code addresses the memory mapped registers should not change. It is the wiring on the cart that gives it new functionality. That gives the question of how the different cart types should be implemented in an emulator and how we can select that with a (ideally backward compatible) LNX header format. I have a gut feeling that Keith Wilkins implemented CART0 and CART1 logic in Handy based on a guess for CART1. Does anyone know what the behavior of the Lynx hardware for CART1 is?

 

The way I solved this in my emulator for cartridges with an EEPROM on it (the aforementioned 93CXX family) is to have a different piece of code. Where a regular commercial cart uses a RomCart class, the EEPROM cartridge is represented by a Eeprom93C46B class, that adapts the pin layout of the Lynx to the electronics of the cartridge. That was the Poke implementation I showed earlier.

I think this solution is viable. Different plugin-like implementations that reflect the cartridges. The rom image header should indicate this in some way.

 

What I cannot judge at this moment is whether a backward compatible rom format is achievable. How bad would it be for special cart rom images to be incompatible with an emulator that will not be able to do something useful with it anyway? Would using more than the 5 spare bytes (and thereby breaking compatibility) give us more options and flexibility?

Share this post


Link to post
Share on other sites

What I still do not grasp completely is how the real hardware deals with this. I strongly believe that the emulator (Handy or otherwise) should resemble the actual implementation in electronics. Otherwise there will be a disconnect between the real Lynx and its emulator, which is not handy in my book (pun intended).

 

The way I see it is that the Lynx console does not change. The carts that you insert do change. So, the way the 65SC02 code addresses the memory mapped registers should not change.

What are you talking about?

You have no memory mapped registers nor any other access to the cart than fdb2/3

The question is not that and how the emulator accesses these registers, but what byte from the emulator memory is given back.

 

It is the wiring on the cart that gives it new functionality. That gives the question of how the different cart types should be implemented in an emulator and how we can select that with a (ideally backward compatible) LNX header format. I have a gut feeling that Keith Wilkins implemented CART0 and CART1 logic in Handy based on a guess for CART1. Does anyone know what the behavior of the Lynx hardware for CART1 is?

 

acess to fdb3 is using strobe1, fdb2 strobe0. if you define that read or write depends on your cartridge wiring.

 

The way I solved this in my emulator for cartridges with an EEPROM on it (the aforementioned 93CXX family) is to have a different piece of code. Where a regular commercial cart uses a RomCart class, the EEPROM cartridge is represented by a Eeprom93C46B class, that adapts the pin layout of the Lynx to the electronics of the cartridge. That was the Poke implementation I showed earlier.

I think this solution is viable. Different plugin-like implementations that reflect the cartridges. The rom image header should indicate this in some way.

 

What I cannot judge at this moment is whether a backward compatible rom format is achievable. How bad would it be for special cart rom images to be incompatible with an emulator that will not be able to do something useful with it anyway? Would using more than the 5 spare bytes (and thereby breaking compatibility) give us more options and flexibility?

 

you will never have a solution which works for everything in the future.

What I want is a small solution for things existing NOW.

And what is existing now are homebrew carts using AUDIN as beank switch. What the emulator supports is STROBE0/STROBE1, but it allows read and write while teh real hardware can support only one action on one strobe.

Share this post


Link to post
Share on other sites

 

The third spare could describe how AUDIO I/O is used

 

0 = used only for EEPROM access

1 = used as a ROM selector

2 = used as an address pin

 

 

actually ther si no difference between 1 and 2 from teh cartridge poitn of view.

Share this post


Link to post
Share on other sites

What are you talking about?

You have no memory mapped registers nor any other access to the cart than fdb2/3

The question is not that and how the emulator accesses these registers, but what byte from the emulator memory is given back.

 

I guess we are talking about the same things. When you PEEK at $FDB2 the strobe0 is used. The byte that is given back depends on the cartridge's behavior, right? Sometimes however the way data is retrieved from a cart is totally different. E.g. the EEPROM 93CXX use A1 and A7 and a lot of strobing is used to create positive edges on the CS, DI and CLK pins of the EEPROM from the A1, A7 and AUDIN pins in the cartridge connector of the Lynx console. The data is returned as individual bits and they are read from AUDIN, IIRC.

 

acess to fdb3 is using strobe1, fdb2 strobe0. if you define that read or write depends on your cartridge wiring.

 

Exactly. Not on the Lynx itself. So that part of any emulator should not change, or have logic in it that does different stuff depending on the cartridge.

 

you will never have a solution which works for everything in the future.

What I want is a small solution for things existing NOW.

And what is existing now are homebrew carts using AUDIN as beank switch. What the emulator supports is STROBE0/STROBE1, but it allows read and write while teh real hardware can support only one action on one strobe.

 

That's why I am proposing a plug-in extensibility. Whenever a new cartridge comes along, someone codes the emulation of that cartridge's wiring. The corresponding rom image with LNX header must reflect the fact that there is a new plugin (direct or indirect) and that the image is using exactly that one. This can be a direct reference (unlikely with just 5 bytes) or indirect. By the latter I see three options:

  1. the emulator might have some form of configuration (file) that lists all of the known plugins with a lookup/reference code (that should fit into 5 bytes e.g.).
  2. it could be baked into a new release of the emulator
  3. the LNX header has a reference code for the plugin, and the emulator enumerates through all discovered plugins and selects the one with the correct code. This means a plugin needs to have a unique identifier.

I think option 3 is the cleanest. It does not involved releasing a new emulator (at least after the plugin functionality has been released). It would mean that adding a file to a known location (plugins subfolder maybe) would mean a new cartridge type.

 

Let's get back to basics here.

Do you have any particular cartridge in mind that has a new setup, like two bank and/or EEPROM and/or SRAM, using the AUDIN, strobe and other pins?

If so, could you describe how the real world hardware is connected to the cartridge and how the wiring on the cartridge is? I will volunteer to write an adapted emulator that is able to deal with this cartridge type.

How about that?

Share this post


Link to post
Share on other sites

Sure I have a cartridge in mind and on disc.

 

Nice idea, i can send you the code lines which have to be changed to get f.e. FS3 running. Alpine games would run too, if there wouldnt be the copy protection ;-)

Share this post


Link to post
Share on other sites

c) handy does not have support for audin bank switching (or adress line extension, call it as you wish)

Should this value be randomized on emulator start? On hardware startup it's high on a Lynx I, but low on a Lynx II.

 

Also, I like the idea of just repurposing the banksize low byte as a banktype byte. I don't think we will run out of configurations anytime soon.

 

for the data part the following applies then:

bank0 with given size (strobe 0)

bank1 with given size (stribe 1)

bank2 with strobe 0 audin high (if type=1), same size as bank0

bank3 with strobe 1 audin high (if type=1), same size as bank0

I've actually been decoding this the opposide way (So the strobe banks are twice as large when audin is used on them), but I suppose the data can just be moved around for that type of binary.

 

PS: Yes I have now 2MB slideshows :-)

Nice :)

Share this post


Link to post
Share on other sites

Should this value be randomized on emulator start? On hardware startup it's high on a Lynx I, but low on a Lynx II.

 

karri is right that it might not be too good to reuse them.

anyway, if one increases the file format number nobody can complain :)

 

Also, I like the idea of just repurposing the banksize low byte as a banktype byte. I don't think we will run out of configurations anytime soon.

 

better to add a switch to set rev1 and rev two, because there are still the differences in audio/stereo and supported cpu opcodes which are not reflected by the emus behavoiur.

 

I've actually been decoding this the opposide way (So the strobe banks are twice as large when audin is used on them), but I suppose the data can just be moved around for that type of binary.

 

Doesnt matter we just have to agree on the order of the banks in the file.

Share this post


Link to post
Share on other sites

O.k. as everybody now had time to think about this. Let me make my final proposal:

The reason is also that we now would like to implement the code for the flashcart supporting this and for that we have to fix the format.

 

(copied from above)

thus to have the simplest solution first, I would add support for audin bank switching, which would not break anything and uses only 1 additional bit in the header.

This would at least allow now for testing 2MB cartridges read only in the emulation. (bank switch by audin, having both strobes for CS on two eproms).

 

thus:

Use the first unused byte as a "TYPE".

type 0: audin not used (compatibility)

type 1: audin used for bank switching

type 2-255: undefined

 

for the data part the following applies then:

bank0 with given size (strobe 0)

bank1 with given size (stribe 1)

bank2 with strobe 0 audin high (if type=1), same size as bank0

bank3 with strobe 1 audin high (if type=1), same size as bank0

 

How you handle the switching of banks in the software and how to create the directory or whatever in your rom is completely independent from that.

 

I do _not_ propose to increase the header version number. Reason: Any code created with the new utilities will not run on old emulators even if the new features are not used. well actually it would be possible to set the version number depending on the content, but i woudl like to avoid additional work. :-)

 

 

Remarks to the handy based emulation code:

As the bank strobes are "messed up" in the original code I do not hesitate to leave it like that.

Which means, raeding and writing on one strobe line is "supported" in handy :-)

Now my patches actually replace only the Peek and Poke depending on the state of AUDIN if the AUDIN flag in the header is set.

 

I will add my changes as a diff file against mednafen 9.24 here thus you can test and review.

 

How you organize it in software is completely independant. Anyway:

My proposal fro the directory structure to support that is to use the upper two bits of the "block offset" as audin and bank1 flags. I already have implemented that in the lynxdir code available on my website. It is also done the same way in my slideshow. But anyway its up to the ocder to implement it as he wishes for example cc65 is using a completly diferent approach...

Share this post


Link to post
Share on other sites

O.k. as everybody now had time to think about this.

The thrilling speeds of Lynx development ;)

 

My proposal fro the directory structure to support that is to use the upper two bits of the "block offset" as audin and bank1 flags. I already have implemented that in the lynxdir code available on my website. It is also done the same way in my slideshow. But anyway its up to the ocder to implement it as he wishes for example cc65 is using a completly diferent approach...

This is completely fine with me. I could swap the bank order in my current 2MB binaries and have them run without any issues.

It also leaves plenty of room to shove other things into the cart later on.

 

I'm guessing this is all going into mednafen?

Share this post


Link to post
Share on other sites

This is completely fine with me. I could swap the bank order in my current 2MB binaries and have them run without any issues.

It also leaves plenty of room to shove other things into the cart later on.

 

I'm guessing this is all going into mednafen?

 

sorry for breaking your binaries :-/

But it would be nice if you can test them after swapping with teh patched version.

 

actually, the patches might also work with the handy code, as mednafen is based on it with only minor modifications.

but as handy does not compile under linux, i stick to patch mednafen.

 

i submitted the patches to the authors, but did not receive any response yet.

Share this post


Link to post
Share on other sites
Posted (edited)

While using a 2 bank scheme with BLL/AUDIN, how do you switch to bank 2 ?

From my understanding, it depends of bit 5 of IODAT :

 

From Handy source code, where SwitchAudInValue is defined as  "return (mIODAT&0x10);"

      case (RCART0&0xff) :
         if(mSystem.mCart->CartGetAudin() && mSystem.mMikie->SwitchAudInValue()) {
            retval=mSystem.Peek_CARTB0A();
         } else {
            retval=mSystem.Peek_CARTB0();
         }

 

As far as I can see, the bit value (reading _iodat, or 0xFD8B) has no impact on result, it always read bank0.

How and when this bit must be set. I tried during the FileSelectBlock routine, of before the peek of FCB2, but nothingchanges.

 

I have checked the directory structure in the LNX file, the "file start block" value is increrasing until it switches to files in bank 2 (it restarts from 0), which is fine for me.

Whatever the value of bit 5 of iodat is, it always read files in 1st bank.

 

I'm using lynxdir 1.6, newcc65 and BLL librairies (and routines from file_bs3.c included with Chipper release, but the file is older than inclusion of AUDIN bank switching in LynxDir, so it is normal it does not work from scratch).

I tried on several versions of Handy (old 0.95 which probably doesn't handle it, this year recompîled version from LordKraken), last version of Mednafen, on real Lynx with Bernd's flashcard... but nothing.

 

Seems there is something I didn't understand, but I haven't found documentation on this feature. Is there somewhere a tutoriel or source code to handle this in BLL in C ?

 

 

Edited by Fadest

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...