joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.77k stars 381 forks source link

PC-98 mode SASI/SCSI BIOS (INT 1Bh) emulation #656

Closed joncampbell123 closed 6 years ago

joncampbell123 commented 6 years ago

According to NP2 code:

SASI BIOS functions are AH=0x00/0x80 and SCSI BIOS functions are AH=0x20/0xA0.

There are provisions it seems to specify read/write by CHS as well as LBA.

The goal is to be able to boot PC-98 MS-DOS from an HDI image, since most PC-98 games are distributed as HDI hard disk images (that may be bootable).

joncampbell123 commented 6 years ago

If getting MS-DOS to boot from the image is too difficult, an easy compromise would be to implement just enough that PC-98 MS-DOS booted from a floppy could see a hard disk and assign it a drive letter.

joncampbell123 commented 6 years ago

Done.

It turns out prior attempts were blocked by a bug in the IMGMOUNT command where it would guess the geometry and then overwrite whatever the HDI image already specified. Since the PC-98 bootloader is sensitive to C/H/S geometry the incorrect guess caused it to load the wrong thing and crash. Also PC-98 bootable floppies need the correct C/H/S geometry to see the hard disk as well.

yksoft1 commented 6 years ago

For HDI images, there is still PROGRAM_BOOT_UNABLE errors coming out (HDI file not detected by BOOT command?) but imgmount -fs none/boot -l trick worked.

When I tried to boot a HDI with the boot menu, the menu shows but booting to DOS just fails. This is the log:

Image file has .HDI extension, assuming HDI image and will take on parameters in header.
HDI header: sectorsize is 512 bytes/sector, header is 4096 bytes, hdd size (plus header) is 114196480 bytes
HDI: Geometry is C/H/S 1640/8/17
Booting guest OS stack_seg=0x0030 load_seg=0x1fe0
Removing UMB block 0xd000-0xcfff
Alright: DOS kernel shutdown, booting a guest OS
  CS:IP=1fe0:0000 SS:SP=0030:00d4 AX=0030 BX=0200 CX=0200 DX=0001
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0200 CX=0200 DX=0001 SI=1FE0 DI=FFFE DS=0000 ES=1FE0
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=1C00 CX=1C20 DX=0002 SI=1D20 DI=FFFE DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=0000 DX=0002 SI=1D20 DI=FFFE DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=0334 DX=0000 SI=1D20 DI=FFFE DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0200 CX=0300 DX=0003 SI=09E0 DI=FFFE DS=0000 ES=1C20
PC-98 INT 18h unknown call AX=0A00 BX=0200 CX=0300 DX=0003 SI=09E0 DI=FFFE DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=0000 DX=E100 SI=0005 DI=239C DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=0000 DX=E100 SI=0005 DI=239C DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0000 CX=0000 DX=E100 SI=0005 DI=239C DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=0000 DX=E101 SI=0000 DI=035A DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0000 CX=0001 DX=E101 SI=0000 DI=035A DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=0000 DX=E100 SI=011D DI=0001 DS=0000 ES=1C20
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=01E1 DX=0000 SI=0220 DI=0000 DS=0000 ES=1FA0
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=01E1 DX=0000 SI=0220 DI=0000 DS=0000 ES=1FA0
PC-98 INT 18h unknown call AX=0A00 BX=0400 CX=01E1 DX=1C20 SI=0220 DI=0000 DS=0000 ES=1FA0
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=0400 CX=01E1 DX=0000 SI=0220 DI=0000 DS=0000 ES=1FA0
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=1C00 CX=1BE0 DX=0002 SI=1CE0 DI=0000 DS=0000 ES=1BE0
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=1C00 CX=000F DX=0000 SI=0800 DI=037C DS=0000 ES=1BE0
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=1C00 CX=1920 DX=0002 SI=1A20 DI=037C DS=0000 ES=1920
PC-98 INT 1Bh unknown SCSI BIOS call AX=B0A0 BX=1C00 CX=1920 DX=0006 SI=00D0 DI=037C DS=1A20 ES=1920
PC-98 INT 1Bh unknown SCSI BIOS call AX=B0A0 BX=1C00 CX=1920 DX=0006 SI=00D0 DI=037C DS=1A20 ES=1920
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=1C00 CX=1920 DX=0006 SI=00D0 DI=037C DS=0000 ES=1920
PC-98 INT 1Bh unknown SCSI BIOS call AX=00A0 BX=1C00 CX=0001 DX=0006 SI=00D0 DI=037C DS=0000 ES=1920
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
 256615962 ERROR CPU:CPU:8c:Illegal RM Byte
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: 8080/8085 mode not handled
PIC: poll command not handled
PIC: poll command not handled
 256617692 ERROR CPU:CPU:8c:Illegal RM Byte
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: 4 byte interval not handled
PIC: 8080/8085 mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
 256619412 ERROR CPU:CPU:8c:Illegal RM Byte
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled
PIC: 4 byte interval not handled
PIC: level triggered mode not handled
PIC: 8080/8085 mode not handled

I suggest to reopen this issue until such problems are fixed. Here is the HDI to test: testx.zip

joncampbell123 commented 6 years ago

Will test. Please pull the latest commit and check the HDI image.

joncampbell123 commented 6 years ago

Works on my end. Please pull the latest commit.

testx works pc98

joncampbell123 commented 6 years ago

Ah, spoke to soon. Selecting MS-DOS crashes.

joncampbell123 commented 6 years ago

The DOSBox-X log reports that the geometry is C/H/S 1640/8/17.

Is that the correct geometry?

Knowing the IPL1 partition table it is unfortunately based on C/H/S sector addresses instead of LBA sector numbers, so getting the geometry correct is very important for PC-98 hard disk booting to work.

yksoft1 commented 6 years ago

I created the HDI image in Anex86 with this geometry so I can 100% assume the CHS is right.

joncampbell123 commented 6 years ago

Can you try smaller geometries (more heads or less cylinders) to see if that fixes anything? I'm poking at the image on my end to see what I can fix about it now.

joncampbell123 commented 6 years ago

The FAT driver appears to work fine with each partition of the image. The IPL1 parsing code uses the disk geometry from the HDI image to locate partitions, so that part is correct.

It's booting the image that seems to be problematic. The first entry causes the boot menu to load some unknown data that obviously isn't an MS-DOS boot sector, executes it, and crashes.

joncampbell123 commented 6 years ago

Okay, if you imgmount without a filesystem attached, it crashes.

If you imgmount to drive c: and boot drive c:, it works.

I'll look into this now.

yksoft1 commented 6 years ago

CHS 512/4/17 -> works CHS 1024/8/17 -> works CHS 1332/8/17 -> crashes CHS 1178/8/17 -> crashes CHS 1101/8/17 -> crashes CHS 1063/8/17 -> crashes CHS 1044/8/17 -> crashes CHS 1025/8/17 -> crashes

joncampbell123 commented 6 years ago

Now that I think of it, IMGMOUNT might still have some IBM PC specific code to try to adjust the C/H/S values if the cylinder count is > 1024 cylinders if you're not mounting with a filesystem.

yksoft1 commented 6 years ago

This?

            /* INT 13h mapping, deal with 1024-cyl limit */
            while (sizes[3] > 1024) {
                if (sizes[2] >= 255) break; /* nothing more we can do */

                                            /* try to generate head count 16, 32, 64, 128, 255 */
                sizes[2]/*heads*/ *= 2;
                if (sizes[2] >= 256) sizes[2] = 255;

                /* and recompute cylinders */
                sizes[3]/*cylinders*/ = (Bitu)((Bit64u)sectors / (Bit64u)sizes[2]/*heads*/ / (Bit64u)sizes[1]/*sectors/track*/);
            }
joncampbell123 commented 6 years ago

That's exactly the code. It needs to not do it's work if PC-98 mode because PC-98 does not have the IBM PC legacy of a 510MB limit and having to remap cylinders into heads to bypass the limit.

joncampbell123 commented 6 years ago

Fixing that code now...

joncampbell123 commented 6 years ago

I have a fix I'm testing now.

The geometry translation was also in the disk image code itself.

joncampbell123 commented 6 years ago

Pull the latest commit and try again.

joncampbell123 commented 6 years ago

The latest commit allows your 3-partition 114MB HDI image to work.

yksoft1 commented 6 years ago

Found the code in bios_disk.cpp by own and disabled that for PC-98 mode, then my 300MB+ HDI also worked... Now how about the PROGRAM_BOOT_UNABLE error using BOOT xxx.hdi directly without imgmount first?

joncampbell123 commented 6 years ago

I don't think BOOT ever supported booting a hard drive directly, even in the original DOSBox project. It only supports directly booting floppy disk images as drive A at this time.

The BOOT code is designed to support hard disk booting through a drive letter using -l, or to directly boot a floppy disk image if given an image name. There's no support for directly specifying a hard disk image, just as the DOSBox project lacks it.

joncampbell123 commented 6 years ago

Git pull the latest changes and booting with the following will work:

IMGMOUNT 2 something.hdi -fs none BOOT -l C

HyabusaBadge commented 2 years ago

The PC-98 has an identification code called DA/UA (device address/unit address) that identifies FDD mode, IDE (SASI), and SCSI. However, the actual machine contains 0x8n of IDE or SASI, and SCSI contains 0xAn. (n is the number of the device) Here, the explanation of the FDD is omitted. In the implementation of DOSBOX-X, it contains 0xan because it is processed by SCSI BIOS even though it is an IDE emulation. So DOS can be booted, but Windows NT and OS/2 cannot be booted as it is. (Also, Windows 9x protect mode driver will not work.) Even in the case of DOS, it will not be possible to boot before NEC PC-98 MS-DOS 3.1 or earlier. MS-DOS 3.1 does not support SCSI. SCSI was supported after MS-DOS 3.3 or later. PC-98 has SASI / IDE BIOS and SCSI BIOS separately.

Strictly 0x2n: SCSI HARD DISK BIOS (LBA) 0xAn: SCSI HARD DISK BIOS (CHS) 0x0n: SASI / IDE HARD DISK BIOS (LBA) 0x8n: SASI / IDE HARD DISK BIOS (CHS) However, PC-98 usually uses CHS.

As a reference, it is a screenshot when both IDE and SCSI are connected to NP21/W. idescsi

The following hacking is also interesting. PC-98 fake SASI hack (proposed) #1204

remarks PC-98 IDE EMULATION #1085