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.
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.
12AB:0000 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.
PUTC 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 PRINT DEBUG STRING from DX 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.
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:
|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.|
|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:
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.
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 ret @@:
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:
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
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:
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.
|Comments are welcome. Send E-Mail to:|