Jump to content
IGNORED

A8DS - An Atari 8-bit Emulator for the DS/DSi/XL/LL


Recommended Posts

Love the cranberry color on the DSi XL - sharp looking!

 

1 hour ago, Irgendwer said:

Without really knowing whats going on, but couldn't you "just" expand the total space in banks to a linear memory space and part of the address is the bank selector which is modified when the selection address changes?


The main problem is that the memory fetcher is called about a quarter-million times per second. Right now it looks like this:

image.thumb.png.08e9e15698fdd0558f07fcd3742d609e.png

Adding even one additional index/multiply/lookup/test does two bad things:

  1. It causes this function to expand by a few bytes and that causes the CPU/ANTIC routines to bloat by almost 2K which causes the entire CPU engine to no longer fit in the DS Tightly Coupled Memory (fast Instruction Cache... or ITCM which is only 16K in size). 
  2. It causes the routine to execute a tiny bit more slowly but when accessed a couple hundred thousand times per second, causes games to start to fall below the required 50/60fps.

The DS is roughly equivalent to an old 386 PC from the mid 90s. It has some amazing features - but CPU power and memory are not among them.  As such, I've had to carefully craft a routine that handles the XE/Port B memory switch in as few cycles as possible to stay above the threshold for the CPU to keep up.  Although I can rework this code, I'm far more likely to end up with games running in "slide show" mode :)  Such is life with emulating a system on a system which itself is already well emulated on more modern hardware!

 

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

57 minutes ago, llabnip said:

The main problem is that the memory fetcher is called about a quarter-million times per second. Right now it looks like this:

...

Adding even one additional index/multiply/lookup/test does two bad things:

  1. It causes this function to expand by a few bytes and that causes the CPU/ANTIC routines to bloat by almost 2K which causes the entire CPU engine to no longer fit in the DS Tightly Coupled Memory (fast Instruction Cache... or ITCM which is only 16K in size). 
  2. It causes the routine to execute a tiny bit more slowly but when accessed a couple hundred thousand times per second, causes games to start to fall below the required 50/60fps.

The DS is roughly equivalent to an old 386 PC from the mid 90s. It has some amazing features - but CPU power and memory are not among them.  As such, I've had to carefully craft a routine that handles the XE/Port B memory switch in as few cycles as possible to stay above the threshold for the CPU to keep up.  Although I can rework this code, I'm far more likely to end up with games running in "slide show" mode :)  Such is life with emulating a system on a system which itself is already well emulated on more modern hardware!

 

Thanks for the explanation!
My suggestion is targeting the implied raise of complexity, while the address is not 16 bit anymore but has in the upper-nibble the e.g. port-b values responsible for the address translation. So you are accessing a bigger space without looking for specific banks...

  • Like 1
Link to comment
Share on other sites

2 hours ago, Irgendwer said:

Thanks for the explanation!
My suggestion is targeting the implied raise of complexity, while the address is not 16 bit anymore but has in the upper-nibble the e.g. port-b values responsible for the address translation. So you are accessing a bigger space without looking for specific banks...

Interesting! Yeah, my knee-jerk reaction is that it won't work only because the memory fetch handler is for the entire 64K (OS, BASIC, various memory mapped devices, RAM, ROM, etc) - including some banked locations and some non-banked. And the banks are different depending on the cart scheme. So it would have to replicate the entire 64K multiple times and that won't work for RAM writes which would need to replicate across all "banks" if it's in a non-windowed area (but not if in a windowed area).

 

 

Link to comment
Share on other sites

24 minutes ago, llabnip said:

Yeah, my knee-jerk reaction is that it won't work only because the memory fetch handler is for the entire 64K (OS, BASIC, various memory mapped devices, RAM, ROM, etc) - including some banked locations and some non-banked. And the banks are different depending on the cart scheme. So it would have to replicate the entire 64K multiple times and that won't work for RAM writes which would need to replicate across all "banks" if it's not in a windowed area (but not if in a windowed area).

..and I knew that my post maybe results in this kind of answer. 😉

With a single e.g. table driven, one indirection approach you prevent repeated writes to non-banked areas.

Something where the upper bits of the enlarged address and relevant banking space is remapped.

 

E.g. take the lower 4 PORTB bits into account for memory mapping and the upper 4 bits of the physical address. Now those are translated with a table to form the real address:


 

ADDRESS BankAndMemToRealMem[256] ? {

...

$03, // index $03

$04, // index $04

$05, // index $05

$06, // index $06

$07, // index $07

$08, // index $08

...

$03, // index $43 (PORTB bit 2 set)

$44, // index $44 (PORTB bit 2 set)

$45, // index $45 (PORTB bit 2 set)

$46, // index $46 (PORTB bit 2 set)

$47, // index $47 (PORTB bit 2 set)

$08, // index $48 (PORTB bit 2 set)

...

};

 

 

then the upper nibbles are translated

upperNibbles =  BankAndMemToRealMem[upperNibbles];

 

resulting in targeting non-banked areas at the same location.

 

Depending how much memory you can waste or instructions you can spend a somewhat quick access should be possible - saving also the 'memory' or 'memory_bank' check from above.

 

  • Like 2
Link to comment
Share on other sites

I appreciate the detailed explanation here. And yes, that will work though I'm still skeptical that the indirection / lookup will be fast enough but I'm willing to experiment and see.  It would have the added benefit of handling the RAM windowing as well. And it would definitely be much faster than moving blocks of memory around but if it renders non-banking games unplayable it's a no-go. 

 

I'm currently down to about 200K of free memory - though I can gain back another 500k by dual-purposing the cart space and RAM space assuming I don't really need to support 320K or 1088K with Cartridges. 

 

 

Edit... gave this a quick try. It's 1.5K smaller (so I have 1.5K more of ITCM memory to play with!) and 2% faster on normal (non-banked) games. That's encouraging!

 

image.png.c4d7eee35b2050c0a38e81c8126fdb59.png

 

This maps 16 chunks of 4K. So for bank switching carts, I only have to write 2 pointers instead of moving 8K.  For RAM banking I have to write 4 pointers but that should still be plenty fast.

 

Fingers crossed!

 

Edit2:  Woot!  Space Harrier sustaining 78 fps and AtariBlast is up closer to 120fps!

 

image.png.0cf3a1b833cc41a1ece0afa4972cb999.png

 

Edit3: Flob went from a 60+ second load to 4 seconds!  I've got a bunch of cleanup but this is clearly a huge win. Many thanks for pushing me in the right direction @Irgendwer

 

  • Like 5
Link to comment
Share on other sites

Ok... I just checked in 3.1a with the new memory handler that gives a slight boost in performance on non-banked games and an order of magnitude speedup on cartridge banked games.

 

https://github.com/wavemotion-dave/A8DS 

 

Flob was taking almost 60 seconds to load - it now comes up in about 4 seconds.  Most of the really big games are playing full speed - the only minor issue right now is that the voices in Space Harrier sound a bit 'chip-monkish' which I think is due to A8DS anchoring the timing to frames and not scanlines (that is, we will try to execute all scanlines in a frame as fast as possible and only perform the NTSC/PAL timing at the frame level).  But the voice is still understandable and the gameplay is fine.

 

This new memory handler might have a bug or two - though I haven't seen anything crop up in a few hours of testing. Please do let me know if something feels wrong here.

 

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

Anyone else having issues with these recent homebrew games?  (I'm using A8DS 3.1a on a DSi, 128K XL/XE, Atari XL OS ROM, Basic disabled)

 

Dracula Story 1.7.ATR - emulator ignores the .ATR when I select it, game does not load

 

Albert 1.02.xex (running in PAL) - interstitial screens are digital garbage, but the main game plays properly

 

onEscape (14.12.2022) .CAR - opening cinemas are all digital garbage, didn't go any further to see if the rest of the game works

 

 

Edited by FifthPlayer
  • Like 1
Link to comment
Share on other sites

8 minutes ago, FifthPlayer said:

Anyone else having issues with these recent homebrew games?  (I'm using A8DS 3.1a on a DSi, 128K XL/XE, Atari XL OS ROM, Basic disabled)

 

Dracula Story 1.7.ATR - emulator ignores the .ATR when I select it, game does not load

 

Albert 1.02.xex (running in PAL) - interstitial screens are digital garbage, but the main game plays properly

 

onEscape (14.12.2022) .CAR - opening cinemas are all digital garbage, didn't go any further to see if the rest of the game works

 

 

Same here, but onescape worked ok in V3.1

  • Like 1
Link to comment
Share on other sites

Would it be possible to add stereo?

 

Jim Slide XL CAR only game: music's not perfect and some minor stripes in intro

 

AtariBlast!: there's garbage on title screen backdrop scrolling image and last column is missing (for example, there's written SCOR, COLOU, Manua, Norma. 

 

I've tested some commercial CAR games I dumped from my cartridges. The following ones have issues

- Adventure XE: garbage on selection menu, it's not possible to choose options

- Tempest Xtreem: garbage on title screen

- Laura: garbage on the long intro

 

It's nice that some disk only or two disk only games converted to CAR work: for example Conan, Spelunker, Gauntlet, Alternate Reality...

 

Prince of Persia CAR works too, that's very good because it loads faster than ATR.

  • Like 2
Link to comment
Share on other sites

4 hours ago, Luke210 said:

Same here, but onescape worked ok in V3.1

Interesting... maybe something is buggy in the A8DS' handling of the cartridge bankswap for that one.  I just had a look and it appears to be type 42 = Atarimax and I was pretty sure I had that one right. But I'll triple check!

 

And yes, Dracula Story, Albert 1.02 and a few others have some issues  - Philsan has been great about reporting a number of issues such as this. I'll do my best to debug these.

 

4 hours ago, Philsan said:

Would it be possible to add stereo?

I'm a bit ignorant of how that works... Pokey already has 4 channels - how is stereo handled? Is that dual pokey or something else?  I could probably support a second pokey chip - it comes at a cost of CPU processing but only for the games that use it.

Link to comment
Share on other sites

33 minutes ago, Beeblebrox said:

@llabnip  great work again.. Sorry to bombard you and maybe this has been mentioned, but will there be plans to run multiple disk image games like the brundles (A8 lemmings clone from 90s). That game comes on 3 x disk images. 

So the emulator has dual disk drives (D1 and D2) and you can swap disks easily enough while the games are playing. I assume that would work? 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I confirm The Brundles works, tested The Dark Crystal too (it has 6 disks, but there's a 1 disk version too - BTW, artifacts works).

The important thing to know when swapping disks in drive 1 is to press Y key to disable autoboot.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

3.1b checked in just now.

 

I figured out a big part of the recent graphical glitches. With the new cart banking memory handler, I forgot that the ANTIC also fetches from memory - and it was still indexing into the base 64k (which worked when we were copying chunks in/out). 

 

Which led me to another discovery - this is actually the source of many of the long-standing graphical glitches (though previously it was only related to RAM memory banking, not cart banking). So games like Albert now look right.

 

I tried a few others - OnEscape now looks right. AtariBlast title screen now looks better though still missing the last column. Tempest Xtreem (demo) and Adventure II XE both look right. I'm sure this won't fix every glitch but it should go a long way! 

 

Found the problem with Dracula's Story - it now loads.

 

image.png.d9c8afdab944e314a91b78c92d03f678.png

 

I've got more scrubbing to do before an official 3.2 release but at least we're moving in a positive direction with compatibility!

 

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

On 5/8/2023 at 1:57 PM, llabnip said:

Edit... gave this a quick try. It's 1.5K smaller (so I have 1.5K more of ITCM memory to play with!) and 2% faster on normal (non-banked) games. That's encouraging!

 

image.png.c4d7eee35b2050c0a38e81c8126fdb59.png

 

This maps 16 chunks of 4K. So for bank switching carts, I only have to write 2 pointers instead of moving 8K.  For RAM banking I have to write 4 pointers but that should still be plenty fast.

You can try a trick I use in Altirra's MMU, which is to offset the page pointers by the full address to avoid the need to mask the offsets. You need to convert the page table from UBYTE* to uintptr_t if you want to be strictly compliant about not offsetting pointers out of bounds temporarily.

 

return *(const UBYTE *)(mem_map[addr >> 12] + addr);

 

  • Like 3
Link to comment
Share on other sites

8 hours ago, llabnip said:

 

I'm a bit ignorant of how that works... Pokey already has 4 channels - how is stereo handled? Is that dual pokey or something else?  I could probably support a second pokey chip - it comes at a cost of CPU processing but only for the games that use it.

The de facto „standard“ for stereo is a second POKEY with an address offset. 

  • Like 1
Link to comment
Share on other sites

6 hours ago, phaeron said:

You can try a trick I use in Altirra's MMU, which is to offset the page pointers by the full address to avoid the need to mask the offsets. You need to convert the page table from UBYTE* to uintptr_t if you want to be strictly compliant about not offsetting pointers out of bounds temporarily.

 

return *(const UBYTE *)(mem_map[addr >> 12] + addr);

 

Clever! Thanks, Avery! A quick test shows this to save another half-K of precious instruction cache memory and gains a frame or two of performance across the board.   

 

  • Like 2
Link to comment
Share on other sites

Okay... and 3.1c has been checked in with Avery's suggestion and a few other small fixes: https://github.com/wavemotion-dave/A8DS  

 

I've gone through all my messages and reports (private and otherwise) and many of the issues are now fixed and I think this is the list of outstanding known issues. I've put this directly into my readme so I can better track what needs improvement.

Known Issues :

  • Jim Slide XL has some graphical glitching: horizontal lines on the intro screens. Cause unknown.
  • Space Harrier cart audio sounds "chip-monkish". Likely cause is frame timing being used vs. cycle-accurate timing.
  • Atari Blast! has one column of letters missing on the main title screen. Cause unknown.
  • Cropky (music problems in game) - cause unknown.
  • Gun Fright (the game doesn't start when you press "3" key) - cause unknown.
  • Intellidiscs (no discs sounds in game) - cause unknown.

 

I've no doubt there are plenty more glitches to be discovered - and I'll endeavor to do a better job tracking them for the future.

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

@llabnip

 

Woohoo! After a lot of reading and installing the various required files, etc etc, it's running on my DSi!! ;) Thanks so much for creating this and all the work thst continues to go into it. 

 

Albert screen grab

image.thumb.png.677661a3a811fc716f56d05685831910.png

 

BTW Albert runs fine aside the music is too slow for some reason.

image.thumb.png.9daf5c926de2cc053d8bfd6f2e874ea5.png  image.thumb.png.1ab5e08a4753ba7d7c03e1132e07ded9.png image.thumb.png.7550ada7169ab7ba1bc3da0485a35ce2.png

 

Also the latest final Scorch doesn't run properly and in game the dpad controls or fire don't respond. (menus are fine initially).

 

EDIT: Also sound isn't quite right with the Rewind demo. Sounds like it's missing a channel. 

 

How do I exit the onscreen keyboard BTW?

 

image.thumb.png.3d2aa7ad050b6156c2e43bb2ba5507c5.png

Scorch final single player Stereo release with icon tweak v1_28__3_5_23.xex Albert 1.02.xex

rewind.xex

Edited by Beeblebrox
  • Like 1
Link to comment
Share on other sites

Glad you got it running! I’ll add the observations to the known issues list. 
 

You exit the keyboard by pressing the Atari/Fuji symbol. We used that before I realized some keyboards had that for the inverse button (on my 800 XL that’s a diagonally shaded box). 

  • Thanks 1
Link to comment
Share on other sites

22 hours ago, llabnip said:

I forgot that the ANTIC also fetches from memory - and it was still indexing into the base 64k (which worked when we were copying chunks in/out)

I'm happy I was able to support you!
Had also a very brief look into your changes: Could it be, that you need two memory tables for the separate ANTIC access support, required by some games or (mostly) demos?

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

1 hour ago, Irgendwer said:

I'm happy I was able to support you!
Had also a very brief look into your changes: Could it be, that you need two memory tables for the separate ANTIC access support, required by some games or (mostly) demos?

Maybe :) 

 

I think I’m only using the memory map for when ANTIC is the same as CPU memory. It should be using the XE pointer if using separate access. But I’m willing to assume something might not be right. 
 

Is there a demo or two that uses the separate access so I can run some tests?

 

in the meantime I’ve had a look in the Altria hardware manual and a second “stereo” pokey via A4 addresses seems reasonable to try and add. I wonder if that’s the source of some missing sounds in a few newer games and demos? 

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...