📄 rombios.c
字号:
//-------------------------------------------------------------------------- voidprint_boot_failure(type, reason) Bit16u type; Bit8u reason;{ if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n"); printf("Boot from %s failed", drivetypes[type]); if (type < 4) { /* Report the reason too */ if (reason==0) printf(": not a bootable disk"); else printf(": could not read the boot disk"); } printf("\n");}//--------------------------------------------------------------------------// print_cdromboot_failure// displays the reason why boot failed//-------------------------------------------------------------------------- voidprint_cdromboot_failure( code ) Bit16u code;{ bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "CDROM boot failure code : %04x\n",code); return;}#define WAIT_HZ 18/** * Check for keystroke. * @returns True if keystroke available, False if not. */Bit8u check_for_keystroke(){ASM_START mov ax, #0x100 int #0x16 jz no_key mov al, #1 jmp doneno_key: xor al, aldone:ASM_END}/** * Get keystroke. * @returns BIOS scan code. */Bit8u get_keystroke(){ASM_START mov ax, #0x0 int #0x16 xchg ah, alASM_END}/** * Waits (sleeps) for the given number of ticks. * Checks for keystroke. * * @returns BIOS scan code if available, 0 if not. * @param ticks Number of ticks to sleep. * @param stop_on_key Whether to stop immediately upon keypress. */Bit8u wait(ticks, stop_on_key) Bit16u ticks; Bit8u stop_on_key;{ long ticks_to_wait, delta; Bit32u prev_ticks, t; Bit8u scan_code = 0; /* * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock. * We also have to be careful about interrupt storms. */ ticks_to_wait = ticks; prev_ticks = read_dword(0x0, 0x46c); do { t = read_dword(0x0, 0x46c); if (t > prev_ticks) { delta = t - prev_ticks; /* The temp var is required or bcc screws up. */ ticks_to_wait -= delta; } else if (t < prev_ticks) ticks_to_wait -= t; /* wrapped */ prev_ticks = t; if (check_for_keystroke()) { scan_code = get_keystroke(); bios_printf(BIOS_PRINTF_DEBUG, "Key pressed: %x\n", scan_code); if (stop_on_key) return scan_code; } } while (ticks_to_wait > 0); return scan_code;}static void clearscreen() { /* Hide cursor, clear screen and move cursor to starting position */ASM_START push bx push cx push dx mov ax, #0x100 mov cx, #0x1000 int #0x10 mov ax, #0x700 mov bh, #7 xor cx, cx mov dx, #0x184f int #0x10 mov ax, #0x200 xor bx, bx xor dx, dx int #0x10 pop dx pop cx pop bxASM_END}int bootmenu(selected) int selected;{ Bit8u scode; int max; /* get the number of boot devices */ max = read_word(IPL_SEG, IPL_COUNT_OFFSET); for(;;) { if (selected > max || selected < 1) selected = 1; clearscreen(); bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n\n\n\n\n\n"); bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " Select boot device\n\n"); bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 1. Floppy\n"); bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 2. Hard drive\n"); bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 3. CD-ROM\n"); if (max == 4) bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 4. Network\n"); bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n Currently selected: %d\n", selected); do { scode = wait(WAIT_HZ, 1); } while (scode == 0); switch(scode) { case 0x02: case 0x03: case 0x04: selected = scode - 1; break; case 0x05: if (max == 4) selected = scode -1 ; else scode = 0; break; case 0x48: selected -= 1; if (selected < 1) selected = 1; scode = 0; break; case 0x50: selected += 1; if (selected > max) selected = max; scode = 0; break; case 0x1c: break; default: scode = 0; break; } if (scode != 0) break; } switch (selected) { case 1: return 0x3D; case 2: return 0x3E; case 3: return 0x3F; case 4: return 0x58; default: return 0; }}void interactive_bootkey(){ Bit16u i; Bit8u scan = 0; bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\nPress F10 to select boot device.\n"); scan = wait(1, 0); if (scan == 0x44) scan = bootmenu(inb_cmos(0x3d) & 0x0f); /* set the default based on the keypress or menu */ switch(scan) { case 0x3D: outb_cmos(0x3d, 0x01); break; case 0x3E: outb_cmos(0x3d, 0x02); break; case 0x3F: outb_cmos(0x3d, 0x03); break; case 0x58: outb_cmos(0x3d, 0x04); break; default: break; }}voidnmi_handler_msg(){ BX_PANIC("NMI Handler called\n");}voidint18_panic_msg(){ BX_PANIC("INT18: BOOT FAILURE\n");}voidlog_bios_start(){#if BX_DEBUG_SERIAL outb(BX_DEBUG_PORT+UART_LCR, 0x03); /* setup for serial logging: 8N1 */#endif BX_INFO("%s\n", bios_version_string);} bx_boolset_enable_a20(val) bx_bool val;{ Bit8u oldval; // Use PS2 System Control port A to set A20 enable // get current setting first oldval = inb(0x92); // change A20 status if (val) outb(0x92, oldval | 0x02); else outb(0x92, oldval & 0xfd); return((oldval & 0x02) != 0);} voiddebugger_on(){ outb(0xfedc, 0x01);} voiddebugger_off(){ outb(0xfedc, 0x00);}void s3_resume(){ Bit32u s3_wakeup_vector; Bit16u s3_wakeup_ip, s3_wakeup_cs; Bit8u cmos_shutdown_status;ASM_START push ds push ax mov ax, #EBDA_SEG mov ds, ax mov al, [EBDA_CMOS_SHUTDOWN_STATUS_OFFSET] mov .s3_resume.cmos_shutdown_status[bp], al pop ax pop dsASM_END if (cmos_shutdown_status != CMOS_SHUTDOWN_S3) return; s3_wakeup_vector = get_s3_waking_vector(); if (!s3_wakeup_vector) return; s3_wakeup_ip = s3_wakeup_vector & 0xF; s3_wakeup_cs = s3_wakeup_vector >> 4;ASM_START push .s3_resume.s3_wakeup_cs[bp] push .s3_resume.s3_wakeup_ip[bp] retfASM_END}#if BX_USE_ATADRV// ---------------------------------------------------------------------------// Start of ATA/ATAPI Driver// ---------------------------------------------------------------------------// Global defines -- ATA register and register bits.// command block & control block regs#define ATA_CB_DATA 0 // data reg in/out pio_base_addr1+0#define ATA_CB_ERR 1 // error in pio_base_addr1+1#define ATA_CB_FR 1 // feature reg out pio_base_addr1+1#define ATA_CB_SC 2 // sector count in/out pio_base_addr1+2#define ATA_CB_SN 3 // sector number in/out pio_base_addr1+3#define ATA_CB_CL 4 // cylinder low in/out pio_base_addr1+4#define ATA_CB_CH 5 // cylinder high in/out pio_base_addr1+5#define ATA_CB_DH 6 // device head in/out pio_base_addr1+6#define ATA_CB_STAT 7 // primary status in pio_base_addr1+7#define ATA_CB_CMD 7 // command out pio_base_addr1+7#define ATA_CB_ASTAT 6 // alternate status in pio_base_addr2+6#define ATA_CB_DC 6 // device control out pio_base_addr2+6#define ATA_CB_DA 7 // device address in pio_base_addr2+7#define ATA_CB_ER_ICRC 0x80 // ATA Ultra DMA bad CRC#define ATA_CB_ER_BBK 0x80 // ATA bad block#define ATA_CB_ER_UNC 0x40 // ATA uncorrected error#define ATA_CB_ER_MC 0x20 // ATA media change#define ATA_CB_ER_IDNF 0x10 // ATA id not found#define ATA_CB_ER_MCR 0x08 // ATA media change request#define ATA_CB_ER_ABRT 0x04 // ATA command aborted#define ATA_CB_ER_NTK0 0x02 // ATA track 0 not found#define ATA_CB_ER_NDAM 0x01 // ATA address mark not found#define ATA_CB_ER_P_SNSKEY 0xf0 // ATAPI sense key (mask)#define ATA_CB_ER_P_MCR 0x08 // ATAPI Media Change Request#define ATA_CB_ER_P_ABRT 0x04 // ATAPI command abort#define ATA_CB_ER_P_EOM 0x02 // ATAPI End of Media#define ATA_CB_ER_P_ILI 0x01 // ATAPI Illegal Length Indication// ATAPI Interrupt Reason bits in the Sector Count reg (CB_SC)#define ATA_CB_SC_P_TAG 0xf8 // ATAPI tag (mask)#define ATA_CB_SC_P_REL 0x04 // ATAPI release#define ATA_CB_SC_P_IO 0x02 // ATAPI I/O#define ATA_CB_SC_P_CD 0x01 // ATAPI C/D// bits 7-4 of the device/head (CB_DH) reg#define ATA_CB_DH_DEV0 0xa0 // select device 0#define ATA_CB_DH_DEV1 0xb0 // select device 1// status reg (CB_STAT and CB_ASTAT) bits#define ATA_CB_STAT_BSY 0x80 // busy#define ATA_CB_STAT_RDY 0x40 // ready#define ATA_CB_STAT_DF 0x20 // device fault#define ATA_CB_STAT_WFT 0x20 // write fault (old name)#define ATA_CB_STAT_SKC 0x10 // seek complete#define ATA_CB_STAT_SERV 0x10 // service#define ATA_CB_STAT_DRQ 0x08 // data request#define ATA_CB_STAT_CORR 0x04 // corrected#define ATA_CB_STAT_IDX 0x02 // index#define ATA_CB_STAT_ERR 0x01 // error (ATA)#define ATA_CB_STAT_CHK 0x01 // check (ATAPI)// device control reg (CB_DC) bits#define ATA_CB_DC_HD15 0x08 // bit should always be set to one#define ATA_CB_DC_SRST 0x04 // soft reset#define ATA_CB_DC_NIEN 0x02 // disable interrupts// Most mandtory and optional ATA commands (from ATA-3),#define ATA_CMD_CFA_ERASE_SECTORS 0xC0#define ATA_CMD_CFA_REQUEST_EXT_ERR_CODE 0x03#define ATA_CMD_CFA_TRANSLATE_SECTOR 0x87#define ATA_CMD_CFA_WRITE_MULTIPLE_WO_ERASE 0xCD#define ATA_CMD_CFA_WRITE_SECTORS_WO_ERASE 0x38#define ATA_CMD_CHECK_POWER_MODE1 0xE5#define ATA_CMD_CHECK_POWER_MODE2 0x98#define ATA_CMD_DEVICE_RESET 0x08#define ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC 0x90#define ATA_CMD_FLUSH_CACHE 0xE7#define ATA_CMD_FORMAT_TRACK 0x50#define ATA_CMD_IDENTIFY_DEVICE 0xEC#define ATA_CMD_IDENTIFY_DEVICE_PACKET 0xA1#define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1#define ATA_CMD_IDLE1 0xE3#define ATA_CMD_IDLE2 0x97#define ATA_CMD_IDLE_IMMEDIATE1 0xE1#define ATA_CMD_IDLE_IMMEDIATE2 0x95#define ATA_CMD_INITIALIZE_DRIVE_PARAMETERS 0x91#define ATA_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91#define ATA_CMD_NOP 0x00#define ATA_CMD_PACKET 0xA0#define ATA_CMD_READ_BUFFER 0xE4#define ATA_CMD_READ_DMA 0xC8#define ATA_CMD_READ_DMA_QUEUED 0xC7#define ATA_CMD_READ_MULTIPLE 0xC4#define ATA_CMD_READ_SECTORS 0x20#define ATA_CMD_READ_VERIFY_SECTORS 0x40#define ATA_CMD_RECALIBRATE 0x10#define ATA_CMD_SEEK 0x70#define ATA_CMD_SET_FEATURES 0xEF#define ATA_CMD_SET_MULTIPLE_MODE 0xC6#define ATA_CMD_SLEEP1 0xE6#define ATA_CMD_SLEEP2 0x99#define ATA_CMD_STANDBY1 0xE2#define ATA_CMD_STANDBY2 0x96#define ATA_CMD_STANDBY_IMMEDIATE1 0xE0#define ATA_CMD_STANDBY_IMMEDIATE2 0x94#define ATA_CMD_WRITE_BUFFER 0xE8#define ATA_CMD_WRITE_DMA 0xCA#define ATA_CMD_WRITE_DMA_QUEUED 0xCC#define ATA_CMD_WRITE_MULTIPLE 0xC5#define ATA_CMD_WRITE_SECTORS 0x30#define ATA_CMD_WRITE_VERIFY 0x3C#define ATA_IFACE_NONE 0x00#define ATA_IFACE_ISA 0x00#define ATA_IFACE_PCI 0x01#define ATA_TYPE_NONE 0x00#define ATA_TYPE_UNKNOWN 0x01#define ATA_TYPE_ATA 0x02#define ATA_TYPE_ATAPI 0x03#define ATA_DEVICE_NONE 0x00#define ATA_DEVICE_HD 0xFF#define ATA_DEVICE_CDROM 0x05#define ATA_MODE_NONE 0x00#define ATA_MODE_PIO16 0x00#define ATA_MODE_PIO32 0x01#define ATA_MODE_ISADMA 0x02#define ATA_MODE_PCIDMA 0x03#define ATA_MODE_USEIRQ 0x10#define ATA_TRANSLATION_NONE 0#define ATA_TRANSLATION_LBA 1#define ATA_TRANSLATION_LARGE 2#define ATA_TRANSLATION_RECHS 3#define ATA_DATA_NO 0x00#define ATA_DATA_IN 0x01#define ATA_DATA_OUT 0x02 // ---------------------------------------------------------------------------// ATA/ATAPI driver : initialization// ---------------------------------------------------------------------------void ata_init( ){ Bit16u ebda_seg=read_word(0x0040,0x000E); Bit8u channel, device; // Channels info init. for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) { write_byte(ebda_seg,&EbdaData->ata.channels[channel].iface,ATA_IFACE_NONE); write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1,0x0); write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2,0x0); write_byte(ebda_seg,&EbdaData->ata.channels[channel].irq,0); } // Devices info init. for (device=0; device<BX_MAX_ATA_DEVICES; device++) { write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE); write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_NONE); write_byte(ebda_seg,&EbdaData->ata.devices[device].removable,0); write_byte(ebda_seg,&EbdaData->ata.devices[device].lock,0); write_byte(ebda_seg,&EbdaData->ata.devices[device].mode,ATA_MODE_NONE); write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0); write_byte(ebda_seg,&EbdaData->ata.devices[device].translation,ATA_TRANSLATION_NONE); write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads,0); write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders,0); write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt,0); write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors,0L); } // hdidmap and cdidmap init. for (device=0; device<BX_MAX_ATA_DEVICES; device++) { write_byte(ebda_seg,&EbdaData->ata.hdidmap[device],BX_MAX_ATA_DEVICES); write_byte(ebda_seg,&EbdaData->ata.cdidmap[device],BX_MAX_ATA_DEVICES); } write_byte(ebda_seg,&EbdaData->ata.hdcount,0); write_byte(ebda_seg,&EbdaData->ata.cdco
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -