void BIOS_Init() { Mem_rStosb(0x400, 0, 0x200); // Clear the Bios Data Area (0x400-0x5ff, 0x600- is accounted to DOS) // Setup all the interrupt handlers the Bios controls CALLBACK_SetupExtra(0, CB_IRQ0, dWord2Ptr(BIOS_DEFAULT_IRQ0_LOCATION)); RealSetVec(0x08, BIOS_DEFAULT_IRQ0_LOCATION); BIOS_HostTimeSync(); // Initialize the timer ticks CALLBACK_Install(0x11, &INT11_Handler, CB_IRET); // INT 11 Get equipment list CALLBACK_Install(0x12, &INT12_Handler, CB_IRET); // INT 12 Memory size default at 640 kb Mem_Stosw(BIOS_MEMORY_SIZE, 640); CALLBACK_Install(0x13, &INT13_DiskHandler, CB_IRET_STI); // INT 13 BIOS Disk support Mem_Stosb(BIOS_HARDDISK_COUNT, 2); // Setup the Bios Area CALLBACK_Install(0x14, &INT14_Handler, CB_IRET_STI); // INT 14 Serial ports CALLBACK_Install(0x15, &INT15_Handler, CB_IRET_STI); // INT 15 Misc calls BIOS_SetupKeyboard(); // INT 16 Keyboard handled in another file CALLBACK_Install(0x17, &INT17_Handler, CB_IRET_STI); // INT 17 Printer Routines CALLBACK_Install(0x1a, &INT1A_Handler, CB_IRET_STI); // INT 1A Time and some other functions // These are already setup as dummy by CALLBACK_Init() // CALLBACK_SetupDummyIRET(0x1c); // INT 1C System timer tick called from INT 8 // CALLBACK_Install(0x71, NULL, CB_IRQ9); // Irq 9 rerouted to irq 2 // CALLBACK_SetupDummyIRET(0x18); // Reboot dummies // CALLBACK_SetupDummyIRET(0x19); // set system BIOS entry point too Mem_aStosb(0xffff0, 0xEA); // FAR JMP Mem_aStosd(0xffff1, Mem_Lodsd(0x18*4)); Bitu cbID = CALLBACK_Allocate(); // Irq 2 CALLBACK_Setup(cbID, NULL, CB_IRET_EOI_PIC1, dWord2Ptr(BIOS_DEFAULT_IRQ2_LOCATION)); RealSetVec(0x0a, BIOS_DEFAULT_IRQ2_LOCATION); Mem_aStosb(BIOS_DEFAULT_HANDLER_LOCATION, 0xcf); // BIOS default interrupt vector location -> IRET Mem_aWrites(0xfff00, "vDos BIOS", 9); // System BIOS identification Mem_aWrites(0xffff5, "01/01/99\x00\xfc\x24", 11); // System BIOS date + signature for (Bitu i = BIOS_COM1_TIMEOUT; i <= BIOS_COM4_TIMEOUT; i++) // Port timeouts Mem_Stosb(i, 1); }
Bit8u DOS_FCBRead(Bit16u seg, Bit16u offset, Bit16u recno) { DOS_FCB fcb(seg, offset); Bit8u fhandle, cur_rec; Bit16u cur_block, rec_size; fcb.GetSeqData(fhandle, rec_size); fcb.GetRecord(cur_block, cur_rec); Bit32u pos = ((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle, &pos, DOS_SEEK_SET)) return FCB_READ_NODATA; Bit16u toread = rec_size; if (!DOS_ReadFile(fhandle, dos_copybuf, &toread) || toread == 0) return FCB_READ_NODATA; if (toread < rec_size) // Zero pad copybuffer to rec_size memset(dos_copybuf+toread, 0, rec_size-toread); vPC_rBlockWrite(dWord2Ptr(dos.dta())+recno*rec_size, dos_copybuf, rec_size); if (++cur_rec > 127) { cur_block++; cur_rec = 0; } fcb.SetRecord(cur_block, cur_rec); if (toread == rec_size) return FCB_SUCCESS; return FCB_READ_PARTIAL; }
static Bitu default_handler(void) { LOG_MSG("Unhandled interrupt called: %2X", lastint); Bit32u addr = (Bit32u)MemBase+4*0x0e; LOG_MSG("0:4xe: %x", *(Bit32u*)addr); addr = dWord2Ptr(*(Bit32u*)addr); LOG_MSG("addr: %x, val: %x", addr, *(Bit32u*)(MemBase+addr)); return CBRET_NONE; }
Bit8u DOS_FCBWrite(Bit16u seg, Bit16u offset, Bit16u recno) { DOS_FCB fcb(seg, offset); Bit8u fhandle, cur_rec; Bit16u cur_block, rec_size; fcb.GetSeqData(fhandle, rec_size); fcb.GetRecord(cur_block, cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle, &pos, DOS_SEEK_SET)) return FCB_ERR_WRITE; vPC_rBlockRead(dWord2Ptr(dos.dta())+recno*rec_size, dos_copybuf, rec_size); Bit16u towrite = rec_size; if (!DOS_WriteFile(fhandle, dos_copybuf, &towrite)) return FCB_ERR_WRITE; Bit32u size; Bit16u date, time; fcb.GetSizeDateTime(size, date, time); if (pos+towrite > size) size = pos+towrite; date = DOS_PackDate(dos.date.year, dos.date.month, dos.date.day); // Ttime doesn't keep track of endofday Bit32u ticks = vPC_rLodsd(BIOS_TIMER); Bit32u seconds = (ticks*10)/182; Bit16u hour = (Bit16u)(seconds/3600); Bit16u min = (Bit16u)((seconds % 3600)/60); Bit16u sec = (Bit16u)(seconds % 60); time = DOS_PackTime(hour, min, sec); Bit8u temp = RealHandle(fhandle); Files[temp]->time = time; Files[temp]->date = date; fcb.SetSizeDateTime(size, date, time); if (++cur_rec > 127) { cur_block++; cur_rec = 0; } fcb.SetRecord(cur_block, cur_rec); return FCB_SUCCESS; }