Jump to content
IGNORED

DS99/4a - An Emulator for the DS/DSi/XL/LL


wavemotion

Recommended Posts

image.png.3d6d996162199813d96d33175553ecbb.png

 

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

 

DS994a is a Texas Instruments TI99/4a Emulator for the DS/DSi/XL/LL

Features :

  • Games and programs run at or near full speed across the spectrum of DS hardware (though the emulator targets the DSi / XL for optimum performance)
  • Cart loads up to 8192K (8MB) on the DSi and 512K on the DS using standard TI99 bankswitching (+40K of GROM beyond the 24K Console GROM)
  • Mixed mode C/D/G/8/9 files supported as well as the MESS/MAME .RPK (Rom PacKs)
  • 32K RAM Expansion built-into the base console emulation
  • SAMS at full 1MB for the DSi (and above) and 512K for the older DS/DS-Lite units
  • MBX, Mini-Mem and Super Carts supported with extra RAM. Use Options to select cart type
  • Save and Load State
  • High score saving for up to 10 scores per game
  • Full mapping of any of the 12 DS keys to any combination of TI Joysticks/Keyboard
  • Virtual TI-99/4A keyboard with classic stylings just the way you remember it
  • Disk Support for DSK1, DSK2 and DSK3 up to 360K each using a modification for the standard TI Disk Controller (you need 994adisk.bin - see BIOS files below)
  • Speech is not fully emulated (but games requiring the Speech Synth will run/play - just no voice except...)
  • A few games have speech samples built-in: Parsec, Alpiner, Moonmine, Star Trek and Bigfoot

 

 

image.thumb.png.e10e8d97736940384bbbf5bef70c9cf1.png

 

I've decided to re-purpose this thread as the one place for all updates to my TI-99/4a emulator on the DS.

 

 

 

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

51 minutes ago, Schmitzi said:

 

Hi, is this one OK for the job ?

https://www.ebay.com/itm/305354504588

Should be overkill. I target the model before this - specifically the DSi (and I strongly prefer the XL or LL model as they are larger). My emulators run on the older DS/Lite units with flash card but the CPU speed is only 67MHz vs 134MHz of the DSi so some of the more complex games might slow down a tad (but still ok to enjoy). I don’t have a 3DS but people do play my emulators on them. A 2DS works as well - mainly because these will fall back to a compatibility mode. 

  • Thanks 1
Link to comment
Share on other sites

Whew! Finally got the megademo from @Asmusr and @Tursi (and others) to run!

 

My emulation was only checking collisions at the end of a frame which was inadequate for the demo. I've corrected this but it comes at a bit of a CPU hit that is hard to come by on the venerable DS handhelds. So for the DSi, I'm checking collisions every 8 scanlines which isn't hardware perfect but seems to render the demo fine (and fixes collision detection in games like Eric in Monsterland and Interceptor).  For the older DS-Lite/Phat (or when running in DS compatibility mode from a cheap R4 flashcart), I can't check collisions quite that often without significant slowdown... so I do it as fast as I can but it won't be as nice as the DSi.  Still good enough to get the job done if a bit slower. It averages checking collisions 3 or 4 times per frame on the oldest DS hardware.

 

Huge thanks to @PeteE and @matthew180 for their guidance - I've calculated that they have roughly 137 times my knowledge on the VDP handling.

 

I've checked in 1.7b (daily build) with the VDP improvements and am now working on optimizing a bit more to ensure the older handhelds can keep pace with the improved accuracy.  I need to do a bit more testing to be sure it's all working before I put out an official 1.8 release.

image.png.5fe559f98f2cc353287c1f788b529fc2.png

 

 

It's been a while, friends!  I spent the last two weeks hard at work on the next version of DS99/4a.  My main goal was to polish around the edges a bit and try to fix some of the games that wouldn't run correctly. I mostly succeeded.

 

I added a mini-debugger to help me sniff what's going on and I did manage to fix the audio squeals in games like Borzork, Mission Destruct, etc. (those games were using 16-bit writes to the 8-bit SN audio chip and I wasn't handling that correctly).  Similarly, some SAMS programs (most notably AMSTEST4) were reading 16-bits out of the SAMS banking registers and I wasn't populating the return value correctly. These are both fixed.

 

image.png.bca985beab467d3ed332a725d04bdd33.png

 

Lots of other improvements... some cosmetic things like a floppy disk access sound that plays when the drive is active - I did my best to isolate a drive that sounds reasonably close to a TI drive. I've also simplified some things - including the new way you can name your files that should still be compatible with most other good emulators out there. You can now marry up your .dsk files to your cartridge .bin files so that when you load the game, it will auto-mount any and all associated disks as well. Saves time - you can, of course, still manually mount disks with the diskette icon on the lower screen.

 

For example, for Tunnels of Doom you might have:

  • TunnelsOfDoom_g.bin - The Tunnels of Doom GROM cart
  • TunnelsOfDoom_1.dsk - The Tunnels of Doom disk mounted as DSK1
     

When you load Tunnels of Doom, it will automatically mount TunnelsOfDoom_1.dsk

 

For something like Realms of Antiquity you can have:

  • roa_8.bin - The 128K cart
  • roa_1.dsk - The first disk to mount as DSK1
  • roa_2.dsk - The second disk to mount as DSK2
  • roa_3.dsk - The third disk to mount as DSK3

 

(the underscores are just a personal preference of mine as I find it makes the filenames look cleaner and more clear. It's not required by the DS99/4a emulator)

 

The configuration has been both expanded and improved - and more games will auto-detect properly  (all of the MBX games will have their proper cart types and RAM if needed). Games like Q-Bert and Hopper will have diagonal directions mapped in automatically. Frogger will automatically select controller 2 (why, Parker... why?!).  I did my best to scour the planet for variations of the ROMs so I could do my best to detect - but you can always override things in settings.

 

Some of these changes are in preparation for my upcoming Wavemotions Highly Curated TI99 Collection - mostly in an effort to get new folks into the fold.

Hope everyone is doing well - thanks to all for the support on DS99/4a over the past year!

  • Like 18
Link to comment
Share on other sites

7 hours ago, wavemotion said:

Should be overkill. I target the model before this - specifically the DSi (and I strongly prefer the XL or LL model as they are larger). My emulators run on the older DS/Lite units with flash card but the CPU speed is only 67MHz vs 134MHz of the DSi so some of the more complex games might slow down a tad (but still ok to enjoy). I don’t have a 3DS but people do play my emulators on them. A 2DS works as well - mainly because these will fall back to a compatibility mode. 

 

thanks. So, overkill or not :grin:, is the "New Nintendo 3DS XL" OK too ?

I would like to have the most modern version (no DSi because of the cam)

as maybe there will be other use for it.

 

PS What about this "SNES-Edition", OK too ?

 

 

Link to comment
Share on other sites

1 hour ago, Schmitzi said:

 

thanks. So, overkill or not :grin:, is the "New Nintendo 3DS XL" OK too ?

I would like to have the most modern version (no DSi because of the cam)

as maybe there will be other use for it.

PS What about this "SNES-Edition", OK too ?

I suspect (but have no proof nor verification) that the "New" 3DS XL is okay as well provided you can run homebrews on it (basically if you can run Twilight Menu++ or similar). I don't have one - my most modern handheld is a 2DS XL which does run my emulators. I've seen my emulators running on 3DS models - though I have no idea if they are the "New" 3DS XL and I don't know anything about the "SNES-Edition".

My advice for the "New Nintendo 3DS XL" is to google to see if something like Twilight Menu++ would run on it.  I would guess the answer is yes but you'll have to do some homework.

 

Dave

 

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

3 hours ago, Schmitzi said:

So, overkill or not :grin:, is the "New Nintendo 3DS XL" OK too ?

I would like to have the most modern version (no DSi because of the cam)

as maybe there will be other use for it.

I have a "New Nintendo 3DS XL" where it works fine.

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

Version 1.8 is released. I spent the last 4 days working on the known remaining glitches. I've updated my github page and the top post here.

 

V1.8: 19-Feb-2024 by wavemotion Dave

  • Improvements to the TMS9918a emulation to fix 5th sprite handling and improve collision detection. Megademo, Eric in Monsterland and Interceptor all work correctly now.
  • Fix for Robots of Death II so it starts properly (was hanging on Speech detection).
  • DSi now supports up to 8192K (8MB) banked ROMs (the older DS still supports 512K). The Dragon's Lair demo will run but won't process speech/sound as the emulation can't sample the SN sound chip fast enough for that game.
  • Optimized VDP rendering and CPU memory read/writes to be a bit faster to help with older DS hardware. This gives a 5-50% speedup in video rendering depending on the game. The megademo will sustain 60fps throughout on a DSi.
  • Properly offset the text modes by 8 pixels so that games like Adventure will center text properly.
  • Improved memory density so that we end up with more cache-hits than misses when dealing with CPU memory - this gives a nice speedup of several percent across the board.
  • Lots of code comments and refactoring improvements as time permitted.

 

The VDP emulation got a ton of attention to fix both the 5th sprite detection and properly handle inter-frame collision detection. I also found one game that was just ... odd to say the least. Miner 2049er seems to have a problem with collision detection. After an archaeological dig on the forums here, it appears that a real VDP will update the 5th Sprite Number when the 5th sprite flag is not latched - I think it will represent the last sprite scanned on a line which is what I implemented and the Miner 2049er collision detection seems to work (probably by accident).

 

I've ensured that the bottles the sea-hag throws in Popeye don't leave artifacts (prefetch of data is correct) and the banner and other aspects of Pole Position are correct - both TI games notorious for their unusual use of the VDP.  It helps that @Asmusr, @Tursi and @nanochess (mostly on the Colecovision side) have left piles of VDP test programs that I found in my searching the archives here which has let me vet out the proper VDP functionality. 

 

DS994a has come a long way - the last two releases have been about improving the accuracy of emulation without sacrificing emulation speed. The design philosophy remains the same: have the ability to play Hunt the Wumpus on the toilet. As such, I'm okay sacrificing a bit of accuracy to make the games playable at full frame rate ... fortunately I found some significant speedups in the VDP rendering. Turns out a lot of what gets written is the background color which I've now optimized for. I also realized that much of the VDP scanline rendering is to even boundaries and instead of writing a byte, I can write 16-bits or 32-bits at a time which gained a ton of speed.

Most actively developed emulators asymptotically approach 100% accuracy - but never quite reach it. I'd now put DS994a about 95% in terms of accuracy - all your favorites should play smoothly even on older hardware. Enjoy!

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

22 hours ago, Schmitzi said:

 

thanks. So, overkill or not :grin:, is the "New Nintendo 3DS XL" OK too ?

I would like to have the most modern version (no DSi because of the cam)

as maybe there will be other use for it.

 

PS What about this "SNES-Edition", OK too ?

 

 

FYI DaveB's original post regarding recommending the DSi XL/LL model:
 


 

  • Like 1
Link to comment
Share on other sites

17 hours ago, wavemotion said:

The VDP emulation got a ton of attention to fix both the 5th sprite detection and properly handle inter-frame collision detection. I also found one game that was just ... odd to say the least. Miner 2049er seems to have a problem with collision detection. After an archaeological dig on the forums here, it appears that a real VDP will update the 5th Sprite Number when the 5th sprite flag is not latched - I think it will represent the last sprite scanned on a line which is what I implemented and the Miner 2049er collision detection seems to work (probably by accident).

Miner2049er works by accident in the original code. The code checks the VDP status register for sprite collision and only tests which sprites are colliding when it's set. However, instead of >20, the collision bit, it checks >02, which is part of the 5th sprite index. This value counts up continuously every scanline until it's latched by a fifth sprite or end of frame, so basically Miner2049er checks sprite collisions at random. ;)

 

My first fix in Classic99 just set it to a random value, that also made Miner work. I also tried correcting the bit test to verify my theory still worked, and it was fine.

 

  • Like 6
Link to comment
Share on other sites

With the upcoming 2.0 release of my emulator, I've decided to repurpose this thread as the one-DS994a-thread-to-rule-them-all (seems others in the community have done the same with their projects).

 

For the big 2.0 release in a week or so, I'll be switching to a newly designed splash screen:

image.png.f05c3416330d3252f64330bfec795463.png

 

I just finished putting in preliminary support for RPK (Rom PacKs) - the same ones used by MAME (formally MESS). Beta testers are playing with it now.

 

With limited CPU and memory resources available, DS994a is not the fastest to depack - but a typical classic-era cart in RPK format is up and running in about a half second (hardly noticeable) but some of the really big homebrews (e.g. Flying Shark) will take 3-4 seconds to depack into memory. A message is displayed on the emulator while the depacking is being accomplished.

 

image.png.3abaa1c5f6b4aa77f91865cac94f73ac.png

 

RPKs can have disks associated with them on load.  For example, if you have these files in the directory:

  • Adventure.rpk
  • Adventure1.dsk

It will load the .rpk and auto-mount the disk as DSK1 (you could similarly have Adventure2.dsk and Adventure3.dsk to mount additional disks as DSK2 and DSK3)

 

For RPKs, I'm supporting the following PCB types:

  • standard
  • paged  (also paged12k and paged16k)
  • gromemu 
  • paged377
  • paged378
  • paged379i
  • mbx
  • minimem 
  • pagedcru

These two are still not done (but probably of minimal value anyway):

  • super - Actually, I do support a Super Cart of 8K (mostly for a few Infocom titles)... just not the 32K CRU-banked version. The CRU handling is trivial but the way I do my memory layout will make banking RAM non-trivial.
  • paged7 - I tried but failed to get TI-Calc to run using this. There are converted _8 (non-inverted banking) versions that work fine and it's hard to imagine anyone sitting back on the couch with DS99/4a and wanting to crunch numbers.

 

Please note, I'm still a fan of and will always support mixed-mode files (C/D/G/8/9 and now '0' for System GROM replace).

 

If anyone wants to play with the beta with RPK support, feel free to contact me.

 

 

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

Okay... I managed to get 'super' working with the 4 banks of 8K = 32K of RAM. It's not yet persistent but I'll work on that.  That leaves just 'paged7' which I'm struggling with and must walk away from for mental health reasons :)  It's possible that I just have a bad RPK of TI-Calc in that format.

 

I also added 'paged12k' and 'paged16k' (both use the normal 'paged' handler with the only difference being that 'paged12k' will internally build up two 8K ROMs out of the original 4K and banked 8K ROM in the RPK so that the logic is simplified).

 

I also found a big speedup in the RPK depacking... sped it up by a factor of 2.  Even fairly large game ROMs now load in 1-2 seconds.

 

I have questions - maybe @mizapf can provide some guidance...

 

  1. Of the first 100 RPKs tested, a few of them had filenames inside the XML that didn't match the case of the files in the zip. e.g. somefile.BIN vs somefile.bin). I've switched to case insensitive searching which I assume is fine? If someone really tried to distinguish two different ROMs via filename casing, they get what they deserve.
  2. How strict does MAME handle the layout.xml file? That is, if an element tag is missing or some element that doesn't impact the actual algorithm of figuring out the layout... does it complain? Right now, I'm being fairly strict but I could loosen that.
  3. I saw somewhere there was a 2MB limit imposed for ROMs in the RPK... but we have examples of ROMs larger (Dragon's Lair demo comes to mind). I'm not strictly enforcing the 2MB limit anywhere on large bankswitched non-inverted (378) carts.

Thanks much in advance!

  • Like 2
Link to comment
Share on other sites

The unzip implementation in MAME uses an own string compare (core_strnicmp, see https://github.com/mamedev/mame/blob/1f9c92a4ccb138e60ed1b88ab5bb78a87961745b/src/lib/util/corestr.cpp) which is case-insensitive ... maybe as a courtesy for Windows users. (For a 25-years-long Linux user like me, case insensitivity always tasted strange. I early learned that "readme" is not "README" and lived with that.  🙂 )

 

One restriction is when you use a type that makes use of "rom2_socket"; in this case, you can only have two 8 KiB ROMs (8K for each bank). The gromemu and other paged cartridges only use "rom_socket". The type "gromemu" allows for 32 MiB ROM space (4096 banks). This was extended further and further over the years, but this should be the upper bound with the current banking technique.

 

There are some error conditions that indeed prevent the cartridge to be loaded. The doctype definition is at https://github.com/mamedev/mame/blob/1f9c92a4ccb138e60ed1b88ab5bb78a87961745b/src/lib/formats/rpk.cpp.

 

 

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

3 hours ago, mizapf said:

One restriction is when you use a type that makes use of "rom2_socket"; in this case, you can only have two 8 KiB ROMs (8K for each bank). The gromemu and other paged cartridges only use "rom_socket". The type "gromemu" allows for 32 MiB ROM space (4096 banks). This was extended further and further over the years, but this should be the upper bound with the current banking technique.

Many thanks for the usual helpful answers!

 

32MB does, indeed, make sense as the upper limit (4096 possible banks using even addresses in the cart-space range) without resorting to some trickery (which I understand @Tursi has done because... well... he can).

 

The oldest DS hardware only has 4MB of RAM and that must be shared by the system, emulator, ARM7 processor for touch-screen and video rendering, etc.  So I can only comfortably support 512K ROM loads on that system... for the larger DSi systems, I have 16MB of RAM of which about 12MB can be used for cart loads (and I'm going to limit to 8MB to give myself room to expand to new features for the emulator).

 

Edit: got 'paged7' working... though not as accurate as MAME. I simply build up a normal 32K paged ROM from the two 8K ROMs. It means that should TI-Calc write to >6000, >6002, etc. it would page switch incorrectly (it should only happen on writes to >7000, >7002, etc). But it seems well behaved and it simplifies my logic greatly.

  • Like 2
Link to comment
Share on other sites

1 hour ago, Hwlngmad said:

I don't suppose there is a video tutorial on how to get this set up on a DS, or 3DS for that matter?  I am just wondering as definitely having the 'ole TI99/4a on a modern-ish device would be great.

The emulator is trivial to setup - just place the DS994a.nds (which is a DS executable type) on an SD card and put your BIOS in /roms/bios and put your ROMS wherever you want (the cool kids use /roms/ti99)

 

Getting the emulator launched is not as trivial. Here you need to use something like Twilight Menu++ or Unlaunch or similar if you are on a DSi or above. It's a soft-mod and the best guide is https://dsi.cfw.guide/

 

If you are running on an older DS-Lite/Phat (one of the originals!), you would need something like a Flashcart - the R4 or cheap clones works well enough.

 

The key is to find a way to get homebrews running... once you have your foot in the door, all 7 of my emulators (and another dozen by other developers) are going to play.

  • Like 2
Link to comment
Share on other sites

1 hour ago, Hwlngmad said:

I don't suppose there is a video tutorial on how to get this set up on a DS, or 3DS for that matter?  I am just wondering as definitely having the 'ole TI99/4a on a modern-ish device would be great.

The soft-mod guide for 2DS/3DS is https://3ds.hacks.guide. Just like Wavemotion mentioned, you'll need Twilight Menu++ once the soft-mod is complete.

 

I know you asked for a video. Watch a recent one to get familiar with the process, but I recommend following the written guides when you actually try to do the mod. There are a lot of steps.

  • Like 3
Link to comment
Share on other sites

@mizapf - found another strange one.  

 

as_robotron_2084.rpk

 

Both roms are overdumps - they are 8.4K

 

My emulator refused to load them as it wouldn't load a 'C' rom of that size into the 8K socket.

 

I guess I should... truncate? I need to depack the whole file so I'll have to do it to some temporary buffer of larger size I guess and then move just 8K in.  But it feels wrong.

 

 

Link to comment
Share on other sites

You can safely truncate the files. If you look at the files in a hex editor you can see that after 0x2000 bytes there are only zeros.

 

This is MAME's output (-oslog):

 

[:gromport:single:cartridge] Paged PCB 16K
[:gromport:single:cartridge] No GROM dump
[:gromport:single:cartridge] ROM dump size=0x20fa
[:gromport:single:cartridge] Second ROM dump size = 0x20fa
[:gromport:single:cartridge] Can only use 8K for second socket; dump truncated
[:gromport:single:cartridge] Can only use 8K for first socket when there is a second socket; dump truncated.
[:gromport:single:cartridge] ROM bank mask=0x0001 (using ROM1/ROM2)

 

The ZIP files contain more reliable dumps, as I reviewed most of them for correctness (some have a CRC word at the end). But you may have to concatenate the ZIP dumps for the CPU ROM space and GROM space, as the ZIP files contain per-chip dumps.

 

Edit: In the case of Robotron, just take the two files from the ZIP file. They should already fit.

  • Like 3
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...