raphnet.net banner

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

twitter@raphnetlabs
Buy Me a Coffee at ko-fi.com
Contents

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.

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.

goto top


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.


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


goto top


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:


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.

goto top


Downloads

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)
Show previous releases...
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

goto top


Where to get the hardware

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

Component side

Component side

Solder side

Solder side


goto top


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.

goto top


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.


goto top


Preparing a 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:


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: 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).

Patching IBM DOS 5 for the PCjr (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

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!

goto top


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.



Warning: I have not yet printed and tested this design!

Here are the .STL files for the two pieces:

goto top


References


goto top


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 :)

goto top


Any trademarks used on this site are the property of their respective owners.
Copyright © 2002-2020, Raphaël Assenat
Website coded withWebsite coded with vimLast update: December 28, 2020 (Monday)