Skip to content

Commit

Permalink
Add INT 13h AH=42 support for El Torito No Emulation boot
Browse files Browse the repository at this point in the history
  • Loading branch information
joncampbell123 committed Mar 23, 2024
1 parent f1b5fc3 commit bcfb979
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 10 deletions.
3 changes: 3 additions & 0 deletions include/bios_disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,4 +564,7 @@ std::string PartitionIdentifyType(imageDisk *loadedDisk);
void LogPrintPartitionTable(const std::vector<_PC98RawPartition> &parts);
void LogPrintPartitionTable(const std::vector<partTable::partentry_t> &parts);

extern unsigned char INT13_ElTorito_NoEmuDriveNumber;
extern char INT13_ElTorito_NoEmuCDROMDrive;

#endif
7 changes: 6 additions & 1 deletion src/dos/dos_programs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2321,6 +2321,10 @@ class BOOT : public Program {
for(i=0;i<2048;i++) real_writeb((uint16_t)load_seg, (uint16_t)i+(s*2048), entries[i]);
}

/* signal INT 13h to emulate a CD-ROM drive El Torito "no emulation" style */
INT13_ElTorito_NoEmuDriveNumber = 0x90;
INT13_ElTorito_NoEmuCDROMDrive = el_torito_cd_drive;

SegSet16(cs, load_seg);
SegSet16(ds, 0);
SegSet16(es, 0);
Expand All @@ -2333,7 +2337,8 @@ class BOOT : public Program {
reg_ecx = 0;
reg_ebp = 0;
reg_eax = 0;
reg_edx = 0;
/* ISOLINUX clearly assumes DL at entry contains the drive number and at no point from entry to INT 13h does it change the contents of DX */
reg_edx = INT13_ElTorito_NoEmuDriveNumber;
#ifdef __WIN32__
// let menu know it boots
menu.boot=true;
Expand Down
3 changes: 3 additions & 0 deletions src/ints/bios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9172,6 +9172,9 @@ class BIOS:public Module_base{
# endif
#endif

INT13_ElTorito_NoEmuDriveNumber = 0;
INT13_ElTorito_NoEmuCDROMDrive = 0;

ACPI_mem_enable(false);
ACPI_REGION_SIZE = 0;
ACPI_BASE = 0;
Expand Down
57 changes: 48 additions & 9 deletions src/ints/bios_disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1815,10 +1815,17 @@ bool IDE_GetPhysGeometry(unsigned char disk,uint32_t &heads,uint32_t &cyl,uint32
void IDE_EmuINT13DiskReadByBIOS_LBA(unsigned char disk,uint64_t lba);

void diskio_delay(Bits value/*bytes*/, int type = -1);

/* For El Torito "No emulation" INT 13 services */
unsigned char INT13_ElTorito_NoEmuDriveNumber = 0;
char INT13_ElTorito_NoEmuCDROMDrive = 0;

bool GetMSCDEXDrive(unsigned char drive_letter, CDROM_Interface **_cdrom);


static Bitu INT13_DiskHandler(void) {
uint16_t segat, bufptr;
uint8_t sectbuf[512];
uint8_t sectbuf[2048/*CD-ROM support*/];
uint8_t drivenum;
Bitu i,t;
last_drive = reg_dl;
Expand Down Expand Up @@ -2208,14 +2215,45 @@ static Bitu INT13_DiskHandler(void) {
break;
case 0x42: /* Extended Read Sectors From Drive */
/* Read Disk Address Packet */
readDAP(SegValue(ds),reg_si);

if (dap.num==0) {
reg_ah = 0x01;
CALLBACK_SCF(true);
return CBRET_NONE;
}

readDAP(SegValue(ds),reg_si);

if (dap.num==0) {
reg_ah = 0x01;
CALLBACK_SCF(true);
return CBRET_NONE;
}
if (INT13_ElTorito_NoEmuDriveNumber != 0 && INT13_ElTorito_NoEmuDriveNumber == reg_dl) {
CDROM_Interface *src_drive = NULL;
if (!GetMSCDEXDrive(INT13_ElTorito_NoEmuCDROMDrive - 'A', &src_drive)) {
reg_ah = 0x01;
CALLBACK_SCF(true);
return CBRET_NONE;
}

segat = dap.seg;
bufptr = dap.off;
for(i=0;i<dap.num;i++) {
static_assert( sizeof(sectbuf) >= 2048, "not big enough" );
diskio_delay(512);
if (killRead || !src_drive->ReadSectorsHost(sectbuf, false, dap.sector+i, 1)) {
// TODO: According to RBIL this should update the number of blocks field to what was successfully transferred
LOG_MSG("Error in CDROM read");
killRead = false;
reg_ah = 0x04;
CALLBACK_SCF(true);
return CBRET_NONE;
}

for(t=0;t<2048;t++) {
real_writeb(segat,bufptr,sectbuf[t]);
bufptr++;
}
}
reg_ah = 0x00;
CALLBACK_SCF(false);
return CBRET_NONE;
}

if (!any_images) {
// Inherit the Earth cdrom (uses it as disk test)
if (((reg_dl&0x80)==0x80) && (reg_dh==0) && ((reg_cl&0x3f)==1)) {
Expand Down Expand Up @@ -2243,6 +2281,7 @@ static Bitu INT13_DiskHandler(void) {
IDE_EmuINT13DiskReadByBIOS_LBA(reg_dl,dap.sector+i);

if((last_status != 0x00) || killRead) {
// TODO: According to RBIL this should update the number of blocks field to what was successfully transferred
LOG_MSG("Error in disk read");
killRead = false;
reg_ah = 0x04;
Expand Down

0 comments on commit bcfb979

Please sign in to comment.