• Please review our updated Terms and Rules here

Help with 286 bios de-compiling.

errolt

Member
Joined
Apr 26, 2024
Messages
24
Hi Everyone,

I'm working on an Halikan LA-20 laptop from the late 80's. It is a 286 laptop with 640KB ram and it shipped with only two 720K floppy drives and two 6V lead acid batteries. The heads on one of the drives are so worn out that it can only read the first 20 or so tracks on a disk.

I want to add a hard drive, or CF card, to the laptop.

The laptop exposes all the 16bit ISA signals on a custom 32 pin by 3 row connector inside the laptop. The footprint looks like it fits a 96pin "Euro Card" type connector. From one photo I found on the net about the LA-22, this was where the hard drive expansion card connected.

I build a 16bit "XTIDE" type card with a GAL, CF slot and flash chip and connected it to the ISA signals on the laptop.

Now the issues:
1. If I place CS1 of the drive at 0x1f0-0x1f7 then the floppy drive can't see a floppy disk in the drive(drive seeks during POST, but accessing it gives "Drive not ready"). This is odd, because the floppy interface sits at 0x3f0-0x3f7. I can map CS2 to the 0x3f0 range with no problem, but the moment I map anything into 0x1f0 range then the drive stops working. All I can think is that the BIOS does something odd when it finds a hard drive at 0x1f0, and remaps the floppy drive. It is possible that the LA-22 IDE card does something to the floppy controller, or replaces it?
2. The bios supports drive type 1 to 47, no custom types, and no info as to what each type represents.

This is where I need help with de-compiling the BIOS.

PS. I can map the CF card to 0x170/0x370 secondary IDE address and use XTIDE on the flash chip, and everything works, but I would like to figure out how to get the bios to recognize and support the CF card natively without an intrusive XTIDE menu(which also eats 1KB of ram!)...

PPS. The laptop has a ram expansion header, but the header only provides A0-A8, D0-D16 and some other odds and ends. No RAS/CAS signals. That must be provided by a missing PAL which, I guess, came with the ram expansion card. The PAL has access to A0,A19-A21, REFRESH, XBHE and SysClock. I have not been able to figure out how the timing for RAS/CAS must be generated, as A0-A8 must already supply the row/column data and the RAS/CAS signals must be synced with it.
 

Attachments

The BIOS selectable drive types 1-47 should just be a table of pre-defined hard drive parameters (Cylinder, Head, Sector, Write Pre-Comp, Landing Zone) from which you could select one that matched a common drive available at the time. It's possible that the parameter data is largely identical to that provided for any other PC, but it's also possible that the developer of a particular BIOS (or family thereof) chose to use a slightly different set.

From looking at the file in a hex editor it looks like this is an AMI BIOS from 1986/1987.

0xFF59 to 0xFF6F: (C)1986AMI,404-263-8181
0xFFF5 to 0xFFFC: 03/09/87


This VOGONS thread/post might be useful to you:

I've attached a copy of a 286 BIOS I downloaded a few years ago. This one seems to be intact as far as I can tell.

Right smack dab at 0xE400 (or possible 0xE401) is what appears to be the first entry in the hd types table:
0xE400: 00 32 01 04 00 00 80 00 00 00 00 00 00 31 01 11
0xE401: 32 01 04 00 00 80 00 00 00 00 00 00 31 01 11 00

P.S.

Type 47 is supposed to be for user defined parameters.

What they should be probably depends on whether the CF card is compatible with C,H,S or expects LBA.
 

Attachments

Last edited:
The IBM AT BIOS, and early clones, have a bug which precludes using IDE drives with it directly. When IRQ14 occurs, the interrupt handler reads a sector, then reads the status register to acknowledge the interrupt. "Fast" (in late 1980s terms) drives already generate another IRQ between the read of the 256th word and the BIOS reading that status register, so subsequent interrupts are lost while reading. If your BIOS has this bug, it is more complicated than just overwriting one of the types with 1024/16/63.

For compatibility, clone BIOSes try to keep data structures at the same offsets as in the IBM BIOS. The hard disk table is at 0E401h. However, it appears this BIOS was not dumped properly as there are way too many FF bytes in there. If you change the table, you'll also have to update the checksum. Later AMIBIOSes add up the whole BIOS as 16-bit words and ensure the result is zero. With this being such an early one, I am not sure if that's already the case.

Port 3f7h is shared by the floppy and hard disk controller. The floppy controller drives bit 7 while the hard disk drives bits 0-6. But I have no idea if that's related to your problem.
 
My worry with this bios is, because this is a laptop, and the user isn't expected to plug in random expansion cards, that the bios is modified in non standard ways. Maybe it expects the disk controller at a non standard address. Or the disk controller also replaces the onboard floppy controller.

@Makefile
I saw all the FFs, and was wondering about that. I used a bios dump utility, can't remember which one, as the two eproms are soldered to the motherboard. I downloaded NSSI and will see what it's bios dump looks like. I don't know why the last bit is ripped good, but the first lot is a mess... If all else fails then I'll socket them and then I can dump them properly.
The IRQ might be one of the issues. If I select a hard drive in the bios(with my card mapped to 1f0h) then the computer hangs for 15 or 20 seconds during post, then gives a hard drive controller error.
I'm aware of the 3f7h "clash", but that does not seem to be the floppy issue.
As a side note, NSSI does detect my homebrew IDE controller as the secondary controller(because I moved it to 170h, even though it is still on IRQ14), and it detects the CF card plugged into it. So theoretically my controller is correctly implemented?

@Istarian
Thanks, I saw that post, but the info in the bios didn't match the info in that post. But that is probably due to the bad rip as pointed out by @Makefile.
Type 47 "should" be for a user defined type, but this bios setup is VERY basic. It asks you, line by line, questions, enter time, enter date, 40/80 column text, then it auto fills the floppy drives(no option to select 1.44MB), then it asks for disk one type, disk two type, and a final "is this correct". On "y" it reboots. No extra questions if you selected 47 to enter details. 🤷‍♂️. If you make a mistake during entry then there is no way to go back, you have to answer "n" at the "is this correct" question, then start over.
But at least it has a "Press (DEL) to enter bios" during post. Unlike my Toshiba T3100SX that needs a utility on the hard drive to enter the bios.
 
Last edited:
This dump looks much better. The Bios is 32KB, the drive tables are there. And I found a prompt(which I never saw on screen but it's there) to show the disk type details. They only go to type 46, and the bios allows you to enter 47. I also saw things in the bios about a DIAG mode which I have never seen on screen. I also see text in the dump prompting for cylinders and heads, but that also never appears on screen.

This is the extent of the bios configuration:
Want to run SETUP utility (Y/N)?
C M O S S E T U P
Current date is : Enter new date (MM-DD-YYYY)?
Current time is : Enter new time (HH:MM:SS)?
Primary display is : Color display
Enter screen width (80 or 40)?
*** WARNING ***
Entering the wrong disk drive TYPE causes improper operation of the disk.
If disk not installed, press <RETURN>.
For disk TYPE details, press <ESC>.

Enter disk drive C type (1-47)?
Enter disk drive D type (1-47)?
Diskette drive A is :
Diskette drive B is :
Base memory size is :
Expansion memory size is :
Are these options correct (Y/N)?
Stand by while system is rebooting.
 

Attachments

@Vortex286 See my previous post. It was still waiting for moderation when you posted. I think I did the bad dump with a tool called biosdump? But I can't remember. The new dump was with NSSI and looks much better. I will try to feed this new dump into IDA to see what it says.
 
This time all odd bytes are FF and the even bytes are almost 00 until offset 8000h
Yes, and at 8000h there is the EVEN/ODD eprom chip markers(which I assume would be at the beginning of each eprom) and the AMI copyright. Which is why I said it is a 32K bios. Even though NSSI ripped the full 64KB block.

1777490275079.png
 
Last edited:
It's pretty weird to have repeating characters in that picture...

E.g.

228866 and ((CC))AAMMII

If the BIOS is 32K then why not use 2 16K ROMs or purposefully leave the unneeded portions of 32K ROMs as a swath of FF bytes?

Are you saying that the dump tool you used this time is interleaving two copies of the real BIOS?
 
OP didn't dump the actual EPROMs, he used a tool that just reads memory. Which is fine for a 286, because the BIOS is uncompressed and directly mapped to memory.

The repeating characters are expected on interleaved EPROMs so that if they are dumped separately, one would start with "286-EVEN (C)AMI" and the other would start with "286-ODD (C)AMI".

The BIOS2 file looks ok to me. Note that "native" IDE support on a BIOS of that vintage is going to be limited to 504MiB / 528MB at most. So if you want to use a larger CF card, you'll need to use an add-on BIOS like XUB anyway.
 
Even if I did dump the eporms, on merging them you would get what I posted, double characters and all, but only the top 32KB.

IDA is making much more sense of this BIOS2 file, and IDA is being very helpful, labeling access to known registers like the disk interface. The bios is definitely looking for a disk at 1f0h-1f7h and 3f6h/3f7h, but I don't know yet if it is expecting it on INT14. And I still dont know why the floppy stops working if the bios detects something at 1fxh.
 
I found:
0AA71h INT 13h for HDD
0AFA4h INT 76h IRQ14
0B18Eh The function that retrieve the HDD parameters from CMOS
0C690h The function for the set up prompt
0E401h The HDD table

The HDD function seems self-contained in the range 0AA71h-0AF21h with empty space in the range 0AF21h-0AFA3h.
It might be possible to replace this block with an updated version that supports translation.

What's the chipset in this laptop?
 
Hmm, none of those interrupts makes sense to me, what does INT 76h mean? Does the bios look for interrupts from the harddrive on IRQ14?

The laptop uses the following main chips:
82C201
82C202
82C203
82C204
82C205
WD37C65B for floppy.
I can't remember the display chip.

I've slowly been going through the bios in IDA renaming functions trying to figure out what is happening. I did see that the "DIAG" mode is only supported in the 64K bios, which I don't have... :(
 
I see jumps to code outside the harddisk code block. Like at 0AC13h there is a jump to 0B0D0h which seems to set up some interrupts and sends something to the drive at 17Fh, so not all drive code is in the AA71h - AFA3h block.
 
Your BIOS does have the bug where 1f7 is read at ad02 after rep insw at acf9 rather than before, so it's not going to work completely with IDE anyway.
Is it possible your CS0 decoding is accidentally including parts of 3fx and by moving it to 170 it erroneously decodes 37x instead which doesn't hurt anything rather than interfering with the FDC?
 
Well, the HDD functions extend to 0B2F2h with its initialization function at 0B18Eh.

INT 76h is the handler for IRQ14
IRQ14 is triggered by the signal from pin 31 on the IDE connector
When the CPU receives IRQ14, it interrupts what it is doing, execute INT 76h then resumes with what it was doing.

The function at 0B0D0h reinitializes IRQ14 and pass the command in AL to the HDD.
The function at 0B026h waits for IRQ14.


On IRQ14 initialization:
Clear the flag at 40:8E

When waiting for IRQ14:
Set a time out in DX
Call the function at 0E377h that check the flag at 40:8E

On IRQ14:
Set the flag at 40:8E to FF


The wait ends when the flag is set.


Notice also the flag is doubled with calls to INT 15h
Wait: Call INT 15h with AX=9000h
IRQ14: Call INT 15h with AX=9100h

The default INT 15h at 0B310h does nothing.
They are meant to be hooked by a multitasker.
 
Hmm, none of those interrupts makes sense to me, what does INT 76h mean? Does the bios look for interrupts from the harddrive on IRQ14?
On the AT, while in real mode, hardware IRQs 0 through 7 translate to INT 08h+IRQ in software while hardware IRQs 8 through 15 translate to INT 70h-8+IRQ.
 
Your BIOS does have the bug where 1f7 is read at ad02 after rep insw at acf9 rather than before, so it's not going to work completely with IDE anyway.
Esh. Ok, that sinks this whole exercise...


Is it possible your CS0 decoding is accidentally including parts of 3fx and by moving it to 170 it erroneously decodes 37x instead which doesn't hurt anything rather than interfering with the FDC?
I don't think so. I used debug to probe 3f6 & 3f7 and there isn't anything there when I map CS0 to 1f0.

But here is my code, maybe I had a doh moment:
GAL20V8 ; IDE decoder first line : used GAL
IDE ; second line: any text (max. 8 char.)


AEN A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 GND
A15 A16 A17 A18 A19 ROMCS CS0 CS1 NC NRESET RESET VCC


/CS0 = /AEN * /A9 * A8 * A7 * A6 * A5 * A4 * /A3 ;0x1f0
/CS1 = GND ;/AEN * A9 * A8 * A7 * A6 * A5 * A4 * /A3 ;0x3f0
;/CS0 = /AEN * /A9 * A8 * /A7 * A6 * A5 * A4 * /A3 ;0x170
;/CS1 = /AEN * A9 * A8 * /A7 * A6 * A5 * A4 * /A3 ;0x370

/ROMCS = /AEN * A15 * /A16 * /A17 * A18 * A19 ;C800
;/ROMCS = /AEN * A15 * /A16 * A17 * A18 * A19 ;D800
NRESET = /RESET

DESCRIPTION

IDE Address decoding:
CS0 = 0x1F0 - 0x1F7
CS1 = 0x3F0 - 0x3F7
NRESET = NOT RESET
ROMCS=C800:0000

INT 76h is the handler for IRQ14
IRQ14 is triggered by the signal from pin 31 on the IDE connector
When the CPU receives IRQ14, it interrupts what it is doing, execute INT 76h then resumes with what it was doing.
Thanks for the explanation. I'm more an embedded dev, never did x86 asm so this is new to me.

On the AT, while in real mode, hardware IRQs 0 through 7 translate to INT 08h+IRQ in software while hardware IRQs 8 through 15 translate to INT 70h-8+IRQ.
Oh, that makes sense, not. I'm used to systems where IRQx stays IRQx, but they, whatever worked for them.

Thank you very much to @Makefile and @Vortex286 for your assistance. But as Makefile pointed out, the bios is bugged. Which means this card can't be a native drop in without xtide bios extension, and then I can place it anywhere open in the address space. I will put the designs on github, but as the bios is soldered in, patching it isn't going to be easy for anyone that wants to make/use the card. I will just have to live with xtide bios.
 
Esh. Ok, that sinks this whole exercise...
If you get the floppy issue out of the way and want to badly enough, it can be fixed. The existing code that reads 1f7 can be changed to read 3f6 instead, which does not acknowledge a pending interrupt. Then, the handler at afa4 needs changed so that it reads from 1f7 and throws it away so that the IRQ is acknowledged (I have to think about whether this would mess up writes. I don't think so). There is room before afa4 for it to spill into, where there is a block of zeros.

Incidentally, if you used this BIOS as is and installed DOS, it would appear to work until you reboot from the C: drive and try to execute a program, where it will hang. This is because the bug isn't hit until a read is issued with a sector count greater than one.

I don't see anything wrong with the equations. Is CS1# always ground?

Oh, that makes sense, not. I'm used to systems where IRQx stays IRQx, but they, whatever worked for them.
Because the low software interrupts/exception numbers are already used for other purposes (most famously, INT 3 is the software breakpoint accordingly with a special one-byte encoding 0xCC), they can't be mapped directly, but there is an offset in the IRQ number to INT number.
 
Last edited:
Back
Top