+// -*- fundamental -*-
/////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c,v 1.1 2007/11/29 20:26:38 pdinda Exp $
+// $Id: rombios.c,v 1.9 2008/07/02 17:58:44 pdinda Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
// $f859 ; INT 15h System Services Entry Point
// $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters)
// $fe6e ; INT 1Ah Time-of-day Service Entry Point
-// $fea5 ; INT 08h System Timer ISR Entry Point
+/// $fea5 ; INT 08h System Timer ISR Entry Point
// $fef3 ; Initial Interrupt Vector Offsets Loaded by POST
// $ff53 ; IRET Instruction for Dummy Interrupt Handler
// $ff54 ; INT 05h Print Screen Service Entry Point
//
// BCC Bug: find a generic way to handle the bug of #asm after an "if" (fixed in 0.16.7)
-#define DEBUG_ROMBIOS 0
+#define DEBUG_ROMBIOS 1
#define DEBUG_ATA 0
#define DEBUG_INT13_HD 0
#endif // BX_ELTORITO_BOOT
-static char bios_cvs_version_string[] = "$Revision: 1.1 $";
-static char bios_date_string[] = "$Date: 2007/11/29 20:26:38 $";
+static char bios_cvs_version_string[] = "$Revision: 1.9 $";
+static char bios_date_string[] = "$Date: 2008/07/02 17:58:44 $";
-static char CVSID[] = "$Id: rombios.c,v 1.1 2007/11/29 20:26:38 pdinda Exp $";
+static char CVSID[] = "$Id: rombios.c,v 1.9 2008/07/02 17:58:44 pdinda Exp $";
/* Offset to skip the CVS $Id: prefix */
#define bios_version_string (CVSID + 4)
#define BIOS_PRINTF_INFO 4
#define BIOS_PRINTF_DEBUG 8
#define BIOS_PRINTF_ALL (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO)
-#define BIOS_PRINTF_DEBHALT (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT)
+#define BIOS_PRINTF_DEBHALT (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT)
#define printf(format, p...) bios_printf(BIOS_PRINTF_SCREEN, format, ##p)
// BX_DEBUG goes to INFO port until we can easily choose debug info on a
// per-device basis. Debug info are sent only in debug mode
#if DEBUG_ROMBIOS
-# define BX_DEBUG(format, p...) bios_printf(BIOS_PRINTF_INFO, format, ##p)
+# define BX_DEBUG(format, p...) bios_printf(BIOS_PRINTF_ALL, format, ##p)
#else
# define BX_DEBUG(format, p...)
#endif
}
// Bit16u
-//get_DS()
-//{
-//ASM_START
-// mov ax, ds
-//ASM_END
-//}
+get_DS()
+{
+ASM_START
+ mov ax, ds
+ASM_END
+}
+
//
// void
//set_DS(ds_selector)
Bit16u max;
int rc;
- printf("rombios: keyboard_init\n");
+ BX_DEBUG("rombios: keyboard_init\n");
/* printf("Assuming keyboard already inited and returning\n");
return; */
while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
/* flush incoming keys */
- max=0x2000;
+ // temporarily chaged for debug -PAD
+ // max=0x2000;
+ max=10;
while (--max > 0) {
- outb(0x80, 0x00);
+ outb(0x80, 0x01);
if (inb(0x64) & 0x01) {
inb(0x60);
max = 0x2000;
/* Wait until buffer is empty */
max=0xffff;
- while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
+ while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x02);
if (max==0x0) keyboard_panic(00);
/* Wait for data */
max=0xffff;
- while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x01);
+ while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x03);
if (max==0x0) keyboard_panic(01);
/* read self-test result, 0x55 should be returned from 0x60 */
Bit16u ebda_seg=read_word(0x0040,0x000E);
Bit8u channel, device;
- printf("rom_bios: ata_init\n");
+ //BX_DEBUG("rombios: ata_init\n");
// Channels info init.
for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) {
Bit8u hdcount, cdcount, device, type;
Bit8u buffer[0x0200];
+ //BX_DEBUG("rombios: ata_detect\n");
+
#if BX_MAX_ATA_INTERFACES > 0
write_byte(ebda_seg,&EbdaData->ata.channels[0].iface,ATA_IFACE_ISA);
write_word(ebda_seg,&EbdaData->ata.channels[0].iobase1,0x1f0);
write_word(ebda_seg, &EbdaData->ata.trsfsectors,0);
write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L);
+ // Device should not be busy yet
+
+#define PDINDA 1
+
+#if PDINDA
+ // wait for device to be ready
+ do {
+ status = inb(iobase1 + ATA_CB_STAT);
+ // BX_DEBUG_ATA("ata_cmd_packet: wait (%2x)\n",status);
+ } while (status & ATA_CB_STAT_BSY);
+#else
status = inb(iobase1 + ATA_CB_STAT);
if (status & ATA_CB_STAT_BSY) return 2;
+#endif
+
+ // set "noninterruptable"
outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
- // outb(iobase1 + ATA_CB_FR, 0x00);
- // outb(iobase1 + ATA_CB_SC, 0x00);
- // outb(iobase1 + ATA_CB_SN, 0x00);
+
+ //outb(iobase1 + ATA_CB_FR, 0x00);
+ //outb(iobase1 + ATA_CB_SC, 0x00);
+ //outb(iobase1 + ATA_CB_SN, 0x00);
+
+ // Set cylinders ?? - Why? And why not sector
+ // This is all embedded in cmd_packet, anyway...
outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
+
+ // select master or slave
outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
+
+ // Tell it we are sending a command packet
outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
+#if 0
+ // Now wait for 400 ns
+ {
+ int i;
+ for (i=0;i<0xffff; i++)
+ ;
+ }
+#endif
+
// Device should ok to receive command
+ // wait until we get
while (1) {
+
status = inb(iobase1 + ATA_CB_STAT);
+
+#if PDINDA
+ if (!(status & ATA_CB_STAT_BSY)) break;
+#else
+ // Shouldn't this be ATA_CB_STAT_RDY? -PAD - NO, it's OK
if ( !(status & ATA_CB_STAT_BSY) ) break;
- }
+#endif
+
+ }
if (status & ATA_CB_STAT_ERR) {
BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status);
return 3;
- } else if ( !(status & ATA_CB_STAT_DRQ) ) {
+ } else if ( !(status & ATA_CB_STAT_DRQ) ) {
BX_DEBUG_ATA("ata_cmd_packet : DRQ not set (status %02x)\n", (unsigned) status);
return 4;
- }
+ }
// Normalize address
cmdseg += (cmdoff / 16);
pop bp
ASM_END
+ // issue read of alternative status - claimed to be in spec
+ //inb(iobase2+ATA_CB_ASTAT);
+
+
if (inout == ATA_DATA_NO) {
status = inb(iobase1 + ATA_CB_STAT);
}
else {
- while (1) {
-
+ // Wait for completion
+ // PDINDA
+ do {
+ status=inb(iobase1+ATA_CB_STAT);
+ BX_DEBUG_ATA("ata_cmd_packet: wait (%2x)\n",status);
+ } while ((status & ATA_CB_STAT_BSY));
+
+ while (1) {
+
status = inb(iobase1 + ATA_CB_STAT);
-
+
// Check if command completed
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 ) break;
-
+
if (status & ATA_CB_STAT_ERR) {
BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
return 3;
}
-
+
+ // If we get here, we are ready and should have DRQ
+ // and so data is available
// Device must be ready to send data
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
- != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
- BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", status);
+ != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
+ BX_DEBUG_ATA("ata_cmd_packet 1: not ready (status %02x)\n", status);
return 4;
- }
-
+ }
+
// Normalize address
bufseg += (bufoff / 16);
bufoff %= 16;
-
+
// Get the byte count
lcount = ((Bit16u)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
-
+
// adjust to read what we want
if(header>lcount) {
- lbefore=lcount;
- header-=lcount;
- lcount=0;
- }
+ lbefore=lcount;
+ header-=lcount;
+ lcount=0;
+ }
else {
lbefore=header;
header=0;
lcount-=lbefore;
- }
-
+ }
+
if(lcount>length) {
lafter=lcount-length;
lcount=length;
length=0;
- }
+ }
else {
lafter=0;
length-=lcount;
- }
-
+ }
+
// Save byte count
count = lcount;
-
+
BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
BX_DEBUG_ATA("to 0x%04x:0x%04x\n",bufseg,bufoff);
// Final check, device must be ready
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= ATA_CB_STAT_RDY ) {
- BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", (unsigned) status);
+ BX_DEBUG_ATA("ata_cmd_packet 2 : not ready (status %02x)\n", (unsigned) status);
return 4;
}
// End of ATA/ATAPI Driver
// ---------------------------------------------------------------------------
+
// ---------------------------------------------------------------------------
// Start of ATA/ATAPI generic functions
// ---------------------------------------------------------------------------
{
Bit16u ebda_seg=read_word(0x0040,0x000E);
- printf("rombios: cdemu_init\n");
+ //BX_DEBUG("rombios: cdemu_init\n");
// the only important data is this one for now
write_byte(ebda_seg,&EbdaData->cdemu.active,0x00);
Bit16u boot_segment, nbsectors, i, error;
Bit8u device;
+
// Find out the first cdrom
for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
if (atapi_is_cdrom(device)) break;
if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
return 3;
+
// Validity checks
if(buffer[0]!=0)return 4;
for(i=0;i<5;i++){
atacmd[5]=(lba & 0x000000ff);
if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
return 7;
+
+
// Validation entry
if(buffer[0x00]!=0x01)return 8; // Header
if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0)
return 12;
+
// Remember the media type
switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
case 0x01: // 1.2M floppy
case 0x20: // coded by osmaker aka K.J.
if(regs.u.r32.edx == 0x534D4150) /* SMAP */
{
-#ifdef HVMASSIST
+#if defined(HVMASSIST) && 0
if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
+
Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
+ BX_DEBUG_INT15("OK bx=%x\n",regs.u.r16.bx);
+
if (regs.u.r16.bx + 0x14 <= e820_table_size) {
memcpyb(ES, regs.u.r16.di,
0xe000, 0x10 + regs.u.r16.bx, 0x14);
{
Bit8u drive_type;
+ // just tell it both drives exist - PAD
+ return 1;
+
// check CMOS to see if drive exists
drive_type = inb_cmos(0x10);
if (drive == 0)
Bit8u drive_type, num_floppies, ah;
Bit16u es, last_addr;
- BX_DEBUG_INT13_FL("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
- // BX_DEBUG_INT13_FL("int13_diskette: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), get_DS(), ES, DI, SI);
+
+ //printf("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
+ BX_DEBUG_INT13_FL("int13_diskette: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(),get_DS(), ES, DI, SI);
ah = GET_AH();
switch ( ah ) {
case 0x00: // diskette controller reset
-BX_DEBUG_INT13_FL("floppy f00\n");
+ BX_DEBUG_INT13_FL("floppy f00\n");
drive = GET_ELDL();
if (drive > 1) {
SET_AH(1); // invalid param
Bit16u bootseg;
Bit16u status;
Bit8u lastdrive=0;
+
+ // BX_DEBUG("rombios: int19 (%d)\n",bseqnr);
// if BX_ELTORITO_BOOT is not defined, old behavior
// check bit 5 in CMOS reg 0x2d. load either 0x00 or 0x80 into DL
if (bootcd != 0) {
status = cdrom_boot();
+ BX_DEBUG("CDBoot:%x\n",status);
+
+
// If failure
if ( (status & 0x00ff) !=0 ) {
print_cdromboot_failure(status);
print_boot_failure(bootcd, bootdrv, 1, lastdrive);
return 0x00000000;
- }
-
+ }
+
bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
bootdrv = (Bit8u)(status>>8);
- }
+ }
#endif // BX_ELTORITO_BOOT
if (bootcd == 0) {
bootseg=0x07c0;
+
+
ASM_START
push bp
mov bp, sp
pop bp
ASM_END
+
if (status != 0) {
print_boot_failure(bootcd, bootdrv, 1, lastdrive);
return 0x00000000;
#if BX_ELTORITO_BOOT
// Print out the boot string
+ BX_DEBUG("cdrom_boot: %x\n",status);
print_boot_device(bootcd, bootdrv);
#else // BX_ELTORITO_BOOT
print_boot_device(0, bootdrv);
#endif // BX_ELTORITO_BOOT
+ BX_DEBUG("boot to %x\n", (((Bit32u)bootdrv) << 16) + bootseg);
+
// return the boot segment
return (((Bit32u)bootdrv) << 16) + bootseg;
}
mov [bp], ax ;; set bp to zero
mov ax, #0xaa55 ;; set ok flag
+
pop bp
+
iret ;; Beam me up Scotty
;----------
mov ds, ax
mov 0x008E, #0xff
call eoi_both_pics
- pop ds
+ pop ds
pop ax
iret
jne rom_scan_increment
call rom_checksum
jnz rom_scan_increment
+
mov al, [2] ;; change increment to ROM length in 512-byte blocks
;; We want our increment in 512-byte quantities, rounded to
;; Video setup
SET_INT_VECTOR(0x10, #0xF000, #int10_handler)
+
+
;; PIC
mov al, #0x11 ; send initialisation commands
out 0x20, al
call rom_scan
+
+ ;; JRL CHANGE
+ ;;push ax
+ ;;push bx
+ ;;mov ah, #0x0e
+ ;;mov al, #0x41
+ ;;xor bx,bx
+ ;;int #0x10
+ ;;pop bx
+ ;;pop ax
+
+
+
call _print_bios_banner
;;