• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

Simple 68k memory disk driver

bbraun

Well-known member
I've been experimenting with 68k driver development with codewarrior and the results so far are a very simplistic, but apparently functional ramdisk driver. It's not at all useful on its own, but represents lots of information collected into a somewhat usable form. Hopefully it can be useful to others learning this stuff as well.

Basically, there's the 'memdrv' project that builds the driver that handles open/close/prime/control/status calls. MacOS drivers don't follow C or Pascal calling conventions, so assembly glue is necessary. Codewarrior automatically generates this glue, and funnels all driver calls to main() in the form of:

Code:
short main(Ptr paramblock, Ptr dctlentry, short cmd)
Where the paramblock and dctlentry pointers are pointers to the IOParam/CntlParam structure and dctlentry is the Device Control Entry structure. cmd is whether the call is Open, Prime, Control, Status, Close.

Once that's all straightened out, you've got yourself a driver in the form of a DRVR resource.

However, getting a driver is only half the battle. Next up is loading the driver, and in this project is handled by the 'loaddrv' codewarrior project. Essentially, it loads the DRVR resource (the actual driver built above), traverses the UnitTable (a table of pointers to device control entries) looking for an empty slot in a valid range, and calls OpenDriver to create the DCE structure for the DRVR resource, and insert it into the UnitTable at the slot found earlier.

Once the driver is loaded, it has to let the File Manager know a new disk is available. It then finds the drive queue, locates an available drive number, creates a DrvQEl structure, and inserts the structure representing the disk into the system's drive queue. After that, the memory disk isn't initialized with any known filesystem, so it still can't actually be used. 'loaddrv' then uses DIZero() to initialize the disk, and from this point, it should show up in the finder and be usable.

A word of caution when testing this, don't quit the loaddrv.A application until after you've ejected the disk. The resources are allocated within the context of the app instead of the system, so quitting while the driver is in use will cause a crash/hang.

Anyway, the code is here

 

techknight

Well-known member
Nice.... this fills in the gap for people like me that dont exactly know how to write drivers for the mac, especially mounting disks via a driver through finder. Thanks for the upload.

At least using this, if i can figure out the protocol to the Mac Bottom serial HDD, i could modify the driver for that application instead of using RAM.

 

Trash80toHP_Mini

NIGHT STALKER
Looks like you might be getting very serious about addressing that 1 GB of RAM that trag has been talking about! VM at silicon speeds via a RAMDisk Card in a PDS Slot? :?:

 

bbraun

Well-known member
Well, it sounds like trag's project would be mapped into the address space and not need a driver in order to be accessed, and there's already some RAMdisks out there. This is more a stepping stone to other projects, mostly pure software based. There's still a lot of pieces to put together before something like this would be terribly useful loaded from a declrom. What would be useful in that regard is a simple nubus dev card that contained an easily programmable declrom, and some LEDs controllable by mapped registers or something along those lines. Maybe a cheap amount of storage of some sort (a small amount of EEPROM, or just ram, or something). Just as a learning tool for writing a declrom and an associated driver capable of accessing resources on its own card.

In the course of figuring this out, I've got some ideas for some tools that would be helpful for working in this space in the future, so that's probably my next step.

It has been pretty enjoyable doing all this on the pb540c so far. The ability to use wifi to back up progress as it is made (I don't trust ~20yr old hdd's), and being able to use an external monitor on occasion. The 2nd head is pretty useful for development, where I can have macsbug up on one screen and have the code up on another.

 

Trash80toHP_Mini

NIGHT STALKER
PDS is a LOT faster and way more convenient than NuBus. Do you need any info about DeclROM development from DCaDftMF3E or anything from GttMFH2E for your work?

The Duo System DevNote .PDFs have a LOT of DeclROM development info inside!

Multiple Dispaly Setups ROCK!!!!!!!!!!!! [:D] ]'>

 

bbraun

Well-known member
I was just thinking nubus out of convenience, in the sense that speed doesn't really matter for a dev board with some LEDs and a few KB of storage, and there's a whole lotta different nubus machines that could be used for development, as opposed to figuring out which PDS form factor is being targeted. I'm not sure what, if any, difference nubus vs. pds makes in terms of declrom development. I suspect the Slot Manager treats them the same in terms of enumeration, declrom interpretation, and the driver unit table population. Anyway, seeing as how I'm a software guy, I find it unlikely I'd get around to building such a dev board. :)

I don't need any more information on declroms at the moment, but I'm sure I will eventually. I plan to pick up both those books in the near future, for sure. For now, I'll work on some of those tools I mentioned, if for no other reason than a further learning experience on directly invoking drivers without some Manager in the way (most *Manager calls are explicitly forbidden to be called from within a driver's Prime/Control/Status routines, so for a driver to invoke another driver, it must do so directly). Then hopefully on to some of the more directly useful ideas.

I just thought I'd post this useless but working driver in case someone else was interested in driver development. When I was looking, I found lots of incomplete examples, but nothing consolidated. Maybe it'll save someone time getting started at some point, who knows.

 

trag

Well-known member
That's very exciting work bbraun. I see the limitations you mentioned, but that's still a lot further at programming low level stuff than any of the rest of us have gotten. It's cool you actually did the programming.

NuBus and PDS do look the same from the Slot Manager's point of view -- or they do as long as PDS hardware uses the correct interrupt for the slot address space it is decoding.

From a hardware point of view, it is much easier to interface to the PDS slot than it is to the NuBus uh, bus. With PDS the address and data buses each have their own signal lines. NuBus sends both addresses and data over the same 32 signal lines, so some intelligence and muxes are needed to route the signals on the DA (AD?) signal lines to the address or data circuitry on the expansion card.

Well, it sounds like trag's project would be mapped into the address space and not need a driver in order to be accessed, and there's already some RAMdisks out there.
It could go a number of directions. First, I just want to get it working as a video frame buffer -- actually first I just want to get to the point where I build some hardware... I still have a few other projects in the way -- like the PEx ROM. All the stuff I've posted here has been the early concept/design iterative loop.

DDR2 memory is so cheap, it's cheaper than a usable quantity of any other kind of memory one could use at this time. And in it's cheapness, it comes in a 512MB or a 1GB chunk.

So, there will be hundreds of MB of DDR2 RAM running at a data rate of 250 MHz - 400 MHz (hoping for 333MHz) sitting there unused after the Frame Buffer gets its allotment.

I think the easiest thing is to map the excess as system RAM.

But it had occurred to me to devote some chunk of it to a RAM disk.

Here's a question for you. If I manage to map it as system RAM, would it be just as easy/beneficial/efficient to use a RAMdisk utility to convert some of it to a RAM disk, as it would be to have code/firmware that directly allocates some portion as a RAM disk?

I don't know enough about how RAM disks are created to even know if I'm stating the question clearly. If that doesn't make sense, let me know and I'll try to be more clear about what I'm asking.

What would be useful in that regard is a simple nubus dev card that contained an easily programmable declrom, and some LEDs controllable by mapped registers or something along those lines. Maybe a cheap amount of storage of some sort (a small amount of EEPROM, or just ram, or something). Just as a learning tool for writing a declrom and an associated driver capable of accessing resources on its own card.
As for a simple Mac development card, we could whip up something which maps certain bits at certain addresses to some LEDs or some such. However, I think the easier and more useful thing would be to create an adapter board from PDS (or NuBus) to one of the FPGA Development Boards. The FPGA Development Boards (Starter Kits) typically have a bunch of LEDs on board (e.g. 8) , some pushbutton switches, serial ports, parallel Flash, serial Flash, ethernet PHY and often a small LCD display.

Going this route is a tradeoff.

Option 1) Having a simple board which just maps a Flash (for declaration ROM) to a fixed address and maps some LEDs to various fixed addresses would be very simple and easy to use and require very little background on the user's part.

However, it is also of limited utility. You can only do the things that you've already designed into the board. Write to addresses on the card and make the LEDs light or go off, etc.

Option 2) Having an FPGA Development Board interfaced into the PDS (or NuBus) slot would be extremely versatile because all of the resources on the Development Board could be made available to the host Mac's address space, and reconfigured as needed. However, it would be more complicated to use and would require the user to have some knowledge of a Hardware Definition Language (typically VHDL or Verilog).

Option 2 would be more expensive than Option 1, but much more useful. But not immediately useful to someone who isn't familiar with FPGAs...

Anyway, I've touched on some of the things you've discussed. I could write a bunch more, but I don't want to hijack your thread too far.

Excellent work!

 

bbraun

Well-known member
Here's a question for you. If I manage to map it as system RAM, would it be just as easy/beneficial/efficient to use a RAMdisk utility to convert some of it to a RAM disk, as it would be to have code/firmware that directly allocates some portion as a RAM disk?
If it's mapped so it shows up to the system as available memory, just using an existing RAMdisk solution would be the way to go. It looks to me like System7 RAMdisk from the Memory control panel stores the settings (presence, size) in PRAM, and on boot the driver loads the settings, builds a disk, initializes and mounts it. Mapping as available memory would be the most versatile and easiest to use out of the box.

However, if for whatever reason not all of it was able to be mapped, but it could be accessed through a mapped register set, then we could make a driver that managed the transfers and present the RAM as a RAMdisk. This is how the Commodore REU's worked. They provided ram, but it wasn't able to be mapped as directly addressable memory due to address space limitations, so there was a register set you banged on to read/write. They also had a few other functions to handle memory copies on the device to avoid going device -> bus -> CPU -> bus -> device, although I'm not really sure a disk driver would be able to utilize that due to File Manager abstraction. In this case, I believe we could potentially boot from the added RAM, if the driver were in the declrom.

As for a development card, I completely agree that throwing more on the card would make it more useful. I was thinking of keeping it simple initially, just to reduce the number of things to debug when something goes wrong, since this is all a learning process. Baby steps and all that. If there was a way to compartmentalize things, that'd satisfy everything I think. A simple flash for the declrom, a register for basic LED and maybe some GPIO accesses, and then the rest for more complex features.

Personally, I'm not terribly familiar with or setup for FPGA dev, and a realistic assessment of my available time would put coming up to speed on that further into the future than I'd like to commit to. On the other hand, I have had some experience with several types of uControllers, like 8051's and ARM (specifically the NXP LPC family), so my bringup time on that would be a little better.

But, that's just me, if other folks are more familiar or up for tackling that side of it, I don't want to hold anything back! :)

 

trag

Well-known member
Here's a question for you. If I manage to map it as system RAM, would it be just as easy/beneficial/efficient to use a RAMdisk utility to convert some of it to a RAM disk, as it would be to have code/firmware that directly allocates some portion as a RAM disk?
If it's mapped so it shows up to the system as available memory, just using an existing RAMdisk solution would be the way to go. It looks to me like System7 RAMdisk from the Memory control panel stores the settings (presence, size) in PRAM, and on boot the driver loads the settings, builds a disk, initializes and mounts it. Mapping as available memory would be the most versatile and easiest to use out of the box.
Okay. Thank you. I think I can get it all into memory space. I'll need to read up on the MMU, I guess. How many segments can the MMU remap is the question I need to explore. The Super Slot space is 256MB per slot. So to remap 1 GB of RAM address space into slot space, I'll need to cover four slots. I guess I can do that as one contiguous segment if I use four slots with contiguous address space. The problem is, I don' t think there are four usable slots with contiguous space. I don't want to use slots 9, A, or B because the SE/30 has interrupts for those and treats them as real slots. That leaves 6, 7, 8, ... , C, D, E.

Of course, 768 MB of RAM address space is probably good enough. And I may only use a 512 MB DDR2 DIMM anyway.

However, if for whatever reason not all of it was able to be mapped, but it could be accessed through a mapped register set, then we could make a driver that managed the transfers and present the RAM as a RAMdisk. This is how the Commodore REU's worked. They provided ram, but it wasn't able to be mapped as directly addressable memory due to address space limitations, so there was a register set you banged on to read/write. They also had a few other functions to handle memory copies on the device to avoid going device -> bus -> CPU -> bus -> device, although I'm not really sure a disk driver would be able to utilize that due to File Manager abstraction. In this case, I believe we could potentially boot from the added RAM, if the driver were in the declrom.
Well, that's interesting/cool. And may be needed, if I end up using a 1 GB DIMM. All kinds of ideas come to mind from your description above. Of course, dreaming is easy; implementing is work. Your mention of booting from the added RAM, suggests the idea of putting a large Flash on the board and storing the OS in it. Have the card copy it to a section of the RAM at power-on, declare the RAM as a RAMdisk, and voila...

Whether to use 512 MB vs. 1 GB depends on whether there are single rank 1 GB DDR2 DIMMs. I'm not going to try to implement multiple ranks, when a single rank is already overkill. But, the price difference between 512 MB and 1 GB is negligible, so if single rank 1 GB DIMMs are available, why not?

As for a development card, I completely agree that throwing more on the card would make it more useful. I was thinking of keeping it simple initially, just to reduce the number of things to debug when something goes wrong, since this is all a learning process. Baby steps and all that. If there was a way to compartmentalize things, that'd satisfy everything I think. A simple flash for the declrom, a register for basic LED and maybe some GPIO accesses, and then the rest for more complex features.
Personally, I'm not terribly familiar with or setup for FPGA dev, and a realistic assessment of my available time would put coming up to speed on that further into the future than I'd like to commit to. On the other hand, I have had some experience with several types of uControllers, like 8051's and ARM (specifically the NXP LPC family), so my bringup time on that would be a little better.

But, that's just me, if other folks are more familiar or up for tackling that side of it, I don't want to hold anything back! :)
At this point, you're way ahead of most everyone else, for having done some actual coding. So you're certainly not holding anyone back.

If we could have as many boards as we want, then I would not hesitate to agree that a simple board should be first. However, every revision of the board will represent a fair bit of design effort and probably about $200 in cost. If it could be done on a two-layer board, the cost would be less than half that, but I think I should use four-layers for this and there just isn't a really cheap proto-typing offer for four-layers, as far as I know.

I'm not in any danger of developing either simple nor a complex board in the immediate future so I can just decide when I get there.

I think that it would actually be simpler to design an adapter board to FPGA Starter Kit than it would be to design a "simple" board with address decoding circuitry which will let one read a Flash or EEPROM and light LEDs and maybe read and write an array of flip-flops standing in for a register.

The disadvantage to the adapter board is that then I'd have to program the FPGA for the functionality that would have been on the simple board. But that should be straightforward and allows debugging one thing at a time. Another disadvantage is that the FPGA Starter Kit costs $200. That may be the bigger issue, but if one is going to develop any kind of peripheral, one is going to need something like that eventually. So in the long run, I don't see how spending that money can be avoided. Unless...

Personally, I think that FPGA is a better route to go than uC, because of performance. But, all my adapter board is going to do is connect the PDS pins to the FPGA pins. And something like 40 of those are going to have to travel the remaining distance on twisted pair wire with .1" headers/connectors. The same adapter can probably be made compatible with a uC development board.

So -- do you have a favorite uC development board? If so, what kind of connectors does it have for I/O? I might be able to work something compatible onto an adapter.

I'm used to the 9S12 myself but I think I'd do anything new on ColdFire because it really doesn't cost more than 9S12 except in the teeny tiny realm where I'd probably use an ATTiny anyway. But I'm not going to do any uC development, so I am happy to look at whichever uC you favor.

 
Top