void __disk_ret_unimplemented(struct bregs *regs, u32 linecode, const char *fname) { u8 code = linecode; if (regs->dl < EXTSTART_HD) SET_BDA(floppy_last_status, code); else SET_BDA(disk_last_status, code); __set_code_unimplemented(regs, linecode, fname); }
void kbd_init(void) { dprintf(3, "init keyboard\n"); u16 x = offsetof(struct bios_data_area_s, kbd_buf); SET_BDA(kbd_flag2, KF2_101KBD); SET_BDA(kbd_buf_head, x); SET_BDA(kbd_buf_tail, x); SET_BDA(kbd_buf_start_offset, x); SET_BDA(kbd_buf_end_offset , x + FIELD_SIZEOF(struct bios_data_area_s, kbd_buf)); }
void __disk_ret(struct bregs *regs, u32 linecode, const char *fname) { u8 code = linecode; if (regs->dl < EXTSTART_HD) SET_BDA(floppy_last_status, code); else SET_BDA(disk_last_status, code); if (code) __set_code_invalid(regs, linecode, fname); else set_code_success(regs); }
// record completion in BIOS task complete flag void VISIBLE16 handle_76() { debug_isr(DEBUG_ISR_76); SET_BDA(disk_interrupt_flag, 0xff); eoi_pic2(); }
static void bda_init(void) { dprintf(3, "init bda\n"); struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0); memset(bda, 0, sizeof(*bda)); #if CONFIG_INT10_SERIAL_CONSOLE // set the default INT10 to serial console value #if CONFIG_CHECK_CMOS_SETTING_FOR_CONSOLE_ENABLE if (!cmos_serial_console_debug_level) SET_BDA(video_mode, UART_OUTPUT_DISABLED); else SET_BDA(video_mode, UART_OUTPUT_ENABLED); #else SET_BDA(video_mode, UART_OUTPUT_ENABLED); #endif #endif int esize = EBDA_SIZE_START; u16 ebda_seg = EBDA_SEGMENT_START; extern u8 final_varlow_start[]; if (!CONFIG_MALLOC_UPPERMEMORY) ebda_seg = FLATPTR_TO_SEG(ALIGN_DOWN((u32)final_varlow_start, 1024) - EBDA_SIZE_START*1024); SET_BDA(ebda_seg, ebda_seg); SET_BDA(mem_size_kb, ebda_seg / (1024/16)); // Init ebda struct extended_bios_data_area_s *ebda = get_ebda_ptr(); memset(ebda, 0, sizeof(*ebda)); ebda->size = esize; add_e820((u32)ebda, BUILD_LOWRAM_END-(u32)ebda, E820_RESERVED); // Init extra stack StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - zonelow_base); }
static void dequeue_key(struct bregs *regs, int incr, int extended) { yield(); u16 buffer_head; u16 buffer_tail; for (;;) { buffer_head = GET_BDA(kbd_buf_head); buffer_tail = GET_BDA(kbd_buf_tail); if (buffer_head != buffer_tail) break; if (!incr) { regs->flags |= F_ZF; return; } yield_toirq(); } u16 keycode = GET_FARVAR(SEG_BDA, *(u16*)(buffer_head+0)); u8 ascii = keycode & 0xff; if (!extended) { // Translate extended keys if (ascii == 0xe0 && keycode & 0xff00) keycode &= 0xff00; else if (keycode == 0xe00d || keycode == 0xe00a) // Extended enter key keycode = 0x1c00 | ascii; else if (keycode == 0xe02f) // Extended '/' key keycode = 0x352f; // Technically, if the ascii value is 0xf0 or if the // 'scancode' is greater than 0x84 then the key should be // discarded. However, there seems no harm in passing on the // extended values in these cases. } if (ascii == 0xf0 && keycode & 0xff00) keycode &= 0xff00; regs->ax = keycode; if (!incr) { regs->flags &= ~F_ZF; return; } u16 buffer_start = GET_BDA(kbd_buf_start_offset); u16 buffer_end = GET_BDA(kbd_buf_end_offset); buffer_head += 2; if (buffer_head >= buffer_end) buffer_head = buffer_start; SET_BDA(kbd_buf_head, buffer_head); }
static void init_bda(void) { dprintf(3, "init bda\n"); struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0); memset(bda, 0, sizeof(*bda)); int esize = EBDA_SIZE_START; SET_BDA(mem_size_kb, BUILD_LOWRAM_END/1024 - esize); u16 ebda_seg = EBDA_SEGMENT_START; SET_BDA(ebda_seg, ebda_seg); // Init ebda struct extended_bios_data_area_s *ebda = get_ebda_ptr(); memset(ebda, 0, sizeof(*ebda)); ebda->size = esize; add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA(ebda_seg, size) * 1024 , E820_RESERVED); // Init extra stack StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - datalow_base); }
static void vbe_104f10(struct bregs *regs) { switch (regs->bl) { case 0x00: regs->bx = 0x0f30; break; case 0x01: SET_BDA(vbe_flag, regs->bh); break; case 0x02: regs->bh = GET_BDA(vbe_flag); break; default: regs->ax = 0x014f; return; } regs->ax = 0x004f; }
static u8 enqueue_key(u16 keycode) { u16 buffer_start = GET_BDA(kbd_buf_start_offset); u16 buffer_end = GET_BDA(kbd_buf_end_offset); u16 buffer_head = GET_BDA(kbd_buf_head); u16 buffer_tail = GET_BDA(kbd_buf_tail); u16 temp_tail = buffer_tail; buffer_tail += 2; if (buffer_tail >= buffer_end) buffer_tail = buffer_start; if (buffer_tail == buffer_head) return 0; SET_FARVAR(SEG_BDA, *(u16*)(temp_tail+0), keycode); SET_BDA(kbd_buf_tail, buffer_tail); return 1; }
static void dequeue_key(struct bregs *regs, int incr, int extended) { yield(); u16 buffer_head; u16 buffer_tail; for (;;) { buffer_head = GET_BDA(kbd_buf_head); buffer_tail = GET_BDA(kbd_buf_tail); if (buffer_head != buffer_tail) break; if (!incr) { regs->flags |= F_ZF; return; } yield_toirq(); } u8 ascii_code = GET_FARVAR(SEG_BDA, *(u8*)(buffer_head+0)); u8 scan_code = GET_FARVAR(SEG_BDA, *(u8*)(buffer_head+1)); if ((ascii_code == 0xF0 && scan_code != 0) || (ascii_code == 0xE0 && !extended)) ascii_code = 0; regs->ax = (scan_code << 8) | ascii_code; if (!incr) { regs->flags &= ~F_ZF; return; } u16 buffer_start = GET_BDA(kbd_buf_start_offset); u16 buffer_end = GET_BDA(kbd_buf_end_offset); buffer_head += 2; if (buffer_head >= buffer_end) buffer_head = buffer_start; SET_BDA(kbd_buf_head, buffer_head); }
static void disk_13(struct bregs *regs, struct drive_s *drive_gf) { //debug_stub(regs); // clear completion flag SET_BDA(disk_interrupt_flag, 0); switch (regs->ah) { case 0x00: disk_1300(regs, drive_gf); break; case 0x01: disk_1301(regs, drive_gf); break; case 0x02: disk_1302(regs, drive_gf); break; case 0x03: disk_1303(regs, drive_gf); break; case 0x04: disk_1304(regs, drive_gf); break; case 0x05: disk_1305(regs, drive_gf); break; case 0x08: disk_1308(regs, drive_gf); break; case 0x09: disk_1309(regs, drive_gf); break; case 0x0c: disk_130c(regs, drive_gf); break; case 0x0d: disk_130d(regs, drive_gf); break; case 0x10: disk_1310(regs, drive_gf); break; case 0x11: disk_1311(regs, drive_gf); break; case 0x14: disk_1314(regs, drive_gf); break; case 0x15: disk_1315(regs, drive_gf); break; case 0x16: disk_1316(regs, drive_gf); break; case 0x41: disk_1341(regs, drive_gf); break; case 0x42: disk_1342(regs, drive_gf); break; case 0x43: disk_1343(regs, drive_gf); break; case 0x44: disk_1344(regs, drive_gf); break; case 0x45: disk_1345(regs, drive_gf); break; case 0x46: disk_1346(regs, drive_gf); break; case 0x47: disk_1347(regs, drive_gf); break; case 0x48: disk_1348(regs, drive_gf); break; case 0x49: disk_1349(regs, drive_gf); break; case 0x4e: disk_134e(regs, drive_gf); break; default: disk_13XX(regs, drive_gf); break; } }
int cdrom_boot(struct drive_s *drive_g) { ASSERT32FLAT(); struct disk_op_s dop; int cdid = getDriveId(EXTTYPE_CD, drive_g); memset(&dop, 0, sizeof(dop)); dop.drive_g = drive_g; if (!dop.drive_g || cdid < 0) return 1; int ret = scsi_is_ready(&dop); if (ret) dprintf(1, "scsi_is_ready returned %d\n", ret); // Read the Boot Record Volume Descriptor u8 buffer[CDROM_SECTOR_SIZE]; dop.lba = 0x11; dop.count = 1; dop.buf_fl = buffer; ret = cdb_read(&dop); if (ret) return 3; // Validity checks if (buffer[0]) return 4; if (strcmp((char*)&buffer[1], "CD001\001EL TORITO SPECIFICATION") != 0) return 5; // ok, now we calculate the Boot catalog address u32 lba = *(u32*)&buffer[0x47]; // And we read the Boot Catalog dop.lba = lba; dop.count = 1; ret = cdb_read(&dop); if (ret) return 7; // Validation entry if (buffer[0x00] != 0x01) return 8; // Header if (buffer[0x01] != 0x00) return 9; // Platform if (buffer[0x1E] != 0x55) return 10; // key 1 if (buffer[0x1F] != 0xAA) return 10; // key 2 // Initial/Default Entry if (buffer[0x20] != 0x88) return 11; // Bootable u8 media = buffer[0x21]; CDEmu.media = media; CDEmu.emulated_drive_gf = dop.drive_g; u16 boot_segment = *(u16*)&buffer[0x22]; if (!boot_segment) boot_segment = 0x07C0; CDEmu.load_segment = boot_segment; CDEmu.buffer_segment = 0x0000; u16 nbsectors = *(u16*)&buffer[0x26]; CDEmu.sector_count = nbsectors; lba = *(u32*)&buffer[0x28]; CDEmu.ilba = lba; // And we read the image in memory dop.lba = lba; dop.count = DIV_ROUND_UP(nbsectors, 4); dop.buf_fl = MAKE_FLATPTR(boot_segment, 0); ret = cdb_read(&dop); if (ret) return 12; if (media == 0) { // No emulation requested - return success. CDEmu.emulated_extdrive = EXTSTART_CD + cdid; return 0; } // Emulation of a floppy/harddisk requested if (! CONFIG_CDROM_EMU || !cdemu_drive_gf) return 13; // Set emulated drive id and increase bios installed hardware // number of devices if (media < 4) { // Floppy emulation CDEmu.emulated_extdrive = 0x00; // XXX - get and set actual floppy count. set_equipment_flags(0x41, 0x41); switch (media) { case 0x01: // 1.2M floppy CDEmu.lchs.spt = 15; CDEmu.lchs.cylinders = 80; CDEmu.lchs.heads = 2; break; case 0x02: // 1.44M floppy CDEmu.lchs.spt = 18; CDEmu.lchs.cylinders = 80; CDEmu.lchs.heads = 2; break; case 0x03: // 2.88M floppy CDEmu.lchs.spt = 36; CDEmu.lchs.cylinders = 80; CDEmu.lchs.heads = 2; break; } } else { // Harddrive emulation CDEmu.emulated_extdrive = 0x80; SET_BDA(hdcount, GET_BDA(hdcount) + 1); // Peak at partition table to get chs. struct mbr_s *mbr = (void*)0; u8 sptcyl = GET_FARVAR(boot_segment, mbr->partitions[0].last.sptcyl); u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow); u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads); CDEmu.lchs.spt = sptcyl & 0x3f; CDEmu.lchs.cylinders = ((sptcyl<<2)&0x300) + cyllow + 1; CDEmu.lchs.heads = heads + 1; } // everything is ok, so from now on, the emulation is active CDEmu.active = 0x01; dprintf(6, "cdemu media=%d\n", media); return 0; }