SD-Cart JR: MMC/SD card reader cartridge for PCjr

Overview

SD-Cart JR

SD-Cart JR

SD-Cart JR is a PCjr cartridge which makes it possible to use MMC (or compatible) memory cards under DOS.

  • Supports MMC and compatible cards
  • Easy to use. Just add sdcart.sys to your config.sys and the cards you insert will be accessible as drive c: (or another letter if you have a hard drive)
  • Cards are treated as removable media and can be removed or replaced without rebooting.
  • An experimental boot ROM is also available, making it possible to start your system using a memory card as if it were a hard drive.
Current performance: Reads at 44 kB/s, writes at 35 kB/s. Much faster than floppies (10 kB/s). Performance can vary between cards. See section compatibility and performance for more information.


Electronics

Quite a few signals from the PCjr BUS are available on the cartridge slot, but there is no write signal. Still, this does not mean the cartridge slot cannot send information, since the address being read is in itself outgoing data! So I divided the cartridge memory space and arranged so that reading from certain address ranges would have specific side effects. (Select/Deselect the card, load a value to transmit, etc).

Since the cards communicate serially (SPI), I used a pair of shift registers (one for transmitting to the card and another for receiving) to perform parallel/serial conversion in the hope of getting better performance by exchanging full bytes with the PCjr...

The cartridge uses the CS2 signal from the slot and is therefore visible from D0000 to D7FFF.

  • Reading from D6000-D60FF loads the 74ls165 shift register with next byte to be transmitted. The value loaded corresponds to address bits A0-A7. The read returns the last byte received by the other shift register (the 74ls164).
  • Reading from anywhere in the D6100-D61FF range generates a clock pulse which causes one bit to be shifted to/from the shift registers and the card.
  • Reading from D6200 deselects the card.
  • Reading from D6300 selects the card.
  • The optional ROM is accessible from D0000 to D5FFF (24 kB)

Schematic, page 1 - PCjr Cartridge, address decoding and ROM

Schema, page 1

Schematic, page 2 - Shift Registers, card interface (voltage regulator and level converters)

Schema, page 2
Before making a PCB, I tested everything on a breadboard, but not entirely without soldering. To access the cartridge signals, I soldered wires between one of my cartridge PCBs and the DIP components on the breadboad. For the card slot, I used a small Adafruit PCB which came with its own regulator, level converter and microsd slot.

My test setup

My test setup

Wires soldered to a cartridge PCB

Wires soldered to a cartridge PCB



Once I got everything working correctly, I designed an equivalent PCB, but changed a few things.

First, instead of using an Adafruit microsd module, I decided to use a large card slot for MMC and "normal" SD cards instead of microsd only. Considering the practical limits regarding disk space (i.e, What DOS supports and if one does not want to wait an eternity when available disk space is being computed), I wanted to support and use old low capacity cards from my parts bin instead of modern cards with excessively large capacities.

Next, I also wanted the circuit to fit in a cartridge shell, so I used surface mount components to save space. The resulting PCB can fit in a cartridge shell, provided you cut some plastic here and there...

And the final addition, a footprint for installing a ROM for booting directly on the card, as if it were a hard drive.

Final PCB

Final PCB




Software

My requirements for the software were:
  1. I want to run stuff on the card, so its contents must be accessible as if it were a floppy or hard drive. In other words, it must have a drive letter, such as c:
  2. Moving the card to another (modern) machine to exchange files with my PCjr must be possible.
  3. I would like to be able to boot on the card, as if it were a hard drive, without using floppies.
For the second requirement above, it was easy. Memory cards are normally partitioned like hard disks are, using a partition table in the MBR, and normally the first (and only) partition covers all the available space. And this partition normally contains a FAT (FAT12, FAT16, FAT32..) file system, depending on the available space. Very standard and well supported by DOS, Linux, Windows, Mac OS... Still, some limitations must be considered, such as what your PCjr DOS version supports. For instance, DOS 2.10 does not know FAT16, DOS 3.3 does not support FAT16B... Creating a smaller partition and reformatting may be necessary.


The sdcart.sys device driver

Example config.sys

Example config.sys

I coded a simple device driver for DOS which scans the card to find the first partition and renders it available as a DOS drive. Installation is a simple matter of adding DEVICE=SDCART.SYS to config.sys.

The card contents will be made available through the first free drive letter at the time the driver was installed. Changing the card without restarting is supported. The driver detects removed or replaced cards and lets DOS know about it.

If you already have a hard drive, possibly jrIDE, or do not wish to boot on a card (requirement 3), the sdcard.sys device driver is all you need.

If you are willing to sacrifice a few kB/s of transfer speed to save memory, SDCARTL.SYS is also available. (It uses approx. 3kB in size instead of 9kB).

Boot ROM

System booted on an 64MB MMC card

System booted on an 64MB MMC card

I also created a Boot ROM for PCjr which replaces int 13h (The BIOS disk services) to make it possible to use a card for booting as if it were a hard drive. When using this ROM, sdcard.sys is not necessary, DOS supports the card as a hard drive. Fdisk and format can even be used normally.

At the moment, this ROM is experimental and incomplete, but still functional. Current implementation:

  • Int 13h, AH=08(read drive parameters): Geometry computed from card size.
  • Also implemented: Int13h AH=00(reset), 01(get status), 02(read sectors), 03(write sectors), 05(format track)
  • Does nothing: Int13h AH=04(verify), 18(set media type - likely not applicable anyway)
  • All other AH values are not implemented. If they are encountered, a panic message will be displayed (please report this)

Also, since I do not have a jrIDE yet, I'm not sure if my boot ROM plays well with it. But I think it should, in theory the card will be installed as secondary (81h) disk drive.



sdpart.com

sdpart.com showing card informations

sdpart.com showing card informations

Fdisk does not support devices accessed trough a drivers such as sdcart.sys, and therefore cannot be used to display partition information. Memory cards also contain additional data stored in registers (such as CID and CSD) including the manufacturer, model and serial numbers...

The sdpart.com tool can display and partly decodes the contents of those registers and show how a card is partitioned. There is also basic functionality for creating a new MBR and a partition up to 32M. The name "sdpart" implies that this should be a full partitioning tool for memory cards. In the long run it may become so, but right now, it is extremely limited. Still, it is a good tool to test if a card is compatible or it may help understand why things are not working.

The format command included with DOS has a similar limitation in that it cannot format the sdcart.sys drive. Maybe one day I will write an sdformat tool, but meanwhile cards must be formatted under another OS, or using the boot ROM.



Downloads

Version v05
March 24, 2021 (Wednesday)
  • BIOS : Improvements for co-existing with another hard drive BIOS. By default, the SD-Cart JR becomes the last drive in the system. (tested only with JR-IDE)
  • BIOS : Add an options menu to allow non-default behavior, such as:
    • Installing the SD-Cart JR as the first drive in a system with another hard drive BIOS (existing hard drive becomes second hard drive and remains accessible)
    • Installing as single drive (other hard drive not accessible)
    • Not installing the SD-Cart BIOS.
    • The option menu count down can be skipped by pressing ESC.
  • sdcart.sys : Add support for command-line options /Y (always install) and /A (install only if card present). Also displays the drive letter it got assigned to on DOS 5.
  • sdpart.com : Add a 'b' command for some BIOS tests. (for debugging purposes)
Versions: sdpart.com v0.5, sdcart.sys v0.5, bios v0.41
File(s):
sdcjr05.zip (15.9 KB)
Show previous releases...
Version v04
December 29, 2020 (Tuesday)
Compatiblity improvements and fixes.
  • sdpart.com / sdcart.sys : Add retries reading MBR (fixes some non-working cards)
  • sdcart.sys : Use CMD13 (Send Status) instead of CMD10 (Read CID) to detect card changes (Solves occasional errors with some cards)
  • sdpart.com : Add more error checking, display card info before reading MBR, so at least some info is displayed if the read fails.
  • BIOS : When reading a sector fails, it is retried at least once. (Fixes issues with some cards where drive C: would not be available)
Versions: sdpart.com v0.4, sdcart.sys v0.3, bios v0.30
File(s):
sdcjr04.zip (14.5 KB)
Version v03
December 8, 2020 (Tuesday)
  • Add support for block-addressed cards (For cards >2GB)
  • Implement >32M partition support in sdcart.sys
  • Add a 'low memory' version of sdcart.sys (sdcartl.sys). Sacrifices speed for using only approx. 3kb of memory instead of approx. 9kb.
  • sdpart.com : Display card information before reading the MBR
Versions: sdpart.com v0.3, sdcart.sys v0.2, bios v0.20
File(s):
sdcjr03.zip (14.4 KB)
Version v02
November 30, 2020 (Monday)
  • Read speed increased from 33 kB/s to 43 kB/s, thanks to suggestions from Trixter and to the use of the Multiple Block Read card commands.
  • Write speed increased thanks to unrolling and the use of 'Multiple Block Write' card commands. (max seen: 35 kB/s on an MMC card)
  • sdcart.sys : Display the type of card detected (MMC or SD) during media check
  • sdpart.com : Now display the geometry the SD-Cart BIOS will use for the card. (Computed from the card size)
  • sdpart.com : When displaying partition information, also show the CHS numbers as is, accompanied by which block they correspond to, given the geometry the SD-Cart BIOS will use.
  • BIOS: The geometry to use is now determined at runtime, based on the size the card reports.
Versions: sdpart.com v0.2, sdcart.sys v0.10, bios v0.10
File(s):
sdcjr02.zip (11.9 KB)
Version v01
November 17, 2020 (Tuesday)
  • Initial release
File(s):
sdcjr01.zip (9.8 KB)
This project is also available on GitHub!
To request features, report issues or contribute, you may send me an email or use the GitHub repository:
https://github.com/raphnet/sdcartJR



Where to get the hardware

Ready to use, tested high quality PCBs are available from my online store:
https://www.raphnet-tech.com/products/sdcartJR/

Component side

Component side

Solder side

Solder side



Please support me by ordering this from my store!

My online store (raphnet-tech) is the only official source for this product.

If you decide to buy one, please buy an original from my store to support me! ❤



Compatibility and performance

Here is a list of known working cards, with some performance information. Please send me information about the cards you use and I'll update this table.

SoftwareType, brand and size of the cardReadsWrites
sdcart.sys v0.10MMC, Lexar, 64MB44.4 kB/s35.7 kB/s
sdcart.sys v0.10SD, Panasonic, 8MB44.4 kB/s34.3 kB/s
sdcart.sysSD, Toshiba, 2GB
sdcart.sys v0.10SD, SanDisk, 2GB
sdcart.sys v0.2SDHC, SanDisk, 4GB
sdcart.sys v0.2(Micro) SDHC, SanDisk, 16GB
The software column is only there to document the performance test conditions. Cards will either work with both the boot ROM and the sdcart.sys driver, or not at all.

The performance tests were made using the iotest.com tool part of this project. This very simple tool writes and reads 100 kB of data to/from a file in the working directory and tracks the elapsed time using the system timer.


Limits

Boot ROM

Limited to 7.84 GiB

The current boot ROM only implements basic int13h functions, that is those which address disk sectors geometrically, using 3 numbers: Cylinder, Head and Sector. Also know as "CHS".

For a very long time already, those concepts of cylinders and heads no longer apply to the reality of hard disks, and never had anything to do with MMC/SD memory cards. Cards use LBA addressing where each sector is accessed using a single number (block number). The SD-Cart BIOS code therefore invents a CHS geometry to fit the card, according to the capacity it reports and performs the required translation.

The maximum counts for elements of CHS addressing are the following: 1024 cylinders, 255 heads and 63 sectors per track. Given 512-byte sectors, this gives a limit of 1024 * 255 * 63 * 512 = 8422686720 (7.84 GiB)

(Note: Technically, 256 heads would be possible, but it is not supported by DOS and therefore avoided)

The partition table stored into the MBR contains CHS and LBA values, and the latter being stored using 32 bits, devices up to 2TB could be supported. But unfortunately, DOS versions typically used on PCjr systems do not use those values, but even if they did, unless the int13h extensions (functions 41h and above) were used to use LBA addressing, the limit would still be 7.84 GiB.

sdcart.sys

DOS is the limit

Things are a bit simpler with sdcart.sys. First, instead of DOS, sdcart.sys directly scans the partition table and only looks at LBA values. DOS accesses the content of the partition with logical sector numbers, similar to LBA, but where 0 represents the first sector within the partition. Since the BIOS int13h services and CHS addressing are not at all used, the partition could begin anywhere, even beyond the 7.84 GiB limit.

For the moment, sdcart.sys does not check if the partition size and file system type (FAT12,16,32) is supported by the running DOS version. If necessary, check the partition type with sdpart.com before accessing the drive.

Partition size

This project does not limit the allowable partition size. In general, the maximum size will depend on the DOS version being used. Typical DOS version on PCjr do not support FAT32, and the maximum size supported by FAT16B (DOS 5) is of about 2 GiB. Under DOS 3.30, FAT16 is limited to a maximum of 65536 sectors and therefore the limit is of only 32 MiB.




Preparing a bootable DOS 5 card

If you have an SD-Cart JR with the lastest BIOS ROM in a socket, you can simply boot using a DOS floppy and then use fdisk and format /S on your card, as you would for a hard disk.

But what if you do not have a boot floppy? Then you can use DOSBox and a Linux computer to make a hard disk image which you then write to a card. (note: I'm sure other OSes could be used, but I only know how to do this on Linux)

This example uses DOS 5 since it is a complicated installation, but adapting the instructions below for earlier DOS versions should be easy. (Just use fdisk and format instead of the DOS installer and do not patch your boot sector).


1. Prepare a hard disk image

First, insert your card and power up your PCjr. Write down the CHS geometry SD-Cart BIOS says it will use. For this example, I used a 64MB MMC card and it gave me: CHS=980,4,32

Now in a working directory, create a file as large as the card. 980 * 4 * 32 = 125440, so using dd under Linux, one can do this:

dd if=/dev/zero of=card.img bs=512 count=125440

(notice the block size of 512). You should end up with a file holding a total of 125440 * 512 = 64225280 bytes.


2. Prepare DOS floppies and jrconfig

Add also your DOS floppy disk images and jrconfig to your working directory. Your directory should then contain something similar to this:

  • card.img
  • Disk01...05.img
  • JRCONFIG.NRD

3. Install and configure DOS

Start DOSBox in your working directory, like this. Do not configure the machine type to pcjr. Use the default.

dosbox -noautoexec -c "mount c ." -c "c:" -c "imgmount 2 card.img -size 512,32,4,980 -fs none" -c "boot Disk01.img Disk02.img Disk03.img Disk04.img Disk05.img"

Notice the -size argument given to imgmount. The first value is the sector size (512) and the numbers following it are the sectors-per-track, heads and cylinder counts (Compared to what the SD-Cart JR BIOS shows, the order is reversed...)

Also, in this example, DOS has 5 installation disks. Those are all passed, in order, to the boot command. To insert the next floppy during the installation, press CTRL+F4.

After installation, quit DOSBox.


4. Copy files to your DOS 5 hard drive

Start DOSBox using the following command. This will give you an environment where your D: drive is your working directory, and your DOS 5 hard drive will be C:

dosbox -noautoexec -c "mount d ." -c "d:" -c "imgmount c card.img -size 512,32,4,980"

Copy files, such as JRCONFIG.NRD, and any other tools or games you would like to have on your card.

Example: COPY JRCONFIG.NRD C:

One you are done copying files, quit DOSBox.


5. Boot into DOS 5 and configure it

Start DOSBox with this command:

dosbox -noautoexec -c "mount d ." -c "d:" -c "imgmount c card.img -size 512,32,4,980" -c "boot -l c"
This will boot you into DOS 5. Edit config.sys to:
  • Make sure the first line is stacks=0,0
  • Add jrconfig (eg: DEVICE=JRCONFIG.NRD -v32 -t3)
  • REM things you may not want, such as HIMEM.
You may also want to edit autoexec.bat, to remove DOSSHELL for instance.

Do not close DOSBox just yet.


5. Patch the boot sector

Still within your DOS 5 running in DOSBox, fire up DEBUG.COM and follow the instructions given in this thread. (In the case of this specific example, the drive number you will use is 2).

http://www.brutman.com/PCjr/docs/Patching_DOS_5_for_the_PCjr.pdf (Mike's PCjr Page)


6. Write the hard disk image to the card

Under Linux, insert your card, find out which block device is assigned to it (eg: sdh) and use dd to overwrite the card.

Example:
dd if=card.img of=/dev/sdX

It is important to write the image to the root of the device (for instance sdh) and not in a partition (such as sdh1, etc).

The above is the equivalent of using rawrite to recreate a floppy from an image, but the target is a MMC or SD card in a USB reader. I have no idea how to do this under non-Linux OSes. Please let me know how and I'll mention it here!


Boot troubleshooting

Suppose you pickup a random card, insert it in your SD-Cart JR with Boot ROM, boot DOS from a floppy, create a new active DOS partition using fdisk, run format /s and then try booting from the card and it does not boot.

It just hangs after showing the Booting from SD-Cart JR... message.

If using DOS 5 (or other newer versions), don't forget to patch the card boot sector! (Or use FORMATJR.COM)

Apparently fdisk and format /s tend to leave things as-is as much as possible when they touch the boot sector. In particular, it seems (I have not actually checked to confirm) that they leave the existing boot code as-is. Who knows what this pre-existing machine code could be on an old card that came pre-formatted (or that you formatted years ago using an old mp3 player) given that those cards are not normally used for booting an OS?

I have found (as have been confirmed by others too) that creating a fresh boot sector solves this issue. There are a few ways to do it:

  1. If running a version of DOS new enough (eg: DOS 5) run FDISK /MBR. Don't forget to (re)patch the card boot sector after that.
  2. Using sdpart.com, use the 'c' and 'w' commands in sdpart.com. This will create a blank partition table, so you will have use fdisk to create a new dos partition after running those commands.
  3. Use DEBUG to wipe the boot sector. (See last section of Patching DOS 5 and up for the PCjr)

If the above does not help, try contacting me or asking in the forum thread at: https://www.brutman.com/forums/viewtopic.php?f=1&t=1041




Enclosure

I designed a simple enclosure that can be built using a 3D printer.

It is in fact a modified version of my PCjr cartridge enclosure with additional openings for the card, the LED, as well as a few tweaks: Removed two mostly useless supports in the front which were conflicting with a capacitor, the area receiving the screws has been trimmed and the screws are placed a bit lower to avoid interference with the circuit board.




Here are the .STL files for the two pieces:
I ordered a print from a commercial service, made out of nylon using an SLS process. The result is very good and everything fitted without rework.




References




Disclaimer

I cannot be held responsible for any damages that could occur to you or your equipment while following the procedures present on this page. Also, I GIVE ABSOLUTELY NO WARRANTY on the correctness and usability of the informations on this page. Please note, however, that the procedures above have worked in my case without any damages or problems.

Now you cannot say that I did not warn you :)