Jump to content
IGNORED

ROM asset management / accessing assets from ROM directly


ggn

Recommended Posts

Ok, this is a slightly iffy subject that I was trying to sweep under the carpet, but since people encountered problems and asked me about it I thought I'd make a topic about this.

 

First of all some generic info:

When the programmer wants to know the address of an asset in ram (say the address of a clut), a slightly weird syntax has to be used: strptr(asset_name). When accessing rom assets the strptr isn't needed. I really tried hard on this in order to have consistent syntax but I couldn't figure out a way (slightly complex reasons involved here so I'll skip describing those for some other time).

 

The real issue I'd like to tackle here is what happens when you try to get the GPU/DSP/OP to access assets in ROM directly. And unless someone has any ideas it's not an easily solved one.

 

To cut a long story short, if the cartridge you use has 16-bit width the OP and DSP (etc) are going to get 16 bits of correct data and 16 bits of garbage (all set to 1 from our tests). To cure that, the system has to be set to 16-bit width using the following code:

 

			move.w	MEMCON1,d0
			bset	#1,d0
			bclr	#2,d0
			bset	#3,d0
			bset	#4,d0
			bclr	#7,d0
			move.w	d0,MEMCON1
This code needs to be run before the hardware is set to access ROM, so at rapapp.s at least before the "jmp __Z9basicmainv".

 

I was thinking about this and came up with an idea: I could add this code as standard to all projects (and any new project people will create) and introduce a new switche to the build system. So build PROJECT ROM would build a standard 32-bit rom and build PROJECT ROM16 would include the above snippet automatically.

 

I'm not sure what's best though, maybe people can just copy/paste the above code snippet and move on. Thoughts?

 

(also if anyone knows if there's a way to detect actual ROM width at boot time this can be automated. Anyone?)

  • Like 4
Link to comment
Share on other sites

You shouldn't need to set the ROM width manually on released games, regardless on which hardware you use, as the ROM width is specified in the header. The boot ROM reads this and configures the hardware accordingly (otherwise the game wouldn't even start, as half of the 68000 instructions would be wrong).

 

It is only required during development (using BJL or the Skunkboard) if you upload code to RAM which fetches data from ROM. From my point of view, it's something that should be added to the Skunkboard tools code ; if you're using the Skunkboard software, then there is a Skunkboard connected, so the ROM width is known and it might as well be set automatically :)

 

If you want to do it automatically from your code, I think the best way would be to put a 32-bit constant somewhere in the ROM :

- set the ROM width to 16

- read the constant from ROM

- If you get the right value, then you're done. Otherwise, set the ROM width to 32.

 

(if you want to get snarky, read the constant in both modes. If you get the same result, then you're running in an emulator :D)

 

The constant value should be chosen so that there is no risk of ambiguity ; $12345678 is fine.

Edited by Zerosquare
  • Like 2
Link to comment
Share on other sites

if new modes were built into the build.bat, additions would need to be included to the notepadd++ plugin to use them. i use that functionality for everything except creating new projects

 

both options are very workable:

 

a switch in rapapp.s like the sound module to use

or this method described above.

 

i dont know about jagtopus, but the skunkboard could be detected, the first $2000 holds the skunk bios so it would be known information apart from the serial number, the first $2000 of an EPROM cartridge is mostly full of FF's after the checksum data which could be used to detect that, as for the jagtopus, i don't know whats involved with that

Link to comment
Share on other sites

Without getting into details, there is no method which can detect a Jagtopus board in all cases without getting false negatives and/or false positives.

 

But in ggn's case, that doesn't matter: you don't have to carte about the exact type of hardware you're running on, you only need to know the ROM width. And it'll even be compatible with hardware that hasn't been released yet ;)

Edited by Zerosquare
Link to comment
Share on other sites

OMG people actually answered!

 

Anyway, without wanting to dispute everything said so far: From my experience so far "you shouldn't have to set ROM width" is just wishful thinking.

 

SH3 had issues with streaming audio from ROM, we thought about it for a few days, then SH3 puts in the magic pokes to MEMCON1 - lo and behold it worked.

 

OMF had issues with displaying graphics from ROM, we checked everything under the sun including alignment, if the ROM was generated correctly etc etc. We stuck the magic pokes and behold - it worked!

 

The bottom line is: people are going to get confused while developing, and it's one of the things you don't really want to when all the code is in flux. And I don't want to be there holding hands to people, trying to debug the issue. That's why I thought I'd just throw a new switch in there, so people can help themselves :).

 

People have different setups, at the moment I have a bjl bios+jagtopus, others have skunkboards with/without bjl bios. Hell, maybe someone will try to use an Alpine while we're at it (or I dunno, a jagserver if people are suicidal enough? :P). So even if this thread doesn't lead to any actions taken on the RB+ side, at least it will be now documented.

 

In any case, awaiting for opinions from the other 1.54 RB+ users ;).

Edited by ggn
  • Like 2
Link to comment
Share on other sites

This kind of stuff is beyond my knowledge. So I'll just follow the path given to me. I wouldn't be able to comment which is the correct way to go about it. The main thing is that its documented now. If all it takes is a switch in rapapp.s then so be it.

 

Also, thanks for investigating and looking into it :)

Link to comment
Share on other sites

I'm coming at this from the completely "don't know what I'm talking about" perspective.

 

That being said, perhaps there should be a community made generic template that has the most common settings (and gotcha avoidance stuff like this) already up and in there.

 

Perhaps in the far flung future when VisualrB+ appears it could be the default code that pops up when "new project" is clicked on.

Link to comment
Share on other sites

Anyway, without wanting to dispute everything said so far: From my experience so far "you shouldn't have to set ROM width" is just wishful thinking.

Note that I said: in released games, by which I mean actual physical cartridges, or self-contained ROM files which can be run on programmable cartridges. If you found a counter-example, I'd be very interested in knowing more.

 

If you're uploading code directly to RAM during development, you may indeed run into problems when accessing ROM. I don't know if that happens on the Skunkboard, but it it does, it can probably be avoided by doing minor updates to the tools code. It will happen on the Jagtopus if you're using BJL (and can't be fixed without patching the BJL ROM), but I didn't mention it since I thought I was the only one actually using the Jagtopus + BJL combo for development :)

 

Anyways, I realized something thanks to your post: the code you posted above not only sets the ROM width to 16 bits, it also sets the access time to 5 cycles instead of the usual 10. That's OK for the Skunkboard and Jagtopus, since their hardware supports it, and it allows them to have the same data throughput as the official carts despite being 16-bit instead of 32-bit wide. But if anyone ever makes a 16-bit cartridge using slow EPROMs (that's a real possibility, as it makes the cartridge cheaper at the expense of slower ROM access), this code will cause hard-to-track corruption and crashes. And there's no way to autodetect the optimum access time.

 

So in fact there is a better and simpler solution that I had not thought of before: mimic what the official boot ROM does, that is configure the ROM width and access time based on the information in the header itself. This should work fine on all current and future hardware; there are a few theoretical edge cases, but I can only think of things that would only happen if you did really weird stuff.

 

I'll extract the code the boot ROM uses and post it here :)

  • Like 1
Link to comment
Share on other sites

Here's the ROM width and access time-setting code from the boot ROM* :

move.b  $800400, d0             
andi.w  #$001E, d0               
ori.w   #$1861, d0              
move.w  d0, MEMCON1

The only hardware I have is the Jagtopus, so my testing will be pretty limited, but I'm pretty confident this will work fine on other hardware. Try it out :)

 

* I've modified and simplified it slightly, since the original does a few other things that aren't need in our cases: setting the GPU PC register, and self-relocating to RAM. It has to do the latter because the ROM width settings affects both the boot ROM (which is 8-bit wide) and the cartridge, so it would immediately crash for 16 and 32-bit wide cartridges otherwise. This can't happen in our case because either the code is executing from RAM already, or it's executing from ROM and in that case it has no effect (otherwise, it couldn't be running correctly in the first place :))

Edited by Zerosquare
  • Like 2
Link to comment
Share on other sites

I can confirm that the above code works for those configurations:

- Original boot ROM + Jagtopus, with data and code in ROM (i.e. the configuration which would be used for a released game)

- BJL ROM + Jagtopus, with data and code in ROM (pressing the B button to run the cart)

- BJL ROM + Jagtopus, with data in ROM and code uploaded directly to RAM

- Virtual Jaguar GIT 20160613

- Project Tempest 0.95

 

Without the above code, the "BJL ROM + Jagtopus, with data in ROM and code uploaded directly to RAM" configuration fails.

 

If you want to test it yourself, here is an example:

rom_width_test.zip

 

rom_width_test.rom is a standalone ROM file which can directly be burned to EPROMs or flashed to programmable cartridges.

rom_width_test.bin is a headerless BJL binary (load and run address are both $4000). It only includes the code ; it assumes the data is in ROM (in other words, you need to burn/flash a cartridge with rom_width_test.rom and have it plugged in for it to work).

 

The picture is directly read by the Object Processor from ROM. If you see this, this means it works fine :)

 

Tests reports on other hardware/configurations welcome! (Skunkboard, EPROM carts, Atari Flash carts, Alpine, whatever)

Edited by Zerosquare
  • Like 3
Link to comment
Share on other sites

First of all,

 

(raises hand) Apologies for quoting Zerosquare out of context there - my reading comprehension sucks!

 

Anyway, what can I say, that's great research and solution there so big up for your efforts :). I think that if we confirm that the attached rom file works in skunkboards and an actual cart with eeproms I see little reason to not include it in standard rb+ startup code!

  • Like 3
Link to comment
Share on other sites

  • 4 years later...

(Hours of research, testing and scratching my head has brought me here, so thanks for this thread!)


So I'm doing all the bad no no voodoo magic tricks that you're not supposed to do, like pulling audio and graphics from a 6MB ROM but as long as the following is included:

			move.w	MEMCON1,d0
			bset	#1,d0
			bclr	#2,d0
			bset	#3,d0
			bset	#4,d0
			bclr	#7,d0
			move.w	d0,MEMCON1

it works fine on my Skunkboard, and as I understand it, is setting the romwidth to 16-bit at 5 cycles. However, if you run this on the new JagSD/GD cart, the graphics being pulled from ROM are scrambled (which would lead me to assume it is a 32-bit romwidth cart) and as a result, the scrambled graphics would make sense.

 

So if I remove the above MEMCON 16-bit trickery, it works fine on the SD but is as expected, corrupted on the Skunk now.

 

I've scoured through everything and the only remaining MEMCON references are in the JAGUAR.INC and Raptor.h files, but should remain untouched.

 

Trying the following code (pulled above) results in the same issue with the Skunkboard having garbled images that are pulled from ROM:

Quote

move.b  $800400, d0             
andi.w  #$001E, d0               
ori.w   #$1861, d0              
move.w  d0, MEMCON1

So my question is, was any of this further verified to be working with the Skunk and or JagSD/GD by anyone else? (I'm assuming not since I'm at the end of the line here with no other claims) but asking just in case and to verify / provide my own personal results for anyone else who may stumble upon this topic with beer in hand after being awake for 22 hours.

 

*Edit - I just downloaded and ran the program Zerosquare provided and here are my results on the Skunkboard:

 

badgpu.thumb.jpg.8501ca83c642a68107de0d76580c744f.jpg

 

Could someone please break this down further for me:

			move.w	MEMCON1,d0
			bset	#1,d0
			bclr	#2,d0
			bset	#3,d0
			bset	#4,d0
			bclr	#7,d0
			move.w	d0,MEMCON1

Which part is setting to 16-bit ROMWIDTH and which part is setting the cycles to 5? Or since without that code it's automatically set to 32-bit, what code would you need to implement to force 5 cycles instead of (what I presume to be, please correct me if I'm wrong) 10 cycles at 32-bit width?

Edited by Clint Thompson
Link to comment
Share on other sites

OK, lets fix this once and for all...

The problem here is that no matter what you do, the original RAPTOR.O file sets it back (because I stupidly left code in there for the Jagtopus board *and* called the MemoryTrack routines! We were doing CD releases at the time, so......)

 

Hex search the original raptor.o file for:

$33c0 00f0 0000

 

replace it with

 

$4e71 4e71 4e71

 

Remove *any* and *all* references to MEMCON1 in any part of your projects (do a 'find in files')

 

Also, search for the following in raptor.o

 

image.png.c32380b898f8427acab3d7e6c271590f.png

 

$4eb9 0000 2ae0 4eb9

 

Replace the FIRST and ONLY THE FIRST $4eb9 with $6004

 

This will 100% disable MemoryTrack (Which was causing the problems - but as you are making carts, you can't have MT anyway)

 

Now, do a rebuild and all should be fine.

  • Like 3
  • Thanks 2
Link to comment
Share on other sites

2 hours ago, CyranoJ said:

OK, lets fix this once and for all...

The problem here is that no matter what you do, the original RAPTOR.O file sets it back (because I stupidly left code in there for the Jagtopus board)

 

Hex search the original raptor.o file for:

$33c0 00f0 0000

 

replace it with

 

$4e71 4e71 4e71

 

Remove *any* and *all* references to MEMCON1 in any part of your projects (do a 'find in files') - rebuild... and.. should be working.

 

 

Is this the correct address in RAPTOR.O you are referring to?

 

raptor.thumb.PNG.1f7fee7f185ec46a39e91540c4397539.PNG

 

 

 

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...