Index: bios/rombios.c =================================================================== RCS file: /cvsroot/bochs/bochs/bios/rombios.c,v retrieving revision 1.22 diff -u -r1.22 rombios.c --- bios/rombios.c 2001/11/18 16:40:26 1.22 +++ bios/rombios.c 2001/11/18 16:55:40 @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: rombios.c,v 1.22 2001/11/18 16:40:26 bdenney Exp $ +// $Id: rombios.c,v 1.21 2001/11/14 01:39:22 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -273,16 +273,28 @@ static void boot_failure_msg(); static void nmi_handler_msg(); static void print_bios_banner(); -static char bios_version_string[] = "BIOS Version is $Id: rombios.c,v 1.22 2001/11/18 16:40:26 bdenney Exp $"; +static char bios_cvs_version_string[] = "$Revision: 1.14 $"; +static char bios_date_string[] = "$Date: 2001/06/13 07:06:10 $"; + +static char CVSID[] = "$Id: rombios.c,v 1.14 2001/06/13 07:06:10 bdenney Exp $"; +/* Offset to skip the CVS $Id: prefix */ +#define bios_version_string (CVSID + 4) + +#define BIOS_PRINTF_HALT 1 +#define BIOS_PRINTF_SCREEN 2 +#define BIOS_PRINTF_DEBUG 4 +#define BIOS_PRINTF_ALL (BIOS_PRINTF_SCREEN | BIOS_PRINTF_DEBUG) +#define BIOS_PRINTF_DEBHALT (BIOS_PRINTF_SCREEN | BIOS_PRINTF_DEBUG | BIOS_PRINTF_HALT) + #define DEBUG_ROMBIOS 0 #if DEBUG_ROMBIOS -# define printf(format, p...) bios_printf(0, format, ##p) -# define panic(format, p...) bios_printf(1, format, ##p) +# define printf(format, p...) bios_printf(BIOS_PRINTF_DEBUG, format, ##p) +# define panic(format, p...) bios_printf(BIOS_PRINTF_DEBHALT, format, ##p) #else # define printf(format, p...) -# define panic(format, p...) bios_printf(1, format, ##p) +# define panic(format, p...) bios_printf(BIOS_PRINTF_DEBHALT, format, ##p) #endif @@ -607,6 +619,7 @@ write_byte(seg, offset, data) Bit16u seg; Bit16u offset; + Bit8u data; { #asm push bp @@ -755,19 +768,51 @@ #endasm } + void +wrch(c) + Bit8u c; +{ + #asm + push bp + mov bp, sp + + push bx + mov ah, #$0e + mov al, 4[bp] + xor bx,bx + int #$10 + pop bx + + pop bp + #endasm +} + + void +send(action, c) + Bit16u action; + Bit8u c; +{ + if (action & BIOS_PRINTF_DEBUG) outb(0xfff0, c); + if (action & BIOS_PRINTF_SCREEN) { + if (c == '\n') wrch('\r'); + wrch(c); + } +} + void -put_int(val, width, neg) +put_int(action, val, width, neg) + Bit16u action; short val, width; Boolean neg; { short nval = UDIV16(val, 10); if (nval) - put_int(nval, width - 1, neg); + put_int(action, nval, width - 1, neg); else { - while (--width > 0) outb(0xfff0, ' '); - if (neg) outb(0xfff0, '-'); + while (--width > 0) send(action, ' '); + if (neg) send(action, '-'); } - outb(0xfff0, val - (nval * 10) + '0'); + send(action, val - (nval * 10) + '0'); } //-------------------------------------------------------------------------- @@ -775,10 +820,13 @@ // A compact variable argument printf function which prints its output via // an I/O port so that it can be logged by Bochs. Currently, only %x is // supported (or %02x, %04x, etc). +// +// Supports %[format_width][format] +// where format can be d,x,c,s //-------------------------------------------------------------------------- void -bios_printf(bomb, s) - Boolean bomb; +bios_printf(action, s) + Bit16u action; Bit8u *s; { Bit8u c, format_char; @@ -793,6 +841,10 @@ in_format = 0; format_width = 0; + if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) { + bios_printf (BIOS_PRINTF_ALL, "FATAL: "); + } + while (c = read_byte(0xf000, s)) { if ( c == '%' ) { in_format = 1; @@ -802,39 +854,48 @@ if ( (c>='0') && (c<='9') ) { format_width = (format_width * 10) + (c - '0'); } - else if (c == 'x') { + else { arg_ptr++; // increment to next arg arg = read_word(arg_seg, arg_ptr); - if (format_width == 0) - format_width = 4; - for (i=format_width-1; i>=0; i--) { - nibble = (arg >> (4 * i)) & 0x000f; - if (nibble <= 9) - outb(0xfff0, nibble + '0'); + if (c == 'x') { + if (format_width == 0) + format_width = 4; + for (i=format_width-1; i>=0; i--) { + nibble = (arg >> (4 * i)) & 0x000f; + send (action, (nibble<=9)? (nibble+'0') : (nibble-10+'A')); + } + } + else if (c == 'd') { + if (arg & 0x8000) + put_int(action, -arg, format_width - 1, 1); else - outb(0xfff0, (nibble - 10) + 'A'); + put_int(action, arg, format_width, 0); } - in_format = 0; - } - else if (c == 'd') { - arg_ptr++; // increment to next arg - arg = read_word(arg_seg, arg_ptr); - if (arg & 0x8000) - put_int(-arg, format_width - 1, 1); + else if (c == 's') { + bios_printf(action & (~BIOS_PRINTF_HALT), arg); + } + else if (c == 'c') { + send(action, arg); + } else - put_int(arg, format_width, 0); - in_format = 0; + panic("bios_printf: unknown format"); + in_format = 0; } - else - panic("bios_printf: unknown format"); } else { - outb(0xfff0, c); + send(action, c); } s ++; } - if (bomb) { + if (action & BIOS_PRINTF_HALT) { + // freeze in a busy loop. If I do a HLT instruction, then in versions + // 1.3.pre1 and earlier, it will panic without ever updating the VGA + // display, so the panic message will not be visible. By waiting + // forever, you are certain to see the panic message on screen. + // After a few more versions have passed, we can turn this back into + // a halt or something. + do {} while (1); #asm HALT2(__LINE__) #endasm @@ -855,32 +916,51 @@ panic("Keyboard RESET error"); } +/* +This is called when the boot fails to print an appropriate message. +If bit 16 is 0, the disk was not readable. +If bit 16 is 1, the disk was readable but didn't have the boot signature. +If bit 15 is 0, it tried to boot a floppy disk. +If bit 15 is 1, it tried to boot a hard disk. +Bits 14-0 are the drive number, usually just a 0 or 1. +*/ void boot_failure_msg(drive) Bit16u drive; { - if (drive < 0x80) { - bios_printf(0, "Booting from floppy drive %d.\n", drive); - } else { - bios_printf(0, "Booting from hard drive %d.\n", drive & 0x7f); - } + Bit16u drivenum = drive&0x7f; + //bios_printf(BIOS_PRINTF_SCREEN, "boot_failure_msg(%x)\n", drive); + if (drive & 0x80) + bios_printf(BIOS_PRINTF_DEBUG | BIOS_PRINTF_SCREEN, "Boot from hard disk %d failed\n", drivenum); + else + bios_printf(BIOS_PRINTF_DEBUG | BIOS_PRINTF_SCREEN, "Boot from floppy disk %d failed\n", drivenum); if (drive & 0x100) - panic("Not a bootable disk"); + panic("Not a bootable disk\n"); else - panic("Could not read the boot disk"); + panic("Could not read the boot disk\n"); } void nmi_handler_msg() +{ + bios_printf(BIOS_PRINTF_DEBUG, "NMI Handler called\n"); +} + +void +log_bios_start() { - bios_printf(0, "NMI Handler called\n"); + bios_printf(BIOS_PRINTF_DEBUG, "%s\n", bios_version_string); } void print_bios_banner() { - bios_printf(0, bios_version_string); - bios_printf(0, "\n"); + bios_printf(BIOS_PRINTF_SCREEN, "Bochs BIOS, %s %s\n\n", + bios_cvs_version_string, bios_date_string); + /* + bios_printf(BIOS_PRINTF_SCREEN, "Test: x234=%3x, d-123=%d, c=%c, s=%s\n", + 0x1234, -123, '!', "ok"); + */ } @@ -1896,6 +1976,9 @@ if ( (num_sectors > 128) || (num_sectors == 0) ) panic("int13_function(): num_sectors out of range!"); + if (head > 15) + panic("hard drive BIOS:(read/verify) head > 15\n"); + if ( GET_AH() == 0x04 ) { SET_AH(0); set_disk_ret_status(0); @@ -2039,6 +2122,9 @@ if ( (num_sectors > 128) || (num_sectors == 0) ) panic("int13_function(): num_sectors out of range!"); + if (head > 15) + panic("hard drive BIOS:(read) head > 15\n"); + status = inb(0x1f7); if (status & 0x80) { panic("hard drive BIOS:(read) BUSY bit set"); @@ -3617,8 +3703,7 @@ ;; if dh=0, load failed. if dh=1, signature check failed. push dx call _boot_failure_msg - int #0x18 ;; Boot failure - iret + hlt ;---------- ;- INT18h - @@ -4174,6 +4259,8 @@ mov ds, ax mov ss, ax + call _log_bios_start + ;; zero out BIOS data area (40:00..40:ff) mov es, ax mov cx, #0x0080 ;; 128 words @@ -4230,6 +4317,7 @@ ;; System Services SET_INT_VECTOR(0x15, #0xF000, #int15_handler) + mov ax, #0x0000 ; mov EBDA seg into 40E mov ds, ax mov 0x40E, #EBDA_SEG @@ -4387,6 +4475,8 @@ out 0x21, AL ;master pic: all IRQs unmasked out 0xA1, AL ;slave pic: all IRQs unmasked + call _print_bios_banner + ;; ;; Hard Drive setup ;; @@ -4396,8 +4486,6 @@ ;; Floppy setup ;; call floppy_drive_post - - call _print_bios_banner int #0x19 //JMP_EP(0x0064) ; INT 19h location