Please enable JavaScript to display the menu.
Another FM TOWNS Internal CDROM Reverse Engineering Project

[Link to the YSSCSICD.SYS details]


Alone In The Dark for FM TOWNS could start from external SCSI CD-ROM using YSSCSICD.SYS, but it didn't play CDDA BGM.  Now patch is available to enable CDDA BGM from external CD-ROM drive.

Dai Koukai Jidai 2 initially didn't start, but it was because the data disk (called data disk, but it has executable programs) was bad.  I was able to start it from Towns OS V2.1 L31 GUI by double-clicking AUTOEXEC.BAT.


Newly confirmed titles:

Confirmed not to work:



Chase HQ Patch Available!

TAITO Chase HQ can now run from an external SCSI CD-ROM.  It was pretty difficult.  The code was encrypted to begin with, but for this problem I could use the same technique that I used for Rainbow Island.

But, when I simply replaced I/O access with CD-ROM BIOS call (and YSSCSICD.SYS expanded function), it just froze.  The RS232C command dump showed me an interesting output.  It entered my function, but never exited.  Apparently it was stuck inside my driver.  Turned out Chase HQ disabled SCSI IRQ, and therefore my SCSI BIOS call never returned.

I also knew that Chase HQ reads CD-ROM files.  So, the IRQs must be enabled while reading files.  I looked for INT 21H for finding a file-reading function.  From there I found a function in Chase HQ code that temporarily enable IRQ and then disable again.  I modified my patch so that it calls IRQ-enabling function, then issues CD-ROM BIOS calls, and then calls the IRQ-disabling function.  Then it appeared to be working find, until the remaining time reaches 16.999999 seconds.

It turned out while the integer part of the remaining time is 16 the program continuously sending a request to play a warning "Hurry Up" message to the CD-ROM drive.  Since FM TOWNS Chase HQ was controlling the frame rate to 60 frames per seconds, I had to wait 60 times of CDDAPlay requests.  Original Chase HQ program got away by just sending I/O requests without checking Drive-Ready signal nor command success or failure.  If I do it with BIOS, it pretty much takes more than 1 minute, and probably not good for CD-ROM servo motor.

But, the fix was easy.  I first inserted a trap code so that it sends the return address (DWORD PTR [ESP] at the beginning of CD-ROM command function, and found where it was sending the CDDAPlay command continuously.  Then I modified one jump instruction so that it only plays the warning message only once when the integer part of the remaining time gets 16.

I am not that a good driver to test it all the way, but I played two rounds, and worked fine.  I suppose it works ok for the rest.

By the way, if someone is trying to preserve a FM TOWNS in working condition, I assumed such a person would have no difficulty in compiling and run a C program, but is it nicer if I also upload a compiled executable?  (In .EXP format)


Rainbow Island CDDA BGM Patch

Thanks nabe-abk ( for the file format of .EXP!  Rainbow Island executable was encrypted, and it was difficult to create a patch.  But, I was able to append a code to apply patches after the code is decrypted thanks to the EXP file format.

I thought the same method should work for Chase HQ, but this one crashed inside YSSCSICD.SYS.  Simply sending CD Stop (AH=52H) crashes the driver, so I am suspecting it is something to do with the IRQ handler that Chase HQ may be setting up in it.  (Wing Commander's CDDA didn't play due to the similar problem until I figured what was happening.)

I already took full disassembly of Chase HQ executable.  I'll look into if it is setting up its own IRQ handler in it next.


YSSCSICD.SYS Bug Fix of ReadTOC (AH=54H) enabled Operation Wolf!  Afterburner 3 patch is available!

YSSCSICD.SYS was returning 2-second shorter overall duration in ReadTOC (AH=54H).  This issue was preventing Operation Wolf from starting.  Well, while I was reading CDSD.SYS source, I thought it was returning 2 second shorter than the duration returned from the SCSI device, so I just was following it.  I might have been reading the source wrong, or CDSD.SYS was wrong, or CDSD.SYS was for MSCDEX.EXE not for replacing FM TOWNS CD-ROM BIOS after all.  Operation Wolf now starts from a SCSI CD-ROM drive with the newest YSSCSICD.SYS.  No patch necessary.

Just to make sure some other titles happened to be working and stop functioning with the update, I have tested 5 or 6 game titles with the newest YSSCSICD.SYS and all worked fine.

The newest version is from the following.

Also a patch for running Afterburner 3 from a SCSI CD-ROM drive is ready.  The program was directly beating CD-ROM I/O ports.  The patch forces it to use CD-ROM BIOS.  Also I patched the program so that it does not use 15KHz display mode.  Other CRI games for FM TOWNS used 31KHz display mode if you start the program with the game-pad A button held down.  I wonder why Afterburner 3 is different.  Actually the source code revealed that if BYTE PTR DS:[00020DF4H]==1, the program uses 31KHz display mode.  However, nowhere in the disassembly was writing 1 to that location.  My patch forces this byte to be 1.  But, the movie corrupts a little bit.  Afterburner 3 is using a display mode that is not officially supported by FM TOWNS graphics BIOS.  Maybe CRI could not prevent movie playback corrupt and gave up 31KHz display mode.

You will see some garbage on the right edge of the screen while playing, but shouldn't be an issue for playing.


Can start Augusta (3D Golf Simulation) with YSSCSICD.SYS!

This was a little bit tricky.  I failed a few days ago, but I was forgetting about the copy protection (I though I was using the one that the protection was broken.)  If you are able to read disassembly of SETUP.EXP, unprotecting it is not too difficult.

So, put Augusta CD-ROM in the SCSI drive, Program/User disk in the A drive, Towns OS V1.1 boot disk in the B drive, and boot from the B drive (REIPL B:).  If you want to run it on 486DX or faster FM TOWNS FAST mode, copy TBIOS.BIN and TBIOS.SYS from Towns OS V2.1 to the Towns OS V1.1 boot floppy disk.


Can start Raiden with YSSCSICD.SYS!

The executable needs to be patched, but it does run.  It only starts from Towns OS V1.1 boot disk though.

If the internal CD-ROM is healthy, it can start from V2.1 L20 (with all drivers ripped), but I cannot tell why the patched version can only start from Towns OS V1.1 boot disk


Unreal Mode Works!

YSSCSICD.SYS now supports CD-ROM BIOS function INT 93H, AH=05H/15H, CH=0FFH.  This function reads CD-ROM sectors into anywhere in the low-4GB physical memory location.  The original FM TOWNS CD-ROM BIOS does it with DMA.  But, a real-mode driver cannot emulate this function.  So, I use Unreal Mode ( to transfer sector data to high memory.  With this update, RAYXANBER boots with no problem from a V1.1 L30 boot floppy disk.

I have also written a patch for starting Galaxy Force 2.  Galaxy Force 2 was directly accessing I/O.  This patch forces it to use BIOS.  Also it makes Galaxy Force 2 run with DOS-Extender that comes with Towns OS V2.1.  The difference of V1.1 and V2.1 DOS-Extender is (apparently) V1.1 DOS-Extender does not aware of any usage of UMB (640KB to 1MB area).  V2.1 DOS-Extender does avoid UMB memory blocks used by the system.  Also PUYOPUYO could start, but with no CDDA BGM.  I have also written a patch for playing CDDA.  Patches are in the GitHub.


Experimenting Unreal Mode

At least Rayxanber is confirmed to be using AH=50H, CH=FFH.  It is for direct reading into 32-bit address space.  The original CD-ROM BIOS is most likely using DMA to implement this function.  It is impossible to emulate this functionality with a real-mode driver.  So, I am now looking into Unreal Mode (  Based on the example on this wiki, I wrote an experiment code that runs on FM TOWNS.

As an independent EXE, I succeeded in transferring data to high-memory.  I was surprised that it is so easy to enter the Protected Mode.  I was thinking I needed a bigger ritual to safely enter and exit the Protected Mode.

But, I need to do it in INT 93H handler called from the DOS Extender without breaking it.  Is it possible?  I am looking into the possibility right now.


Solved Wing Commander CDDA Problem!

I've written details in here Revision section.


Wing Commander CDDA Problem.

Wing Commander stubbornly does not play CDDA.  At one time, it started playing, and thought I fixed the problem, and turned out I was using CDSD.SYS + CDISC2.SYS.  I'm going back and forth for testing purposes.

I took a command dump using RS232C.  When I start Wing Commander from Towns OS V2.1 L20, Start_Play command (AH=050H) is coming in, but both start time and end time were 00:00:00.  If I start from V2.1 L31, Start_Play comman doesn't even come in during the opening demo.  Instead, if I go into the Tigers' Claw Bar and press M key, the command is sent, but the times were both 00:00:00.

I can imagine two possibilities:

(1) AH=54H (Read_TOC) is not able to pass information to the protected mode.

(2) Track number for CDDA is not right.

If I am able to see memory and register dumps, I will have a better idea.  Agh!!!  I need FM TOWNS version of 386DEBUG.EXE!!!!  Why did I throw away when I left Japan!!!!  Curse me!!!!

I at least confirmed that the TOC is read to DS:DI during Read_TOC BIOS command (54H).  But, what I cannot tell is if the information was passed to the protected mode by DOS Extender.

So, I am writing a device driver that sends register dump via RS232C.  Wing Commander code looks to be written in C, and it is not too tight.  I have a space to insert INT 77H different places.

Also, I am writing a program to write a memory dump to a specified file by INT 68H.  I can only take low 1MB, but hopefully that will give a better idea of what's going on.


At least I am able to take disassembly with objdump command, but it is not very easy to read because it is in GAS expression.  I want a better disassembler....

I have also succeeded in TownsOS V1.1 L30 Boot Floppy Disk.  CONTROL.EXE of TownsOS V1.1 was  not using I/O 3C32H.  Instead, it was looking at DOS Default Drive for the path to look for RUN386.EXE and TMENU.EXP.  Below is the disassembly of that part.

     26c:	b4 19                	mov    $0x19,%ah        Get Current Default Drive
     26e:	cd 21                	int    $0x21
     270:	a2 cb 00             	mov    %al,0xcb         Remember default drive in 0xCb, DS base is offset 0x0A50 -> 0x0A50+0xC4=0xB1B
     273:	a2 c4 00             	mov    %al,0xc4         Remember default drive in 0xC4, DS base is offset 0x0A50 -> 0x0A50+0xC4=0xB14 
     276:	04 41                	add    $0x41,%al        AL=AL+'A'
     278:	a2 31 00             	mov    %al,0x31         DS base is offset 0x0A50  0x0A50+0x31=0x0A81.  Drive letter for TMENU.EXP
     27b:	a2 16 00             	mov    %al,0x16         DS base is offset 0x0A50  0x0A50+0x16=0x0A66.  Drive letter for RUN386.EXE
     27e:	a2 3e 00             	mov    %al,0x3e         DS base is offset 0x0A50  0x0A50+0x3E=0x0A8E.  Drive letter for T_OAK2.EXE
     281:	3c 51                	cmp    $0x51,%al        'Q' drive?
     283:	75 0a                	jne    0x28f            Jump if not Q drive.
     285:	c6 06 c4 00 11       	movb   $0x11,0xc4       0x0A50+0xC4=0xB14  (0x11 is 'Q'-'A')
     28a:	c6 06 16 00 52       	movb   $0x52,0x16       Use R drive for RUN386.EXE

So, instead of writing to I/O 3C32H, I needed to use DOS INT 21H AH=0EH to change the default drive.  But, if I do it in YSSCSICD.SYS, what's going to happen to AUTOEXEC.BAT?  After reading through CONFIG.SYS, DOS may look for AUTOEXEC.BAT in the then-default drive which is Q.  But, Q drive is not ready until MSCDEX.EXE is registered in AUTOEXEC.BAT.

So, instead of doing it in YSSCSICD.SYS, I added INT 21H AH=0EH call in SYSDRV.EXE.  By using SYSDRV.EXE at the beginning of AUTOEXEC.BAT, I successfully booted from the boot floppy disk into the Towns System Software V1.1 L30 in the SCSI CD-ROM drive.

Probably most of the V1.1-based software would work with this boot disk including Wing Commander.

By the way, if you start Towns OS V1.1 in 486DX models, the CPU is too fast and mouse cursor will jump around unless you choose "Slow" mode.


Separated pages:

BIOS Redirector YSSCSICD.SYS and System Drive Changer SYSDRV.EXE

FM TOWNS Unpublished BIOS Functions and I/O Ports

As of yesterday I was able to boot from a floppy disk and then start Towns System Software V2.1 L20 in an external SCSI CD-ROM drive.  But, the system software was not fully functional.

For example, if I went down to Command Mode, and then tried to go back to Towns MENU, I saw an error saying Towns OS Disc was not in the drive.  Also, if I register MSCDEX.EXE at the beginning of AUTOEXEC.BAT and use files in the CD for the rest of initialization, I saw a message saying insufficient memory for TownsOS.  Towns MENU somehow started, but I saw a warning message saying voice message was unavailable.  V2.1 L31 was not that fortunate.  After seeing insufficient memory error message, it just rebooted.  Only way to start Towns MENU without that error message was postpone MSCDEX.EXE.  If I placed MSCDEX.EXE immediately before CONTROL.EXE, I was able to start partially functional Towns System Software.

I knew why.  FM TOWNS remembers the boot drive somewhere.  Very often Towns OS look for files in the boot drive.  If I am able to find where the boot-drive information is stored and re-point to the CD-ROM drive (Q drive), this problem should be gone.

The problem was, nobody knew where that information was stored.  In fact, I searched hard when I was using FM TOWNS as my primary PC but could not find it.  But, this time I was better equipped.  I didn't have a good 8086 disassembler then, but now I can take binary to Linux and use objdump command to take disassembly.  Also, I cannot run PharLap 386DEBUG on FM TOWNS, but at least I can start debugging in DOSBOX to find the entry address.

If I do nothing, CONTROL.EXE will start TMENU.EXP located in the root directory of the boot drive.  Therefore, somewhere in CONTROL.EXE must be reading this information.  I took disassembly of CONTROL.EXE with objdump.

As I was reading from the entry address, what caught my attention was offset 0B00H.  It reads DS:[1016H] into AL, then far call to 12AB:0000, and then store returned AL back to DS:[1016H].  Immediately after that, 41H (character code of 'A') is added to AL, which is then stored to various locations preceding file names.  If DS:[1016H] is the boot drive, it explains.

Then, where is this value coming from?  At offset 0AFAH, IN AL,DX.  The boot drive was hidden in an I/O port.  The line above was telling it was I/O port 3C32H.

      aee:	07                   	pop    %es
     aef:	1f                   	pop    %ds
     af0:	fc                   	cld    
     af1:	6a 01                	push   $0x1
     af3:	e8 ac 0e             	call   0x19a2   (17A2 in debugger)
     af6:	5a                   	pop    %dx
     af7:	ba 32 3c             	mov    $0x3c32,%dx          			I/O Unpublished
     afa:	ec                   	in     (%dx),%al
     afb:	c0 e8 02             	shr    $0x2,%al
     afe:	24 1f                	and    $0x1f,%al
     b00:	a2 16 10             	mov    %al,0x1016           			DS:[0x1016] Base Drive, Probably.
     b03:	9a 00 00 80 01       	lcall  $0x180,$0x0          12AB:0000 runtime
     b08:	a0 16 10             	mov    0x1016,%al           
     b0b:	a2 0f 10             	mov    %al,0x100f
     b0e:	04 41                	add    $0x41,%al            AL=AL+'A'  ! Drive Letter!
     b10:	a2 fe 0d             	mov    %al,0xdfe            Drive Letter for "TMENU.EXP"  (File offset 0xFFE)
     b13:	a2 95 0e             	mov    %al,0xe95            Drive Letter for "\HCOPY\DELDRV.EXP" (File offset 0x1095)
     b16:	a2 b4 0e             	mov    %al,0xeb4
     b19:	a2 c8 0e             	mov    %al,0xec8
     b1c:	a2 e0 0e             	mov    %al,0xee0
     b1f:	a2 fa 0e             	mov    %al,0xefa
     b22:	a2 0e 0f             	mov    %al,0xf0e
     b25:	a2 17 0d             	mov    %al,0xd17            Drive Letter for "RUN386.EXE"
     b28:	a2 27 0d             	mov    %al,0xd27            Drive Letter for "RUN386.EXE"
     b2b:	a2 b7 0d             	mov    %al,0xdb7
     b2e:	a2 ce 0d             	mov    %al,0xdce
     b31:	a2 e4 0d             	mov    %al,0xde4

Then located 12AB:0000 using 386DEBUG.  It was offset 1A00H.  Among them I found a function that was recognizing command parameters.

    1A00:   e8 0d 00                CALL   0x1A10   Console Clear Screen
    1A03:   e8 0f 00                CALL   0x1A15
    1A06:   e8 1e 00                CALL   0x1A27
    1A09:   e8 1f 01                CALL   0x1B2B   Command Parameters
    1A0C:   e8 e5 00                CALL   0x1AF4   Calling CD-ROM BIOS Set Idle Auto-Stop Time
    1a0f:	cb                   	lret   

Turned out, by /D option, I could overwrite I/O 3C32H.

'D' option
    1ba0:	e8 4b 00             	call   0x1bee
    1ba3:	74 46                	je     0x1beb
    1ba5:	3c 41                	cmp    $0x41,%al
    1ba7:	7c 92                	jl     0x1b3b		If AL<'A' ignore.
    1ba9:	3c 5a                	cmp    $0x5a,%al
    1bab:	7f 8e                	jg     0x1b3b		IF AL>'Z' ignore.
    1bad:	2c 41                	sub    $0x41,%al
    1baf:	26 a2 16 10          	mov    %al,%es:0x1016
    1bb3:	26 a2 0f 10                mov    %al,%es:0x100f
    1bb7:	ba 32 3c                   	mov    $0x3c32,%dx
    1bba:	8a e0                	      mov    %al,%ah
    1bbc:	c0 e4 02             	shl    $0x2,%ah
    1bbf:	ec                   	in     (%dx),%al       Read from I/O 0x3c32
    1bc0:	80 e4 7c             	and    $0x7c,%ah       Leave Bit2 to Bit6
    1bc3:	24 83                	and    $0x83,%al       Leave Bit7, Bit1, and Bit0
    1bc5:	0a c4                	or     %ah,%al
    1bc7:	ee                   	out    %al,(%dx)       Write to I/O [0x3c32]
    1bc8:	e9 70 ff             	jmp    0x1b3b

So I adde /D:Q option to CONTROL.EXE, and I was able to boot from a floppy disk, and then start Towns System Software in the SCSI CD-ROM drive.  That was yesterday.

However, if I wrote MSCDEX.EXE at the beginning of AUTOEXEC.BAT and then used files in the CD-ROM drive to continue initialization, I saw a message telling insufficient memory for TownsOS.  This message was coming from SYSINIT.EXE.  First I took this message as is, and thought if I put MSCDEX.EXE before SYSINIT.EXE, probably MSCDEX.EXE took a memory location that blocks initialization of SYSINIT.EXE. 

Actually it had nothing to do with the memory.  I took disassembly of SYSINIT.EXE.  I couldn't find a place where it was failing to allocate memory.  Actually I couldn't find it because I was not familiar with high-memory access from real mode.  The code seemed to be using what's called Unreal Mode.  I was not familiar with it.

I changed the strategy to carpet bombing.  I searched everywhere firing INT 21H.  Actually I found a function that seemed to be showing debug messages.

     a12:	52                   	push   %dx
     a13:	50                   	push   %ax
     a14:	8a e2                	mov    %dl,%ah
     a16:	ba 34 3a             	mov    $0x3a34,%dx   IO[3A34]?
     a19:	ec                   	in     (%dx),%al
     a1a:	3c 52                	cmp    $0x52,%al    'R'
     a1c:	75 0e                	jne    0xa2c
     a1e:	83 c2 02             	add    $0x2,%dx      IO[3A36]?
     a21:	ec                   	in     (%dx),%al
     a22:	3c 41                	cmp    $0x41,%al    'A'
     a24:	75 06                	jne    0xa2c
     a26:	8a d4                	mov    %ah,%dl
     a28:	b4 02                	mov    $0x2,%ah      Display Output
     a2a:	cd 21                	int    $0x21
     a2c:	58                   	pop    %ax
     a2d:	5a                   	pop    %dx
     a2e:	c3                   	ret    

     a2f:	56                   	push   %si
     a30:	8b f2                	mov    %dx,%si
     a32:	b4 02                	mov    $0x2,%ah
     a34:	ac                   	lods   %ds:(%si),%al
     a35:	84 c0                	test   %al,%al
     a37:	74 07                	je     0xa40
     a39:	8a d0                	mov    %al,%dl
     a3b:	e8 d4 ff             	call   0xa12
     a3e:	eb f4                	jmp    0xa34
     a40:	5e                   	pop    %si
     a41:	c3                   	ret    

But SYSINIT.EXE was not showing anything useful.  Apparently SYSINIT.EXE shows those information only if I/O [3A34H] and [3A36H] are 'R' and 'A' respectively.  I wanted to see the debug messages.  I altered SYSINIT.EXE.  I wrote zero to offset 0A1DH and 0A25H so that the jump instruction didn't really jump.

It worked, and SYSINIT.EXE spit out all useful information.

Then, it told that even though I changed the current working drive to Q (CD-ROM drive), SYSINIT.EXE was looking for files in the A (floppy) drive.

SYSINIT.EXE is called before CONTROL.EXE.  Therefore, it was too late to change the boot drive information in CONTROL.EXE.  By the way, it turned out [3A34H] and [3A36H] are for both read and write.  I made a utility SYSINIW.EXE that enables debugging output from SYSINIT.EXE.  If you run this program at the beginning of AUTOEXEC.BAT, SYSINIT.EXE will show debug information.

So, to solve this problem, I needed to modify the boot-drive information before SYSINIT.EXE by writing to I/O 3C32H.  For that purpose, I made SYSDRV.EXE.  Both available from GitHub.

I have added SYSDRV.EXE at the beginning of AUTOEXEC.BAT, enabled Q drive with MSCDEX.EXE before all other initializations, and used files in the CD drive for the subsequent initialization.  It worked perfectly.

I am now able to boot from floppy disk into fully-functional Towns System Software V2.1 L20 in SCSI CD-ROM drive.  Details of making a boot disk is in here.



FM TOWNS Internal CD-ROM to SCSI CD-ROM Redirector Driver Ver. 0.5

I need to write a lot of findings.  But, I went ahead and released my FM TOWNS Internal CD-ROM to SCSI CD-ROM Redirector driver.

I've just uploaded binary YSCDSD.SYS in there, too.  I've never imagined I could come all the way here in 20 days.

A very simple explanation is this driver is for saving Fujitsu FM TOWNS with a dead internal CD-ROM drive.  FM TOWNS was the world first computer that had CD-ROM drive as a standard equipment.  Therefore, all FM TOWNS has an internal CD-ROM drive.  However, because it was done very early, the CD-ROM is neither SCSI nor IDE.  The specification is not open.  Once broken, there was little hope of repair.  Already there had been drivers called CDSD.SYS and CDISC2.SYS.  But, I cannot make a boot floppy image or a boot hd image public because the licensing term of CDSD.SYS tells I can redistribute the source code, but not binary.  I wanted to get a permission from the developer, but I cannot find a contact information.  And, the emulation was far from perfect anyway.  If you know how to use CDSD.SYS and CDISC2.SYS, you may have lines in CONFIG.SYS like:


You can simply replace these two lines with:


The driver automatically searches for a SCSI CD-ROM drive.  Therefore you don't have to specify SCSI ID.  Once loaded and found a SCSI CD-ROM drive, it will redirect internal CD-ROM BIOS call to SCSI BIOS call.  By making a boot floppy or boot partition in the hard drive, you can start a CD-ROM based game titles.  I think it emulates CD-ROM BIOS better than CDSD.SYS and CDISC2.SYS.  At least I confirmed Afterburner II and Splatter House works.

Also, with CDSD.SYS and CDISC2.SYS, you had to reboot FM TOWNS every time you change a CD-ROM media.  My driver, YSSCSICD.SYS, detects media change.

CDISC2.SYS was doing very complicated thing.  It receives commands from MSCDEX.EXE and pass to CDSD.SYS.  Also it translates direct CD-ROM BIOS calls in a format that MSCDEX.EXE would send, which is then passed to CDSD.SYS.  The result is also re-translated to the format of CD-ROM BIOS.  I just keep my YSSCSICD.SYS simple.  It just overrides CD-ROM BIOS.  MSCDEX.EXE sends requests to TOWNS_CD device driver, which then calls CD-ROM BIOS, which is intercepted by my driver, and translated to SCSI BIOS call.

As a side product, I finally figured where the system drive was written.  FM TOWNS always look for TMENU.EXP in the boot drive.  If you boot from A drive, it looks for A:\TMENU.EXP. If you boot from Q drive, it looks for Q:\TMENU.EXP . When I was using an FM TOWNS as my primary PC, I was always wondering where the information was written.

It is in bit2 to bit6 of I/O address 0x3c32.  This is an unpublished I/O.  I found by reading disassembly of CONTROL.EXE.  This I/O address is for R/W.  And, bit7, bit1, and bit0 may have a meaning.  CONTROL.EXE when /D option is used to change the system drive, also updates 0x3c32, but it first read 0x3c32 and preserved bits 7, 1, and 0.

I should be able to make a boot floppy that starts Towns MENU.  I tried on the emulator UNZ.EXE, but it crashed.  I'll see if it works in the real hardware.  Wing Commander is started from Towns MENU.  I am hoping I find a way to do so.

Although there are some issues, I really thank developers of CDSD.SYS and CDISC2.SYS for releasing the source code.


Major development in the new driver for replacing CDSD.SYS and CDISC2.SYS.  I was able to:

I was worried about unpublished functions 61H and 0FH, and indeed my driver crashed after issuing 0FH at first.  But, it turned out the cause of crash was my implementation of AH=053H which returns the play state.  When CDDA is playing, this function must return AL=1, and play state in the 10-byte buffer from DS:DI.  If not playing, it should return AL=0, and do not touch the 10-byte buffer.  However, my driver was destroying this 10-byte buffer when CDDA was not playing.  I modified my code so that it does not touch the buffer, and it started working.

But, currently I can pause but cannot stop.  Also the play state is incorrect when CDDA is paused.  SCSI2 command Read Sub-Channel (42H) gives the play state, which should be 11H if playing and 12H if paused.  But, I have a feeling that this function is actually returning play state=11H even when CDDA is paused.  I'll verify tomorrow.  CDISC2.SYS source looks to be caching PAUSE state.  Maybe many SCSI drives incorrectly report play state=11H even when CDDA is paused.

Also STOP PLAY/SCAN command (4EH) may be either non-standard command or SCSI-3 command, and SCSI2 CD drive may not understand it.  I can force CDDA by Seek command, but I don't want to move the head unnecessarily.  I may have to use PAUSE command and cache if it is pause or stop.

I'm going to open source and binary here once all the functions are working.


I have been playing with INT 93H, AH=0FDH on actual FM TOWNS II MX unit.  So far I was able to get meaningful return from INQURY and READ_TOC commands.

I initially thought I can make a small modification to CDISC2.SYS to bypass CDSD.SYS.  But, I have realized that CDISC2.SYS was doing two things:

I don't understand why CDISC2.SYS needs to receive calls from MSCDEX.EXE and redirect to CDSD.SYS.  If the only purpose is to redirect internal CD-ROM to external SCSI CD-ROM, only redirecting INT 93H, AL=0C0H to CDSD.SYS should be adequate.  If redirection of MSCDEX.EXE is necessary, I cannot make a small program that allows to use external SCSI CD-ROM drive in place for internal CD-ROM drive.

But, there is a high probability that CDSD.SYS has a lot of cache, which did not allow in-place call.  If so, I may be able to make even simpler redirector, but I need to write the driver from scratch.


Reverse Engineering FM-R/TOWNS SCSI BIOS INT 93H AH=0FDH

Success in finding and adding un-emulated function in CDISC2.SYS was very encouraging to me.  Actually, I wish I could upload boot floppy images that can start a game title from an external SCSI CD-ROM drive for as many game titles as possible in here, but what's blocking me is the license clause of CDSD.SYS.  I am allowed to redistribute source files.  But, I am not allowed to redistribute binary.  I have a feeling that the developer wouldn't care at this time.  But, I cannot find a contact of the developer.

Rather I am looking into the possibility of eliminating the dependency of CDISC2.SYS on CDSD.SYS.  The source files of CDSD.SYS is open.  So, I just need to replicate the functionality of CDSD.SYS inside CDISC2.SYS.  The source file of CDSD.SYS is using an unpublished function of FM-R/TOWNS SCSI BIOS, INT 93H AH=0FDH.  A comment in the CDSD.SYS tells it is "Direct Command Function".  I looked for the exact definition of this function.  I looked in:

Interblog, Official Technical Manual for Fujitsu FM-R Series, BNN, 1989

Noriaki Chiba, FM TOWNS Technical Guidebook, ASCII, 1989

Both has a section talking about SCSI BIOS (rather described as Disk BIOS), but INT 93H AH=0FDH was nowhere to find.  What I could guess from the CDSD.SYS source files are:

INT 93H  
AH Command Code  0FDH
DS:DI Pointer to the SCSI-command structure
CH LUN (Unit number)   LUN looks to be different from SCSI ID.  But, looks like I can just say 0.  Maybe SCSI adapter ID?  If so, FM TOWNS has just one.
CL 00H
AL Lower 4 bits: SCSI ID
Higher 4 bits 1011 (SCSI device)
Word Ptr [DS:DI] Data Read Buffer Address
Word Ptr [DS:DI+2] Data Read Buffer Segment
[DS:DI+4~] SCSI Command (Max 12 bytes)
CH Error Coe  0:No error  2: Probably parameter error  4:Meaning unknown
AX A value is returned, but the meaning is unknown.

CDSD.SYS source file is using this function as:

     int 93h
    xchg al,ah
    or ah,ah
    jz ExPhase2

It is using AL as the error code.  As far as I tested, it is incorrect.  Another bug in CDSD.SYS for FM-R/TOWNS.

I have tested this function from my test program on FM TOWNS emulator UNZ.EXE.  I issued INQUIRY command to a virtual hard drive.  If I issue INQUIRY to a SCSI ID where the virtual hard drive is connected, I had CH=0.  Otherwise I had CH=2.  In both cases AX=0.

Apparently INT 93H AH=0FDH does not tell how many bytes were read from the device.  I first suspected AX should be it, but I got zero from INQUIRY.  I then checked first two bytes of the data buffer, but it was zero, too.

I also tried to read disassembly of this function.  I was able to figure that this function is using DMA to read data from a SCSI device.  It is using DMA, but it runs a busy wait until the operation is over.  I also found a location where looks to be sending SCSI commands, but I couldn't find a place calling this routine.

     567b:	8b 1e 1c 05          	mov    0x51c,%bx   0x051c=Counter.
    567f:	8b 14                	mov    (%si),%dx   -> AH=0FDH, SCSI Disk -> DX=0x0C30  IO[0x0C30]=SCSI Data Register  RedBook pp. 262
    5681:	1e                   	push   %ds
    5682:	8b 3e 12 05          	mov    0x512,%di   Pointer to SCSI command array
    5686:	8e 1e 14 05          	mov    0x514,%ds   Pointer to SCSI command array
    568a:	8a 01                	mov    (%bx,%di),%al
    568c:	ee                   	out    %al,(%dx)
    568d:	1f                   	pop    %ds
    568e:	ff 06 1c 05          	incw   0x51c
    5692:	c3                   	ret    

This may be called as an IRQ handler for Data Request from a SCSI device.  Well, then I don't know why it is not returning by IRET.

And, I figured AX and CH carry some return information by reading the disassembly, but the meaning of AX is yet to be determined.  But, CDSD.SYS is not using AX anyway.  So, it may not matter for my purpose.

By the way, this SCSI BIOS function is internally using unpublished function of the timer BIOS, INT 97H AH=010H/011H.  It looks to be an interval timer, but the meaning is yet to be found.


Updated CDISC2.SYS!

First thing first, I've uploaded the updated CDISC2.SYS here.

Please do not throw away a FM TOWNS with a dead internal CD!

You just need a boot floppy disk or boot partition on your hard drive, but I have written how you can set up your CDSD.SYS and CDISC2.SYS to emulate the internal CD-ROM drive with an external SCSI CD-ROM drive.  The problem was that many popular game titles didn't run from an external SCSI CD-ROM drive.  I found one of the reasons.  CDISC2.SYS was not emulating one function, specifying idle time before stopping the CD-drive motor.

The situation was INT 93H with AH=052H and CH=0FFH.  Splatterhouse (namco ported by VING) was stopping in an infinite loop in the following location.  By the way I figured that I can trace very beginning of .EXP in a DOS Emulator and the original Pharlap 386DEBUG.

15334B			MOV		AX,052C0H
			MOV		CX,0FF00H
			INT		93H
			CMP		AH,00
			JNE		15334B

The fix for this problem was extremely easy:

CDStop		proc	near
; YS  This function (CH==0FFH) does not exist in SCSI-2 command
; YS  But, at least it shouldn't return an error.
; AH=52H, CH=0FFH means set sleep timer.
		cmp		ch,0ffh
		jne		@f
		mov		ah,	0


With this fix, now I can start Splatterhouse and Flying Shark.  Due to time constraints I tested only these two titles.  But I suspect more titles would run with this fix.  Either case, you would need a boot floppy or boot partition to start a game.  Have I written how to set up a boot floppy?  Maybe not.  In short, what you need to do is:

  1. Format a floppy disk from Towns OS (I recommend V2.1 L10 or V2.1 L20) with copy-system option.  If your FM Towns' CD-ROM is dead, no bootable hard drive, or you have a bootable drive, but CMOS is gone, please find someone who can make a bootable disk for you.  Or, this may work.
  2. Copy device drivers from the game's CD-ROM to the boot floppy.  Surprisingly Windows 10 can still read/write 1.2MB floppy disk with USB-connected floppy drive.  You just need to format from the FM Towns.  Or, you can try this.
  3. In the boot floppy's CONFIG.SYS, install device drivers just as the CD-ROM's CONFIG.SYS does, and also add CDSD.SYS and CDISC2.SYS.
  4. In the boot floppy's AUTOEXEC.BAT, the first line should be MSCDEX.EXE (Towns's ROM drive or C drive has it) to enable Q drive.  And then change the current drive to Q and do the same thing as CD-ROM's AUTOEXEC.BAT does.

Or, if you have a working hard drive, or hard drive emulator like SCSI2SD, you can make a small bootable partition with all device drivers from the games you want to boot, and write a launcher batch file that only update CONFIG.SYS and AUTOEXEC.BAT and REIPL to the drive.  REIPL is a FM TOWNS's command that allows you to boot from any bootable drive.

I really want to make a bunch of boot-floppy images for the games I have and open here.  BUT, CDSD.SYS does not permit re-distribution of binary.  I want to get a permission from the developer, but the contact information is not on README.  Even if there is, I don't know if the same EMail is active, and I'm stuck.

Maybe I should learn how to control SCSI from FM Towns and write my own.  I'll see.

Since I was able to enable at least two additional games with CDISC2.SYS, I'll go into this track deeper.  I'm still looking for a reason why no BGM from Wing Commander for FM TOWNS if I start from the external SCSI drive.


Sad news.  I was hoping those titles that do not run with CDSD.SYS and CDISC2.SYS were not running because those were using unpublished CD-ROM BIOS functions.  I was wrong.  I have tested on the emulator Splatter House and Hishozame (Flying Shark) with modified CDISC2.SYS that would fall into an infinite loop if a hidden function is used.  Then I would be able to see what hidden function was used in the emulator's register dump.  Actually by that I found MSCDEX.EXE was using a hidden function 0FCH, but the purpose is unknown.  It just passes.  But both Splatter House and Flying Shark did not hit my trap.

The possibilities are either CDISC2.SYS emulation is imperfect or those titles are directly beating CD-ROM I/O.

Damn!  If only I had 386DEBUG.EXE for FM TOWNS!  Actually I had a chance to try Pharlap's original 386DEBUG.EXE, but it uses INT 15H, which is not implemented on FM TOWNS.  Therefore it didn't run.  Whoever outbid me in Yahoo! auction, I hope you are really using them for a good purpose!  If you are just keeping for your collection, I'll curse you!

 The hope is it is simply because CDISC2.SYS's emulation is imperfect.  Then I should be able to improve it so that more titles can run.  If at least I can capture commands shot at CD-ROM BIOS....  I can catch them by modifying CDISC2.SYS, but the problem is how can I transmit them to outside of FM TOWNS's RAM?

Serial port!  I should be able to transmit all the commands shot at CDISC2.SYS via RS232C!  But I don't know if it is ok to call RS232C BIOS from inside of CDISC2.SYS.  I feel it would be better if I directly beat RS232C I/O.  What is RS232C I/O of FM TOWNS?

That's just Intel 8251!  I have used that chip intensively while I was writing RS232C utilities for FM-7.  I know how to use it!  So, I wrote a short test code with MASM.  I knew 8251, but I first could not figure how I should configure timer that generates baud rate.  I had to read disassembly of RS232C BIOS, but I figured it.  I was able to send letters "YS" at 19200bps from FM TOWNS to Tera Term from 8086 assembly.  I think my assembly programming skill is as sharp as when I was an undergrad.  Only it doesn't do anything good for my real job  :-P

[comtest.asm (source only)]

If you assemble and run on FM TOWNS, FM TOWNS will send two letters "YS" at 19200bps, 1 stop bit, No parity to RS232C port.

Then I should modify CDISC2.SYS so that it transmit every CD-ROM BIOS commands and maybe parameters to RS232C.  Then at least I'll know the last CD-ROM BIOS command before the program crashed.


I was believing that CD-ROM BIOS (and disk bios) is installed from the ROM since FM TOWNS needs to boot from the CD-ROM drive.  I was wrong.  CD-ROM BIOS is from IO.SYS on the CD.  It depends on the different TownsOS version then.

I guess in that case it would also be better disassembling the boot ROM before putting my FM TOWNS on the logic analyzer.  Since that will receive the byte data from the first sectors of IO.SYS, I should be able to intercept those bytes.

What's next?  My short-term goal is to increase titles that runs with CDISC2.SYS and CDSD.SYS.  Maybe I should look into individual titles.  I spent some time to check which titles work with current CDISC2.SYS and CDSD.SYS.  I didn't have too much time actually, and was able to test only a handful of game titles, but below are what I had:

Worked with no problem (You may need to make a boot floppy disk):

Worked but no BGM:

Not Work:

Didn't work, but I am positive it was working last year (Why?):

By the way, when I was using FM TOWNS as my primary computer, I didn't buy Afterburner III.  I in general don't like a product that uses a famous name but that is different.  For this reason, I didn't like Afterburner III.  There was no such arcade.  If I knew it was pretty much G-LOC, I probably bought it and played nights after nights.  Why did they call it Afterburner III?  They lost at least one customer just because they didn't call it appropriately G-LOC.

I believe I could play Wing Commander with CDISC2.SYS + CDSD.SYS, but no BGM.  If the executable is directly accessing I/O, I need to modify the code (which is possible), but if not I could make it run by improving the emulation of CDISC2.SYS, which I also can do.  In particular, if the program is using function 16H for playing CDDA, and if it is checking if the CDDA started for the presence of the CD, just redirecting function 16H to function 50H might make more titles work. 


I'm experiencing light muscle pain after carrying heavy FM TOWNS 2F, II MX, FM-7, FM77AV, and FM77AV40 to the event location, deploying them, putting them on display for two days, and then packing and stored behind my desk.

I already found interesting things while reading disassembly of CD-ROM BIOS extracted from my FM TOWNS II MX.  The following BIOS commands are published by Fujitsu.

This is all.  However, looking at the disassembly of CD-ROM BIOS, BIOS is taking FBH to 16H are data/status commands, and 4FH to 62H are CDDA commands.  Then, jump table for these commands are as follows.

00005700 02 B5 02 80 FD FF 74 E1 C3 80 3E 29 05 80 75 0C ......t...>)..u.
00005710 C6 06 29 05 82 A0 28 05 B4 11 CD 97 C3 91 14 6B ..)...(........k
00005720 14 91 14 91 14 91 14 83 14 91 14 8A 14 B8 47 0D ..............G.
00005730 8E D8 BE 39 05 8B 54 02 EC A8 80 74 0D 24 70 C0 ...9..T....t.$p.
00005740 E8 03 98 8B D8 2E FF 97 0D 15 CB B8 47 0D 8E D8 ............G...
00005750 80 3E 29 05 80 75 05 C6 06 29 05 81 CB 00 00 00 .>)..u...)......
00005760 4E 1C 0E 16 0E 16 0E 16 11 16 45 16 8C 16 F4 16 N.........E.....
00005770 03 17 3F 17 0E 16 0E 16 0E 16 0E 16 0E 16 0E 16 ..?.............
00005780 71 17 0E 16 82 17 B8 17 1D 18 40 18 0E 16 0E 16 q.........@.....
00005790 FB 16 43 18 70 18 DE 18 1B 19 6E 19 F0 19 D1 1A ..C.p.....n.....
000057a0 0F 1B 46 1B A3 1B 0E 16 0E 16 0E 16 0E 16 0E 16 ..F.............
000057b0 0E 16 0E 16 C9 1B F9 1B 00 00 00 00 00 68 47 0D .............hG.
000057c0 1F 8A 46 03 BF 58 15 3C 16 7F 04 3C FB 7D 0F 2C ..F..X.<..<.}.,
000057d0 50 BF 84 15 3C 12 7F 04 3C FF 7D 02 33 FF B4 01 P...<..<.}.3...
000057e0 0B FF 74 14 98 8B D8 8A 46 02 24 0F B4 80 B9 04 ..t.....F.$.....
000057f0 00 3C 01 73 03 E8 19 00 80 FC 80 75 03 89 4E 06 .<.s.......u..N.

Light blue bytes and following yellow bytes and blue bytes are for command 00H to 16H.  Pink bytes are for FBH to FFH.   Blue bytes and green bytes are for 50H to 62H.  Actually yellow bytes also correspond to 4FH.  Among them 0E 16 (160EH) are no function, and just returns error code.  Other addresses are assigned a function.  If CD-ROM BIOS is called with command code AH=FBH, it will jump to CS:0000, which is the re-entrance of the IRQ handler.  It probably would crash the system with stack overflow.  Command FCH will jump to 1C4EH, which is the same function as 00H, but it does not check the value of the drive mode.

Also, because there is overlap on yellow and blue bytes, command 16H must work same as 50H, and 4FH as 15H.  Also 57H, 58H, 60H, and 61H have an assigned function, but I haven't explored yet.

Looking at the source code of CDISC2.SYS, it is only re-directing BIOS call for the published commands.  Those game titles that do not work with CDISC2.sys may be directly accessing internal CD-ROM I/O (in which case I need to patch the executable), or may simply be using unpublished commands, or using 16H as 50H, or 4FH as 15H.  More titles may work if I add support for those commands in CDISC2.SYS.

I should be able to verify if the program is using these functions by patching a state file of FM TOWNS emulator UNZ.exe.  I continue exploration.


My work on FM-7 and FM77AV has achieved pretty much what I wanted to do.  I shift my focus to FM TOWNS.  I had grown up with FM TOWNS series.  I don't let them die without resisting.  I have one FM TOWNS II MX unit with a half-functioning internal CDROM drive.  It barely boot from the pressed CDs, but no CDDA.  It doesn't even recognize CD-Rs.  Apparently broken internal CDROM is a common problem in preserving FM TOWNS units in working condition.

I have heard about reverse-engineering projects, but none seems to have succeeded.  What makes me somewhat sad is all of those projects starts outside of Japan.  FM TOWNS was born in Japan, but Japanese people doesn't seem to care about preserving the heritage.  It is similar to Japanese Zero fighters.  All of the flyable Zero fighters are outside of Japan.  One person tried to keep one flyable in Japan, but could not get funding, and I believe it is no longer flying.  Quite sad, isn't it.

I have a technical specification called the "Red Book" that I salvaged from my parents' home (before thrown away.)  For experimenting, there is an excellent FM TOWNS emulator called UNZ, and MAME seems to have certain level of emulation of FM TOWNS.  The source code gives good information, too.  UNZ actually is converting internal CDROM commands to SCSI command to emulate the internal CDROM.  If so, if I make a hardware emulator that translates FM TOWNS's internal CDROM commands to SCSI command, I should be able to build an adapter that is inserted between FM TOWNS motherboard and a SCSI CDROM drive.  Once I finds the specification, it should be doable with an FPGA or maybe even Arduino.

The problem is between the I/O port and the CDROM unit.  FM TOWNS has a one-chip microcomputer that translates I/O write to the command that CDROM drive can understand, and then translates CDROM command feedback to the I/O port.  What this one-chip microcomputer does is not open.  Internal CDROM drive's pinout is not open either.  GND pins I must be able to figure by tester.  If I can pin point the one-chip microcomputer, I may able to use tester to find which of the 40pins are data pins.  Actually two of the 40 pins may be for audio, in which case I should not connect my FPGA pins to those.

Here are my goals.

Long term:

Mid term:

Short term:

Survey Links:

Comments are welcome.  Send E-Mail to: 

Back to