flashjazzcat #1 Posted September 21, 2009 I'm trying cobble together a quick standard for DOS 2.5 compatible RAMdisks which will interface easily with applications which are competing for extended memory banks. Right now, there's NO reliable way of deducing how many banks a DOS 2.5 RAMdisk is using, so (for example), The Last Word requires the user to configure the program to use known free banks. Wouldn't it be nice if we had a RAMdisk driver which worked with any memory expansion (right up to 1MB), was size-configurable, and would kindly report back the number of used/free banks in a quick and easy manner? Thinking about it, it will have to allow multiple drives to make use of 1MB in AtariDOS format... Where to put the code that the application will detect? Well, why not in the CIO? My idea was to make an "M:" device. An application could try and open "M:FREE", and do an open-ended block read to get the list of usused banks (their PORTB values). If 0 bytes are returned, there's no free banks. If "M:FREE" returns a "Device not found", then the new RAMdisk isn't installed and we can assume we have to do things the old way. What other kinds of information should the "M:" handler return? What's the best format to do it in? How do we effectively return a list of banking values for the banks used by individual RAMdisks? Is it difficult to implement multiple RAMdisk numbers with DOS 2.5? I'd like to get this coded up pronto so that The Last Word can check for the device on loading. I'll also release the source code so that MyDOS coders can have a go at adapting the system - or at least creating a driver which reports back the same information. I know there are a couple of uber, multi-platform RAMdisks out there, but at least one of them takes up all the RAM under the OS just with its code. I want this handler to be very small: it doesn't have to do much. I've already got the base code for a DOS 2.5 RAMdisk driver: I just need to add the universal memory detection code and the "M:" handler. Quote Share this post Link to post Share on other sites
Rybags #2 Posted September 21, 2009 A cool idea would be the ability to dynamically reserve and release entire banks of memory. A RAMDisk by default has to use a bitmap or <whatever> to keep track of what's in use, so a nice extension would be the ability to allocate a File which reserves a given bank. Just have it use a different AUX1 byte, and probably use the AUX2 byte to specify which 16K bank to mark unavailable to the Ramdisk. e.g. OPEN #1,10,3,"M:RESERVE1":CLOSE #1 - reserve the third bank, make unavailable to user programs. To free the memory bank, just delete the file. Quote Share this post Link to post Share on other sites
flashjazzcat #3 Posted September 21, 2009 A cool idea would be the ability to dynamically reserve and release entire banks of memory. A RAMDisk by default has to use a bitmap or <whatever> to keep track of what's in use, so a nice extension would be the ability to allocate a File which reserves a given bank. Just have it use a different AUX1 byte, and probably use the AUX2 byte to specify which 16K bank to mark unavailable to the Ramdisk. e.g. OPEN #1,10,3,"M:RESERVE1":CLOSE #1 - reserve the third bank, make unavailable to user programs. To free the memory bank, just delete the file. OK - so we're decided on using "M:" in the CIO. I like your ideas. I had been going to make the M: device purely for reporting info to applications, rather than setting up the system. The RAMdisk configuration would be held in a plain text file on the boot drive, and would simply specify the RAMdisk ID numbers and their sizes. To free up banks (and it really doesn't matter WHICH banks get freed up), you just edit the config file accordingly. Re: allocating files to banks, though. It's an interesting idea. We could build a whole memory management library around a CIO device. The most important thing now is to finalise the reporting system; we can then bolt on additional functionality to the handler. Quote Share this post Link to post Share on other sites
Mathy #4 Posted September 21, 2009 Hello flashjazzcat You could also choose to implement the Percom Block. That would turn the RAMdisk into a "real" disk. DOS would see the RAMdisk as a normal disc and access it the same way. The driver would translate sectors and stuff into bank numbers and vice versa. The driver would ofcourse also detect which banks are available and which once should be used. Maybe even with "M1:" means banks x, y, z and "M2:" means banks a, b and c. Or, to make it even simpler, "M1:" means x through z, "M2:" means banks a through c. Ofcourse, a RAMdisk would not consist of just three banks. Since a RAMdisk smaller then 720 sectors isn't much use, it might be handy to limit the use of more the one RAMdisk to upgrades that can handle atleast 1440 sectors (for two RAMdisks, 2160 sector for three RAMdisks, 2880 sectors for four RAMdisks, etc). BTW MyRD2, the latest MyDOS RAMdisk driver does detect very nicely which banks are available. greetings Mathy Quote Share this post Link to post Share on other sites
flashjazzcat #5 Posted September 21, 2009 BTW MyRD2, the latest MyDOS RAMdisk driver does detect very nicely which banks are available. Would you be interested in writing a version which contains the "M:" driver and will report free banks to applications in a standard format? Quote Share this post Link to post Share on other sites
flashjazzcat #6 Posted September 23, 2009 (edited) I'm working on a version of SmartRAM by Tim Patrick with a revised RAM detection routine which will create a banking list for 1MB machines. The RAMdisk driver itself only creates a single RAMdisk of up to 130K (1050 "Enhanced" density), but it at least offers the chance to build in some kind of free memory reporting system. It's also pointed me in the direction of DOS 2.5's internal banking table. If I can figure out how to establish the length of this table and whether or not the standard DOS 2.5 RAMdisk is installed, that's another possible route towards automatic RAM detection. Edited September 23, 2009 by flashjazzcat Quote Share this post Link to post Share on other sites
Rybags #7 Posted September 23, 2009 I wouldn't call RAMDisks of small size "not much use". For years (and even now) I've used the hacked DOS 2.5XL which only uses the RAM under the OS. Fair enough, it's not a user-accessable RAMDisk, but only used for MEM.SAV and DUP.SYS. But still, just being able to have it resident, and only needing the 9K or whatever to do so is immensely useful and timesaving. Quote Share this post Link to post Share on other sites
flashjazzcat #8 Posted September 23, 2009 I wouldn't call RAMDisks of small size "not much use". For years (and even now) I've used the hacked DOS 2.5XL which only uses the RAM under the OS. Fair enough, it's not a user-accessable RAMDisk, but only used for MEM.SAV and DUP.SYS. But still, just being able to have it resident, and only needing the 9K or whatever to do so is immensely useful and timesaving. I agree: I used to use a similar system myself to great effect before I had 128K. To differentiate between various "M:" handlers and to minimize the possibility of false positives, I'll use an XIO command to return a buffer containing a list of free memory banks to a specified memory location. LW will check for this, and if it errors out (device not found, no such function in handler, etc), it'll just revert to the "manual" configuration. That's the plan, anyway. The new RAMdisk handler is fundamentally a revised SmartRAM with a (very) small relocatable CIO handler tagged on the end. It will be bundled with The Last Word as an alternative to the stock 130XE driver. It's something I aim to add to as time goes on, and I'd like to incorporate its functionality into a MyDOS compatible RAMdisk driver at some stage. SDX's user-accessible data table already provides all the required information, so that DOS doesn't need a RAMdisk with "M:" support. Quote Share this post Link to post Share on other sites
Mathy #9 Posted September 23, 2009 (edited) Hello Flashjazzcat Why not "compress" the banking table? On a 1024 kB RAM extension, you'ld normally get a 64 byte banking table. But $D301 only consists of 8 different bits. You could reduce the 64 bytes of the banking table into an 8 bit value of the bits that are used. On the 130XE (with "just" 64kB + 64kB) that would be "00110000" (or should that read: "00001100"?). Or one byte. But the typical 130XE extension is different from the typical 800XL upgrade. For instance, an 130XE would have 320kB while an 800XL would have 256kB of memory. If all upgraded 800XL's use the same four banks of memory as main memory, you'ld just need one bit to flag "130XE or 800XL". If not, you'ld need a second byte to tell which banks are used as main memory. Then there's the "what does bit 5 control" question. IIRC bit 5 (ANTIC control in the non-upgraded 130XE) can do different things in different upgrades: 1) ANTIC gets access to extended or main memory depending on the state of bit 5, as in the non-upgraded 130XE. Bit 5 is NOT used to control banks of memory. 2) ANTIC gets access to extended or main memory depending on the state of bit 5, but now bit 5 IS used to select banks of extended memory 3) ANTIC only sees extended memory, while bit 5 is used to control banks of extended memory 4) ANTIC only sees main memory, while bit 5 is used to control banks of extended memory 5) ANTIC sees what the CPU sees, while bit 5 is used to control banks of extended memory You could use one bit to test if "1)" is the case and if not, use 2 bits to show which of the other 4 possibilities is true. This way, your new banking table would only be a couple of bytes long and would have a fixed length, independent of the size of the memory extension. And you could even use three extra bytes if a memory extension uses two addresses for selecting banks, like the MegaRAM III upgrade (it uses $D600 to select between 4 banks of 256kB (selected via $D301) for a total of 1MB). Two bytes for the address that's used and one byte to show which bits of this address are used. greetings Mathy Edited September 23, 2009 by Mathy Quote Share this post Link to post Share on other sites
flashjazzcat #10 Posted September 24, 2009 (edited) Why not "compress" the banking table? On a 1024 kB RAM extension, you'ld normally get a 64 byte banking table. But $D301 only consists of 8 different bits. You could reduce the 64 bytes of the banking table into an 8 bit value of the bits that are used. On the 130XE (with "just" 64kB + 64kB) that would be "00110000" (or should that read: "00001100"?). Or one byte. But the typical 130XE extension is different from the typical 800XL upgrade. For instance, an 130XE would have 320kB while an 800XL would have 256kB of memory. If all upgraded 800XL's use the same four banks of memory as main memory, you'ld just need one bit to flag "130XE or 800XL". If not, you'ld need a second byte to tell which banks are used as main memory. Then there's the "what does bit 5 control" question. IIRC bit 5 (ANTIC control in the non-upgraded 130XE) can do different things in different upgrades: 1) ANTIC gets access to extended or main memory depending on the state of bit 5, as in the non-upgraded 130XE. Bit 5 is NOT used to control banks of memory. 2) ANTIC gets access to extended or main memory depending on the state of bit 5, but now bit 5 IS used to select banks of extended memory 3) ANTIC only sees extended memory, while bit 5 is used to control banks of extended memory 4) ANTIC only sees main memory, while bit 5 is used to control banks of extended memory 5) ANTIC sees what the CPU sees, while bit 5 is used to control banks of extended memory You could use one bit to test if "1)" is the case and if not, use 2 bits to show which of the other 4 possibilities is true. This way, your new banking table would only be a couple of bytes long and would have a fixed length, independent of the size of the memory extension. And you could even use three extra bytes if a memory extension uses two addresses for selecting banks, like the MegaRAM III upgrade (it uses $D600 to select between 4 banks of 256kB (selected via $D301) for a total of 1MB). Two bytes for the address that's used and one byte to show which bits of this address are used. Makes sense when space is at a premium (as with the DOS 2.5 RAMdisk driver I'm writing). The driver could easily put together a list of banking values for free banks by using the bit mask and removing the values already used for the RAMdisk. Perhaps I could include an XIO call to simply return the bit mask as well as a complete list. The question of which bit controls what is effectively dealt with by both MyRD2's and LW's memory detection routines (MyRD's is a little more exhaustive but they do the same job). It would be quite interesting to convert the resulting list of banking values into a bitmask (just a few OR instructions, I suppose). LW doesn't provide support for any banking register than $D301 at the moment, and nor does the DOS 2.5 RAMdisk driver I'm working on. The difference between DOS 2.5 and MyDOS's RAMdisks are that MyDOS doesn't need RAMDISK.COM to have a RAMdisk: you can set one up and format it manually. Any way you look at it, it's going to be necessary to interrogate MyDOS's core code to establish a) if there's a RAMdisk, and b) how many banks it takes up. We're nearly there, but I'm still waiting on a couple of technical answers from the developer. Edited September 24, 2009 by flashjazzcat Quote Share this post Link to post Share on other sites
flashjazzcat #11 Posted September 24, 2009 (edited) Just made an interesting discovery and encountered several problems when testing the default DOS 2.5 RAMdisk handler. A discovery first: I noticed my DLIs were getting upset again when reading/writing to a RAMdisk under DOS 2.5. I can't imagine why, but DOS 2.5 sets NMIEN ($D40E) to 1 (merely a convenient shorthand for clearing all the NMI bits, by storing the contents of the Y register there) when accessing the RAM disk. Putting three NOPs at $12DA cures the problem. Is this likely to cause any side-effects? SpartaDOS X only clears the NMI bits during high speed, critical SIO. It doesn't touch NMIEN during RAMdisk access, so in normal use, there's never any problem when using SpartaDOS with DLIs enabled. The MyDOS RAMdisk handler does exactly the same thing, causing unsightly screen glitches when accessing a RAMdisk. No doubt this can be patched as well. The second puzzling discovery is that DOS 2.5's RAMdisk driver doesn't seem to like any access to extended RAM. With a 320K machine, no matter which extended banks I designate for my own use (even if I keep well away from $E3, $E7, $EB, and $EF), the system crashes when I exit to DOS. MyDOS doesn't seem to mind, providing you don't use the banks in use by the RAMdisk. I'm still working on this problem with DOS 2.5. Using my modified SmartRAM driver, the problem disappears. I looks like I'll be releasing a number of small "patching" programs with The Last Word. DOS 2.5 users could always write the modified DOS to disk. I'm going to see if a NMIEN patch is possible with MyDOS, too. At all but the very highest SIO speeds, SDX displays none of the DLI problems, and its RAMdisks live in idyllic peace and harmony with The Last Word's extended memory text buffers. ------------------------------------------ EDIT: The offending code is at $C02 in MyDOS 4.53, where there's a LDA #0 / STA $D40E. Three NOPs at $C04 fixed the DLI problem. Edited September 24, 2009 by flashjazzcat Quote Share this post Link to post Share on other sites
+CharlieChaplin #12 Posted September 24, 2009 Hmm, maybe an older patch of DOS 2.5 helps a little. A programmer from (former) eastern germany patched DOS 2.5 to allow for bigger Ramdisks (up to 256k or better 2x 128k). While doing so he also corrected dozens of bugs in DOs 2.5 and commented these bugs/corrections (errm, in german language). Afaik he named this patch DOS 2.71 and when I discovered it, I changed the version number to DOS 2.75 just to remember later it has something to do with DOS 2.5... Attached this version and its RD driver here (think you have to rename the RD256kb.COM driver to Ramdisk.COM to see what I mean). If I remember correctly with this patched DOS 64k and 128k ramdisks were possible with most (all?) XE-compatible upgrades, whereas 256k was only possible with upgrades that are using 8ACE blocks (Newell, Rambo, TOMS, Atari Magazin, etc. - not with Compyshop, Megaram 1,2,3 and others that use 26AE blocks)... Greetings, Andreas Koch. P.S.: If the attached DOS version and the RD-driver is useless, I am sorry - I am no programmer... Quote Share this post Link to post Share on other sites
flashjazzcat #13 Posted September 24, 2009 (edited) Hmm, maybe an older patch of DOS 2.5 helps a little. A programmer from (former) eastern germany patched DOS 2.5 to allow for bigger Ramdisks (up to 256k or better 2x 128k). While doing so he also corrected dozens of bugs in DOs 2.5 and commented these bugs/corrections (errm, in german language). Afaik he named this patch DOS 2.71 and when I discovered it, I changed the version number to DOS 2.75 just to remember later it has something to do with DOS 2.5... Attached this version and its RD driver here (think you have to rename the RD256kb.COM driver to Ramdisk.COM to see what I mean). If I remember correctly with this patched DOS 64k and 128k ramdisks were possible with most (all?) XE-compatible upgrades, whereas 256k was only possible with upgrades that are using 8ACE blocks (Newell, Rambo, TOMS, Atari Magazin, etc. - not with Compyshop, Megaram 1,2,3 and others that use 26AE blocks)... Greetings, Andreas Koch. P.S.: If the attached DOS version and the RD-driver is useless, I am sorry - I am no programmer... Brilliant, thanks! I'll have a good look at this. I'm interested to know about as many popular OS's as possible: I want to make The Last Word as compatible as I can. I thought more about the NMIEN issue tonight and it suddenly became obvious why the RAMdisk driver disables interrupts: in case user-defined interrupt handlers reside in the $4000-$7FFF region. Still, it's interesting that SpartaDOS X doesn't appear to observe this precautionary measure. I've decided that the best solution to the DLI issue is for LW to temporarily patch the DOS 2.5/MyDOS RAMdisk code and then revert the changes on exit to DOS. This gets rid of the DLI flicker problem but doesn't upset any software with interrupts in the banked region. Edited September 24, 2009 by flashjazzcat Quote Share this post Link to post Share on other sites
flashjazzcat #14 Posted September 25, 2009 (edited) Fixed DOS 2.5 "Exit to DOS" bug. This DOS expects the exact same value to be in PORTB as was there when the application started when there's a RAMdisk set up. I have enough information now to wrote an "M:" handler which will simply interface with existing RAMdisks and provide a free bank list under DOS 2.5 and MyDOS. LW won't require it, but if "M:" is present it will greatly simplify the setup process. The big pay-off is that the "M:" handler can get updated independently of the main application, which only cares about the free bank list, not how it was arrived at. Edited September 25, 2009 by flashjazzcat Quote Share this post Link to post Share on other sites
flashjazzcat #15 Posted September 26, 2009 I started writing a loader for LW which first analysed DOS 2.5/MyDOS and then passed on the banking table to the main program. It's so reliable, though, that I decided to go ahead and build the detection routines right into the main application. This threw up a massive bug in the banking routines (improper bitmasking which was basically making LW overwrite portions of the RAMdisk banks it had taken such pains to avoid), so this week's work has been time very well spent. Quote Share this post Link to post Share on other sites