Jump to content

ADAM Emulation and CP/M Disk Problems

Recommended Posts

So I'm working on cleaning up the ADAM emulation for ColecoDS and have run into a problem I can't yet solve.


Right now, the emulation supports two drive bays - a DISK drive at up to 320K (DSDD) and a TAPE drive at the standard digital data pack capacity of 256K.


  • Both virtual drives work fine for EOS disks/games/programs (e.g. Super Donkey Kong, SmartBASIC, etc.) - no problems reading and writing and saving back to the SD card as a .DSK or .DDP file. I can save high scores, save game states in Super Zaxxon, etc.
  • Both virtual drives work fine for any flavor of T-DOS disks/games/programs - no problems reading and writing and saving back to the SD card as a .DSK or .DDP file.
  • But CP/M 2.2 disks are driving me nuts. I can read them fine - list directories and run programs (Infocom Games and various utilities) but as soon as I try to write to the virtual .DSK it gets screwed up. I end up either destroying the disk image in memory or some other malady (all files are removed from the directory listing, or the disk suddenly gets marked as R/O when it was R/W just second before, etc).  I've been sticking to standard 160K disks with no special attributes so as to not introduce issues with larger capacity disks.


And it's perplexing. The disk emulation handles the proper ADAM sector skew factor of 5 and appears to be handling the block transfer to and from main memory at the proper timing. I'm still debugging what is obviously a problem in my emulation but if anyone has any clues about what oddness might lie in CP/M write I/O handling on the ADAM, I'm all ears! Even the smallest clue can help me narrow in on my issue. I've been googling facebook and the forums here for clues - and although there are occasional mentions of oddness with CP/M and ADAM, there isn't anything definitive that I can point to.


I have a hunch it might have something to do with how I initialize main ADAM memory. CP/M disks seem to be picky about the state of RAM when the system comes up... 

Appreciate you guys!

Link to comment
Share on other sites

Could it be because the directory is in a different location on a CP/M disk as opposed to an EOS disk? Just tossing out an idea. That would certainly destroy the disk if a CP/M directory was being written back to the EOS directory location when you write something to the disk.


All this stuff is mostly above my pay grade so I probably have no idea what I'm talking about.

  • Like 1
Link to comment
Share on other sites

I never could make CP/M to boot with CoolCV, it gets stuck in the loading screen.


I'll try to give another look as CP/M tends to be pretty compatible because every disk access passes through the BIOS.

  • Like 1
Link to comment
Share on other sites

2 hours ago, nanochess said:

I never could make CP/M to boot with CoolCV, it gets stuck in the loading screen.

I had that issue for the longest time. I don't understand why, but the only way I could get CP/M disks to boot with my emulator was to initialize all of the ADAM RAM to 0x38 on a "cold-start".  As I recall, there was no other pattern from 0x00-0xFF that worked reliably.  ADAMem initializes main memory as WORDs (the lower byte of the word to 0x00 and the upper to 0xFF but that wasn't any more useful in getting CP/M disks booting).



If I set my emulator to use RANDOM memory at startup, CP/M disks would boot about 1 in 10 tries but most of the time would just get stuck on the loading screen waiting for the A> prompt.


  • Like 1
Link to comment
Share on other sites



Okay, Clue, tonight we check everything in the right-hand column...


I spent the evening (and early morning with coffee) going back through my code, the ADAM Technical Manual, the ADAMem and MAME drivers and ... nothing.


I took a guess that maybe the writes from CP/M was pulling the same trick I've seen on reads by some programs (most famously by Super Donkey Kong and Super DK Jr) where the clever game programmer would request to start the NEXT block of data transfer knowing that the CPU could outpace the physical tape/disk and so read and process the last 1K block while the disk/tape controller was slowly filling in behind it. I solved this last year by slightly buffering the read requests so that it does not "instantaneously" fill the read-buffer but will delay a few frames (arbitrary but it worked) before it starts to copy the read-buffer into main RAM.  Otherwise games that pull this trick will have wrong data in RAM (Super DK will have massive graphical glitches while Super DK Jr. will fail after completing the first screen, etc). With this as my new guess, I hacked in a quick-and-dirty write delay cache... which didn't seem to help any (admittedly it was done sloppily enough that I might have gotten it incorrect - I pulled it back out for now).


I also remember CP/M utilizing the expanded RAM (my emulation is a 128K Adam with one bank of expanded RAM) - I thought it was only for a small RAM Disk but maybe it has other uses and I'm not handling something correctly... so I temporarily disabled the extra bank and while the small RAM Disk did disappear, CP/M disks did not work any better.


So I'm back to thinking it's how main RAM is setup. It's just too quirky that CP/M is so picky about what the contents of RAM are on a cold-boot and there is something here I'm just not yet understanding.


Now it's not the end of the world if CP/M programs can be run but not write back to disk... ColecoDS is a portable/handheld emulator and being able to play games is more important than full-blown general-purpose emulation... but I'd like to understand and get it as close to perfect as possible.

[slight rant mode - feel free to skip!]

As an aside, having worked more than 1000 hobby-hours over the last 3+ years on various classic emulators, I can say that the ADAM is the most mysterious in terms of finding definitive technical information. Even the obscure Tatung Einstein got a pile of books from the manufacturer describing the inner details of the hardware, full schematics, timing diagrams, best practices, etc. Coleco didn't seem to release as much technical information and a lot real knowledge appears tribal in nature. Worse, I see gaps from (clearly) knowledgeable people who were once on Atari Age whose posts are now taken down (I assume by request of the person(s) who left... a shame and feels a bit like the "I'm taking my ball and going home!" attitude). Other times I see people say they will respond to a question in private (email, PMs, etc.) which doesn't help grow the knowledge base. I'm very thankful for what documentation does exist - and to those pioneers who make sure that their knowledge is spread far and wide - it's those people who share information freely and publicly that help the hobby the most.

  • Like 1
Link to comment
Share on other sites

Sorry, I got nothing for you as this is far beyond my pay grade.


it’s odd that there wouldn’t be an obvious answer in the ADAMem source code especially since CP/M works quite well in it. Perhaps send Geoff Oltmans a message on here or the ADAM FB Group.


The problem definitely isn’t the difference in what block on the media the EOS directory is placed compared to what block on the CP/M media as the CP/M BIOS probably handles that.


Extra RAM, up to 64K that CP/M can recognize and use as a RamDISK, should not be an issue… as you have found.


Only 160K disk images are compatible with the original CP/M.


Try upgrading a vanilla version of CP/M with ABP (Adam Bios Patch) to make CP/M compatible with larger memory expanders and larger sized disk images. I put together a disk image for the ADAM Archive with all the versions of ABP that I could find. ABP was the beginning of T-DOS but without all the extra bells and whistles of T-DOS and some of the incompatibilities between these two OS choices. If an patched version of CP/M fixes the issue, then we are a big step closer to figuring out what the issue is in ColecoDS.


Probably best to use ADAMem DOS or SDL to upgrade CP/M with ABP, test and then copy to the SD card and try with ColecoDS.


  • Like 1
Link to comment
Share on other sites



I had to go over the ADAMem code about a dozen times before I saw a subtle but significant difference in how I cache the block being read from tape/disk vs the way Marcel does it.  It didn't help that ColEM which is what I started with for Adam emulation is so close to the ADAMem implementation - roughly the same layout, functions, variables and it's clear that the two code bases share more than a passing similarity and that caused me to be a bit over-sure of my caching algorithm.


I now follow the ADAMem block caching algorithm almost exactly - my timeouts are almost the same though I'm hooked into the VDP vertical blank for timing which is a little course but gets the job done.


That removes almost every hack I had in place for ADAM disk/tape and memory handling.  I no longer need any special memory pattern to make CP/M disks boot and I can read/write and save back a CP/M disk with no issues. The only remaining weirdness is that Adam Bomb 2 remains incredibly picky about the state of main ADAM RAM on a cold start. I'm still using a set pattern to get it to come up reliably... but otherwise things are in a much better place.  Compatibility for Adam games should really shoot up - and I'm excited enough that I'll probably rig up a 2nd virtual disk drive.


A new ColecoDS release soon - I've got a bit of cleanup to do and a ton of debug to remove.


Huge thanks to Marcel and ADAMEm for a roadmap to follow.




  • Like 4
Link to comment
Share on other sites

Okay... more questions.


Disk emulation is working much better for me now - but I'm perplexed by how CP/M 2.2 and T-DOS 4.5x handles disks and drives of varying size.


I know on T-DOS (and presumably via a patch on CP/M) you have to configure your drives - providing how big they are (160K, 320K, etc).


So I did that and told T-DOS that my first drive was 320K and my second drive was 160K.


So far, so good. I was able to make a 320K T-DOS boot disk with a bunch of utilities on there - it boots and the utilities all load and run reasonably well.


But this is where it gets strange. If I put a 160K T-DOS disk into the second configured drive, it works fine - files read and run without issue. I guess that's because I told T-DOS that drive was a 160K drive.


But if I put a 160K T-DOS disk into the first drive (configured as 320K max), it will show the directory but things don't load right - most programs I try to run crash and a CP/M STAT command on that drive freezes. If I try to copy *.* to, say, the RAM drive, it will keep trying to copy the same file over and over (no errors - just copying it forever) as if T-DOS misunderstood the directory structure on the 160K disk.


Why does T-DOS care if I put a 160K disk into a drive that can support 320K?  Even an EOS formatted disk will work properly for SmartBasic which will see the proper space on both a 160K and 320K disk ... now I realize that EOS is a much simpler / linear block structure ... but you would think T-DOS could figure it out by reading the disk and saying "yeah, this is a 160K disk and even though it's in a 320K max drive, I can handle it".


Is this just a limitation of how T-DOS (and, probably, CP/M) work?  I went through the ADAM CP/M 2.2 manual and the T-DOS 4.5x manual but nothing specifically addressed this.


From my endless DOS years, I was able to use different disks (single sided, double sided and different densities) in the same drive with no issues.


Or is there still something buggy in my emulation (more likely I'd guess!)?




Okay... found this in the ADAM Survival guide which gives me a clue with the 'DISK COMPATIBILITY' comments. I suspect that the way the disk structure is laid out, a full 320K DSDD is different enough that you can't mix/match 160K and 320K disks with T-DOS... but it looks like you can mix/match 160K with 'medium-sized' (WTF?) disks that would reduce the capacity on a 320K disk but allow it to remain compatible with 160K disks (I gather that this "Eve Format" is from Eve Electronics).  Still digging my way through docs to try and come to grips with all this.




EDIT#2 ... I suspect this is another clue:


  • Like 1
Link to comment
Share on other sites

I recommend just using the proper sized disk/disk image in the specifically configured drive/drive size in T-DOS and also CP/M patched with ADAM Bios Patch (ABP). BitD when I made a T-DOS disk with the system installed on it, I would list out the drives and their sizes on the disk label or sleeve so as to avoid any of these maddening issues.




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

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.

  • Recently Browsing   0 members

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