• Please review our updated Terms and Rules here

Got CF cards to work on Tidalwave palmtop

dreNorteR

Experienced Member
Joined
Dec 19, 2016
Messages
119
So it turns out CompactFlash adapters (and probably other ATA-type cards) do work in type 1 PCMCIA slots. It's in the specs, but I'm probably not the only one who wasn't aware of this before seeing hjalfi's thread ;)

I decided to try it on another machine, namely this very common model of DOS palmtop. And luckily, each card has its own 16K address window which stays permanently enabled (C800 for slot A, CC00 for B).

I haven't yet disassembled the ROM to find out about I/O registers, but it's not necessary for the basic functionality. That means no change detection of course, so this driver behaves like a hard disk - you need to reboot to use a different card or after writing to it from another machine. On the plus side, it is small and might work on other platforms as well.

Load it from E:\CONFIG.SYS, with the address immediately after the filename
e.g. "DEVICE=A:\MM_ATA.SYS CC00" if you already have an SRAM card in A: with the driver on it
 

Attachments

  • MM_ATA.ZIP
    5.6 KB · Views: 23
Thank you for sharing your knowledge. It is 3 years later and yours is still one of the most recent posts on this rare machine.

I haven't tested it yet but will add it to my todo queue.


For posterity, I made a quick review video on the PS1000 for youtube

If I get your cf hack working; I will make a follow-up video as it will significantly improve the usability of the system.
 
So it turns out CompactFlash adapters (and probably other ATA-type cards) do work in type 1 PCMCIA slots. It's in the specs, but I'm probably not the only one who wasn't aware of this before seeing hjalfi's thread ;)

I decided to try it on another machine, namely this very common model of DOS palmtop. And luckily, each card has its own 16K address window which stays permanently enabled (C800 for slot A, CC00 for B).

I haven't yet disassembled the ROM to find out about I/O registers, but it's not necessary for the basic functionality. That means no change detection of course, so this driver behaves like a hard disk - you need to reboot to use a different card or after writing to it from another machine. On the plus side, it is small and might work on other platforms as well.

Load it from E:\CONFIG.SYS, with the address immediately after the filename
e.g. "DEVICE=A:\MM_ATA.SYS CC00" if you already have an SRAM card in A: with the driver on it
What cards and adapters did you use? I own two Highscreen Handy Organizers and would like to test this.
 
What cards and adapters did you use? I own two Highscreen Handy Organizers and would like to test this.

I used some no-name 512 MB card, should really work with any brand. The adapter is entirely passive; getting it into the slot may require a bit of force, but I didn't have to remove the cover to do it.

The driver isn't very polished unfortunately, and I didn't keep working on it.

- the card needs to be already formatted with a MBR and FAT (12 or 16 bit) partition
- use "C800" as parameter if the card is in slot A, or "CC00" for B
- it is only detected once, when the driver is being loaded
- you need to use the new drive letter to access it, not A: or B:

There may be some problem where the card becomes inaccessible, don't know if it's a bug or the palmtop changing the memory mapping / switching to attribute space. Had it happen once so far and it worked again after rebooting IIRC.

I didn't get anywhere with disassembling the ROM (the code seems very convoluted). When the palmtop is turned off, the card is no longer powered and loses its register contents, maybe that has something to do with it. Might also be the only way to detect disk change. There is a hardware register that seems to show if a card is currently inserted, but no change flag. Or maybe there is and it's cleared by some code in ROM?
 
Last edited:
No new driver yet, but an update. There's no real documentation online about how the hardware works, but I wrote some code to trace through INT 13h and log what I/O it does when reading a sector:

Port B0h:
always written with 01h before accessing card; doesn't seem necessary, maybe resets poweroff timer?

Port EEh index (r/w), EFh data:
index 8/9 is status for card 'A'/'B' (read only)
reads as 1Fh if no card, 1Eh if card inserted?

The ports for memory mapping are entirely different. Somewhat like EMS on the NEAT chipset, except each 16K window has a different address space.

0208h (r/w) for C000 (ROM/RAM disk, didn't check which)
4208h (r/w) for C400 (RAM/ROM)
8208h (r/w) for C800 (card A)
C208h (r/w) for CC00 (card B)

Bit 7 must be set to enable, bit 6..0 select a 16K page.
There seems to be no way to access attribute space, or more than 2MB of memory.

Other observations:

The built-in "Microsoft driver for Databook drives" does an 8 bit sum of the first 512 bytes on the card and expects it to be zero for some reason. Didn't look further into that, I assume it at some point modifies a byte there to make the checksum valid. Might cause problems with write-protected cards? It also sets a byte in the BIOS data area and then goes into a delay loop. So there might be an interrupt involved?

NMI is invoked on power down (but not power up).

--------

I think it would be possible to hook into the built-in device driver and detect if it is a CF or SRAM card. The standard says that address bits 9..4 are "don't care", so we can check if the same read/write registers appear on all of these addresses.

Can't access any regs if "busy" bit is set, but it shouldn't be for long normally?

0. Test card status reg - might not always be reliable?

1. Map first 16K in

2. Read ATA status reg (0007), compare with 0017, 0027 ... 03F7
a) if bit 7 was set and becomes cleared, restart
b) if not all the same, or bit 7 remains set -> not a CF card

3. Compare 02-05 with 12-15h, see if both change on write

4. If we got power-down interrupt before, do identify command and compare with previous info to detect disk change

Seems a bit hacky, but it should work...
 
Okay, here's a small update to my terrible hack of a driver. No new features but it should be more stable!

It's no longer completely generic: if the memory window is C800 or CC00, it will now use the "EMS" ports
to switch the card into memory, and back out when finished with it. That should make sure we can access
it, and protect against most other code doing so by accident.

It also now resets the drive if it seems stuck, which likely happens because the ROM writes something to
the IDE command register on "waking up". Hopefully that will never be a "write" command
followed by 512 bytes to the data register...


There's a small "installation script" that is intended to run from A:, with the flash "hard drive" in the other slot.

The palmtop needs CONFIG.SYS to be on the RAM disk, but can run AUTOEXEC.BAT from A:. The idea is to have that "boot disk" always plugged in, so it can automatically make a new config file when it gets lost.

----------

Perhaps there's some way to enable attribute memory, and the built-in software doesn't use it?

Some bits in (write-only, of course!) registers seem to switch off parts of address space, including
the memory windows at C000-CFFF. So the chip was probably designed to support other hardware than
just this model of palmtop?
 

Attachments

  • twcfhack.zip
    2.6 KB · Views: 9
Currently getting distracted by trying to reverse engineer more of the hardware :)

There are definitely registers that the ROM never uses and doesn't expect to change from their power-on defaults. I found what at first looked like a config bit to make the BIOS boot from "floppy" like on a normal PC!

Turns out it really controls the memory mapping for segment D800 (which normally contains the ROM-DOS boot loader).

The ROM disk driver uses C000-C3FF (port 0208h) to access the first 1 MB of drive D:, and B000-B7FF (port EEh index 3Ch) for the rest of D: and C:. This alternate address window is never expected to be enabled, and D000-FFFF is normally the top of the second 1 MB ROM.

Code:
	;enable page register for D800-DFFF
	mov	ax,012bh	;index=2B, data=01
	out	0eeh,ax

	;not actually necessary, but cleaner than leaving it pointing at
	;garbage inside the ROM disk:
	mov	ax,1c2ah	;map to ROM addr E0000 (will return to BIOS)
	out	0eeh,ax

	;reboot
	jmp	0ffffh:0000h

MS-DOS 5.0 will hang when booting from A:, but FreeDOS works. Not very useful except to prove it can be done: you have about 100K less RAM available and it is S L O W !

There's also a real time clock, but it's different from the AT:

Code:
00E0 (r/o) alarm interrupt flag (bit 7), read by NMI?
00E3-00ED real time clock (r/o)
    use port EEh/EFh with index 21-29h to set these
    00E3 time of day, low byte
    00E4 time of day, high byte
        counts seconds from 0 to 43199 (12 hours)
    00E5 AM/PM (bit 0) and day counter, low
    00E6 day counter, high
         day count is (year-1980)*366 + day_in_year
         leap days handled by software?
    00E7 alarm time, low
    00E8 alarm time, high
    00E9 alarm am/pm and day, low
    00EA alarm day, high
    00EB status/control
         bit 4 update in progress? (INT 1A loops until clear)
             2 alarm ??? (cleared by INT 1A fn7, set where?)
             1 alarm enabled
             0 clock running (should clear before setting time)

Has anyone seen another system that looks similar to this?
 
For a chip that is supposedly custom and only used in cheap palmtops, the TM8886 seems to have a lot of options for memory configuration.

It actually supports up to 8 MB of EMS memory. Any window can be freely set to ROM, RAM or one of
the two cards, and the base address / page registers can be moved like on the NEAT chipset.

Code:
00E1 (r/w)  address space select
            bit 7-6 window 3 (default 11=card B)
                5-4 window 2 (default 10=card A)
                3-2 window 1 (default 01=RAM)
                1-0 window 0 (default 00=ROM)

00EE  index
00EF  data
      02 (r/w) EMS address extension
         bit 7-6 2MB page for window 3 
             5-4 2MB page for window 2
             3-2 2MB page for window 1
             1-0 2MB page for window 0
      0D (w/o) EMS base register
         bit 7-4 base segment (0=C000, 1=C400, ...)
             3-0 I/O port (0=208, 1=218, ...)
                 can always read at 208 but r/w only at selected

I also managed to switch to attribute space, but still have no clear idea how to do it reliably!

It doesn't work like just setting or clearing a bit, it is almost like it only expects
certain bytes, and can seemingly get stuck in one state when the wrong ones are sent.

After a cold start, the following seems to work reliably:

Code:
	mov	ax,081Bh
	out	0EEh,ax

;card0 now accesses attribute space
;(after some delay, how long exactly?)

	mov	ax,3B1Bh
	out	0EEh,ax

;card0 now back to common
;(also delay here)

I got the second card to switch using index 1Ch, but it can somehow affect both
cards or get stuck? Need to do more investigation...

Inserting or removing a card generates IRQ 5 or 6 depending on the slot.
No way to detect it when power is off however.
 
Figuring out stuff:

So, the problem I had was that the changes to that register are only applied once the index register EEh is set to some other value than 1Ch/1Dh. I didn't do that, but after waiting long enough some interrupt handler did, making it seem like there is a long delay involved.

writing 3Bh to reg 1Bh/1Ch sets card to attribute memory
writing 3Dh to switches back to common

I got the 3Dh from looking at the early startup code in ROM (but it only sets reg 1Bh for some reason), and 3Bh by experimenting. Maybe there are other control bits in there? What I would really want is one that enables an interrupt on change in the PCMCIA "ready" signal, which is the inverse of "busy" in the ATA status register.

NEW DRIVER

It's now a COM file and takes over drive A: / B: completely (there are already too many drive letters on this thing!).

Supports both SRAM and ATA cards, with auto-detection.

No formatting yet; the DOS "generic IOCTL" mechanism seems really overcomplicated and not suited to anything but floppy disks. There will probably be an external FORMAT/FDISK utility soon. For now, just format your card on any modern PC - as long as it's FAT16 it should work.
 

Attachments

  • tidalcf1.zip
    14.6 KB · Views: 10
Hi dreNorteR!
This all sounds very interesting, but I only understand half of what you are doing and don't know how to help. :(
Regards
 
Update

Formatting now works!

I fixed a rather stupid bug in the load_bpb routine: it would load as many bytes as the start of the boot code jumps over, likely overflowing the space available in its data structure.

Also added support for the "get/set volume label" IOCTL, which required adding a 512 byte buffer. The driver now takes about 3K of RAM, my plan for the next version is to simply overwrite the original disk driver (which is much, MUCH larger and all of it is in RAM).

The reason for adding volume label support was that there is actually a special volume label recognized by the palmtop's boot loader. If it finds a card in drive A: with the label "$$#%@LITEON", it will run whatever code is in its boot sector instead of loading ROM-DOS! You can also hold Alt+Shift to get a menu, which won't allow booting other cards but can bypass the startup files.

(My formatter doesn't write any boot code - not even something to print an error message - right now, so don't set that label if you don't know what you're doing.)

The old version was already stable enough for me to install and run Windows 3.0, if I haven't introduced some major bug this one should be good too.

One thing to keep in mind is that this driver appears to drain the batteries like crazy, and I'm now forced to find out just how bad it is. I've mostly tested it with external power before, but either the adapter or my palmtop seems to have gone bad somehow and will now only run properly from batteries. When plugged in now, the LCD contrast noticeably changes from just pressing keys, and the card drives don't seem to work at all even with SRAM.

Making the driver consume less power would only be possible if there's a way to enable interrupts from the card, and I've not yet found a way to do that...
 

Attachments

  • tidalcf2.zip
    24.5 KB · Views: 23
Last edited:
The IORD/IOWR pins on the card slots are connected to the Tidalwave chip. So it should be possible to not only enable interrupts, but also use other types of cards (like Ethernet)!

Figuring out how to do this by poking random ports could be difficult, but I'm slowly getting a better picture of how it all fits together. It turns out my original method for switching to attribute space worked mostly by accident:

* Port EEh regs 1B/1Ch are used to move the actual card control ports, in steps of 4.

* The hardware default for the second card seems to be 3Dh, which results in the port being at 4*3Dh = F4h (with aliases at F5-F7h). I guess the first card should normally be at 4*3Ch = F0h, but for some reason the BIOS moves it so that both cards respond to writes at port F4h.

So what actually happened is that by writing 3Bh, I moved the control port to EC-EFh, which overlaps the index/data registers. Anything written to the index register afterwards will then also affect the control port :)
 
Sorry for reviving such an old thread, but I'd like to thank dreNorteR for this wonderful driver. I got it installed on my Tidalwave and its great. However, I've been wondering if theres any update regarding the power draw: when I have a CF card plugged in, the card draws around 65mA even with the Tidalwave turned off, so my fresh batteries get drained in less than 24h of no use.

Is there a way to fix this, or at least to get the CF card to draw no power when the Tidalwave is off?
 
Oh wow, someone else is using my driver. Did not check the forum for some time :)

No luck with finding a way to make it more power efficient. But I did not expect the card to be drawing power when the palmtop is "off", especially since it loses its register contents (my first idea for change detection involved writing some signature there). PCMCIA 1.0 did not have a reset signal, so that should only happen when the card is powered off.

Did you actually measure the 65mA between the card and connector?

Tidalwave power management is generally kind of bad, and it doesn't help that there is 1 MB of DRAM that has to be constantly refreshed.
 
I did not expect the card to be drawing power when the palmtop is "off"

Tested it myself now and it's definitely a problem - less than 24 hours of standby time, and it's clearly the CF card that's causing it.

I tried setting some bits in what I believed to be a power management register and it didn't help, it seems to disable the PCMCIA interface but the card is still drawing power. No idea what to do about this, other than always removing the card when you're not using it.
 
Back
Top