rombios.c

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////
00002 // $Id: rombios.c,v 1.163 2006/07/07 16:10:37 vruppert Exp $
00003 /////////////////////////////////////////////////////////////////////////
00004 //
00005 //  Copyright (C) 2002  MandrakeSoft S.A.
00006 //
00007 //    MandrakeSoft S.A.
00008 //    43, rue d'Aboukir
00009 //    75002 Paris - France
00010 //    http://www.linux-mandrake.com/
00011 //    http://www.mandrakesoft.com/
00012 //
00013 //  This library is free software; you can redistribute it and/or
00014 //  modify it under the terms of the GNU Lesser General Public
00015 //  License as published by the Free Software Foundation; either
00016 //  version 2 of the License, or (at your option) any later version.
00017 //
00018 //  This library is distributed in the hope that it will be useful,
00019 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021 //  Lesser General Public License for more details.
00022 //
00023 //  You should have received a copy of the GNU Lesser General Public
00024 //  License along with this library; if not, write to the Free Software
00025 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
00026 
00027 // ROM BIOS for use with Bochs/Plex x86 emulation environment
00028 
00029 
00030 // ROM BIOS compatability entry points:
00031 // ===================================
00032 // $e05b ; POST Entry Point
00033 // $e2c3 ; NMI Handler Entry Point
00034 // $e3fe ; INT 13h Fixed Disk Services Entry Point
00035 // $e401 ; Fixed Disk Parameter Table
00036 // $e6f2 ; INT 19h Boot Load Service Entry Point
00037 // $e6f5 ; Configuration Data Table
00038 // $e729 ; Baud Rate Generator Table
00039 // $e739 ; INT 14h Serial Communications Service Entry Point
00040 // $e82e ; INT 16h Keyboard Service Entry Point
00041 // $e987 ; INT 09h Keyboard Service Entry Point
00042 // $ec59 ; INT 13h Diskette Service Entry Point
00043 // $ef57 ; INT 0Eh Diskette Hardware ISR Entry Point
00044 // $efc7 ; Diskette Controller Parameter Table
00045 // $efd2 ; INT 17h Printer Service Entry Point
00046 // $f045 ; INT 10 Functions 0-Fh Entry Point
00047 // $f065 ; INT 10h Video Support Service Entry Point
00048 // $f0a4 ; MDA/CGA Video Parameter Table (INT 1Dh)
00049 // $f841 ; INT 12h Memory Size Service Entry Point
00050 // $f84d ; INT 11h Equipment List Service Entry Point
00051 // $f859 ; INT 15h System Services Entry Point
00052 // $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters)
00053 // $fe6e ; INT 1Ah Time-of-day Service Entry Point
00054 // $fea5 ; INT 08h System Timer ISR Entry Point
00055 // $fef3 ; Initial Interrupt Vector Offsets Loaded by POST
00056 // $ff53 ; IRET Instruction for Dummy Interrupt Handler
00057 // $ff54 ; INT 05h Print Screen Service Entry Point
00058 // $fff0 ; Power-up Entry Point
00059 // $fff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
00060 // $fffe ; System Model ID
00061 
00062 // NOTES for ATA/ATAPI driver (cbbochs@free.fr)
00063 //   Features
00064 //     - supports up to 4 ATA interfaces
00065 //     - device/geometry detection
00066 //     - 16bits/32bits device access
00067 //     - pchs/lba access
00068 //     - datain/dataout/packet command support
00069 //
00070 // NOTES for El-Torito Boot (cbbochs@free.fr)
00071 //   - CD-ROM booting is only available if ATA/ATAPI Driver is available
00072 //   - Current code is only able to boot mono-session cds 
00073 //   - Current code can not boot and emulate a hard-disk
00074 //     the bios will panic otherwise
00075 //   - Current code also use memory in EBDA segement. 
00076 //   - I used cmos byte 0x3D to store extended information on boot-device
00077 //   - Code has to be modified modified to handle multiple cdrom drives
00078 //   - Here are the cdrom boot failure codes:
00079 //       1 : no atapi device found
00080 //       2 : no atapi cdrom found
00081 //       3 : can not read cd - BRVD
00082 //       4 : cd is not eltorito (BRVD)
00083 //       5 : cd is not eltorito (ISO TAG)
00084 //       6 : cd is not eltorito (ELTORITO TAG)
00085 //       7 : can not read cd - boot catalog
00086 //       8 : boot catalog : bad header
00087 //       9 : boot catalog : bad platform
00088 //      10 : boot catalog : bad signature
00089 //      11 : boot catalog : bootable flag not set
00090 //      12 : can not read cd - boot image
00091 //
00092 //   ATA driver
00093 //   - EBDA segment. 
00094 //     I used memory starting at 0x121 in the segment
00095 //   - the translation policy is defined in cmos regs 0x39 & 0x3a
00096 //
00097 // TODO :
00098 //
00099 //   int74 
00100 //     - needs to be reworked.  Uses direct [bp] offsets. (?)
00101 //
00102 //   int13:
00103 //     - f04 (verify sectors) isn't complete  (?)
00104 //     - f02/03/04 should set current cyl,etc in BDA  (?)
00105 //     - rewrite int13_relocated & clean up int13 entry code
00106 //
00107 //   NOTES:
00108 //   - NMI access (bit7 of addr written to 70h)
00109 //
00110 //   ATA driver
00111 //   - should handle the "don't detect" bit (cmos regs 0x3b & 0x3c)
00112 //   - could send the multiple-sector read/write commands
00113 //
00114 //   El-Torito
00115 //   - Emulate a Hard-disk (currently only diskette can be emulated) see "FIXME ElTorito Harddisk"
00116 //   - Implement remaining int13_cdemu functions (as defined by El-Torito specs)
00117 //   - cdrom drive is hardcoded to ide 0 device 1 in several places. see "FIXME ElTorito Hardcoded"
00118 //   - int13 Fix DL when emulating a cd. In that case DL is decremented before calling real int13.
00119 //     This is ok. But DL should be reincremented afterwards. 
00120 //   - Fix all "FIXME ElTorito Various"
00121 //   - should be able to boot any cdrom instead of the first one
00122 //
00123 //   BCC Bug: find a generic way to handle the bug of #asm after an "if"  (fixed in 0.16.7)
00124 
00125 #define DEBUG_ROMBIOS      1
00126 
00127 #define DEBUG_ATA          0
00128 #define DEBUG_INT13_HD     0
00129 #define DEBUG_INT13_CD     0
00130 #define DEBUG_INT13_ET     0
00131 #define DEBUG_INT13_FL     0
00132 #define DEBUG_INT15        0
00133 #define DEBUG_INT16        0
00134 #define DEBUG_INT1A        0
00135 #define DEBUG_INT74        0
00136 #define DEBUG_APM          0
00137 
00138 #define BX_CPU           3
00139 #define BX_USE_PS2_MOUSE 1
00140 #define BX_CALL_INT15_4F 1
00141 #define BX_USE_EBDA      1
00142 #define BX_SUPPORT_FLOPPY 1
00143 #define BX_FLOPPY_ON_CNT 37   /* 2 seconds */
00144 //#define BX_PCIBIOS       1
00145 #define BX_APM           0
00146 
00147 #define COREBOOT        1
00148 
00149 #define BX_USE_ATADRV    1
00150 //#define BX_ELTORITO_BOOT 1
00151 
00152 #define BX_MAX_ATA_INTERFACES   4
00153 #define BX_MAX_ATA_DEVICES      (BX_MAX_ATA_INTERFACES*2)
00154 
00155 #define BX_VIRTUAL_PORTS 1 /* normal output to Bochs ports */
00156 #define BX_DEBUG_SERIAL  1 /* output to COM1 */
00157 
00158    /* model byte 0xFC = AT */
00159 #define SYS_MODEL_ID     0xFC
00160 #define SYS_SUBMODEL_ID  0x00
00161 #define BIOS_REVISION    1
00162 #define BIOS_CONFIG_TABLE 0xe6f5
00163 
00164 #ifndef BIOS_BUILD_DATE
00165 #  define BIOS_BUILD_DATE "06/23/99"
00166 #endif
00167 
00168   // 1K of base memory used for Extended Bios Data Area (EBDA)
00169   // EBDA is used for PS/2 mouse support, and IDE BIOS, etc.
00170 #define EBDA_SEG           0x9FC0
00171 #define EBDA_SIZE          1              // In KiB
00172 #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
00173 
00174   // Define the application NAME
00175 #ifdef PLEX86
00176 #  define BX_APPNAME "Plex86"
00177 #else
00178 #  define BX_APPNAME "Bochs"
00179 #endif
00180 
00181   // Sanity Checks
00182 #if BX_USE_ATADRV && BX_CPU<3
00183 #    error The ATA/ATAPI Driver can only to be used with a 386+ cpu
00184 #endif
00185 #if BX_USE_ATADRV && !BX_USE_EBDA
00186 #    error ATA/ATAPI Driver can only be used if EBDA is available
00187 #endif
00188 #if BX_ELTORITO_BOOT && !BX_USE_ATADRV
00189 #    error El-Torito Boot can only be use if ATA/ATAPI Driver is available
00190 #endif
00191 #if BX_PCIBIOS && BX_CPU<3
00192 #    error PCI BIOS can only be used with 386+ cpu
00193 #endif
00194 #if BX_APM && BX_CPU<3
00195 #    error APM BIOS can only be used with 386+ cpu
00196 #endif
00197 
00198 #define PANIC_PORT  0x400
00199 #define PANIC_PORT2 0x401
00200 #define INFO_PORT   0x402
00201 #define DEBUG_PORT  0x403
00202 
00203 // define this if you want to make PCIBIOS working on a specific bridge only
00204 // undef enables PCIBIOS when at least one PCI device is found
00205 // i440FX is emulated by Bochs and QEMU
00206 #define PCI_FIXED_HOST_BRIDGE 0x12378086 ;; i440FX PCI bridge
00207 
00208 // #20  is dec 20
00209 // #$20 is hex 20 = 32
00210 // #0x20 is hex 20 = 32
00211 // LDA  #$20
00212 // JSR  $E820
00213 // LDD  .i,S
00214 // JSR  $C682
00215 // mov al, #$20
00216 
00217 // all hex literals should be prefixed with '0x'
00218 //   grep "#[0-9a-fA-F][0-9a-fA-F]" rombios.c
00219 // no mov SEG-REG, #value, must mov register into seg-reg
00220 //   grep -i "mov[ ]*.s" rombios.c
00221 
00222 // This is for compiling with gcc2 and gcc3
00223 #define ASM_START #asm
00224 #define ASM_END #endasm
00225 
00226 ASM_START
00227 .rom
00228 
00229 .org 0x0000
00230 
00231 #if BX_CPU >= 3
00232 use16 386
00233 #else
00234 use16 286
00235 #endif
00236 
00237 MACRO HALT
00238   ;; the HALT macro is called with the line number of the HALT call.
00239   ;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex 
00240   ;; to print a BX_PANIC message.  This will normally halt the simulation
00241   ;; with a message such as "BIOS panic at rombios.c, line 4091".
00242   ;; However, users can choose to make panics non-fatal and continue.
00243 #if BX_VIRTUAL_PORTS
00244   mov dx,#PANIC_PORT
00245   mov ax,#?1
00246   out dx,ax
00247 #else
00248   mov dx,#0x80
00249   mov ax,#?1
00250   out dx,al
00251 #endif
00252 MEND
00253 
00254 MACRO JMP_AP
00255   db 0xea
00256   dw ?2
00257   dw ?1
00258 MEND
00259 
00260 MACRO SET_INT_VECTOR
00261   mov ax, ?3
00262   mov ?1*4, ax
00263   mov ax, ?2
00264   mov ?1*4+2, ax
00265 MEND
00266 
00267 ASM_END
00268 
00269 typedef unsigned char  Bit8u;
00270 typedef unsigned short Bit16u;
00271 typedef unsigned short bx_bool;
00272 typedef unsigned long  Bit32u;
00273 
00274 #if BX_USE_ATADRV
00275 
00276   void memsetb(seg,offset,value,count);
00277   void memcpyb(dseg,doffset,sseg,soffset,count);
00278   void memcpyd(dseg,doffset,sseg,soffset,count);
00279   
00280   // memset of count bytes
00281     void 
00282   memsetb(seg,offset,value,count)
00283     Bit16u seg;
00284     Bit16u offset;
00285     Bit16u value;
00286     Bit16u count;
00287   {
00288   ASM_START
00289     push bp
00290     mov  bp, sp
00291   
00292       push ax
00293       push cx
00294       push es
00295       push di
00296   
00297       mov  cx, 10[bp] ; count
00298       cmp  cx, #0x00
00299       je   memsetb_end
00300       mov  ax, 4[bp] ; segment
00301       mov  es, ax
00302       mov  ax, 6[bp] ; offset
00303       mov  di, ax
00304       mov  al, 8[bp] ; value
00305       cld
00306       rep
00307        stosb
00308   
00309   memsetb_end:
00310       pop di
00311       pop es
00312       pop cx
00313       pop ax
00314   
00315     pop bp
00316   ASM_END
00317   }
00318   
00319 #if 0 
00320   // memcpy of count bytes
00321     void 
00322   memcpyb(dseg,doffset,sseg,soffset,count)
00323     Bit16u dseg;
00324     Bit16u doffset;
00325     Bit16u sseg;
00326     Bit16u soffset;
00327     Bit16u count;
00328   {
00329   ASM_START
00330     push bp
00331     mov  bp, sp
00332   
00333       push ax
00334       push cx
00335       push es
00336       push di
00337       push ds
00338       push si
00339   
00340       mov  cx, 12[bp] ; count
00341       cmp  cx, #0x0000
00342       je   memcpyb_end
00343       mov  ax, 4[bp] ; dsegment
00344       mov  es, ax
00345       mov  ax, 6[bp] ; doffset
00346       mov  di, ax
00347       mov  ax, 8[bp] ; ssegment
00348       mov  ds, ax
00349       mov  ax, 10[bp] ; soffset
00350       mov  si, ax
00351       cld
00352       rep
00353        movsb
00354   
00355   memcpyb_end:
00356       pop si
00357       pop ds
00358       pop di
00359       pop es
00360       pop cx
00361       pop ax
00362   
00363     pop bp
00364   ASM_END
00365   }
00366 
00367   // memcpy of count dword
00368     void 
00369   memcpyd(dseg,doffset,sseg,soffset,count)
00370     Bit16u dseg;
00371     Bit16u doffset;
00372     Bit16u sseg;
00373     Bit16u soffset;
00374     Bit16u count;
00375   {
00376   ASM_START
00377     push bp
00378     mov  bp, sp
00379   
00380       push ax
00381       push cx
00382       push es
00383       push di
00384       push ds
00385       push si
00386   
00387       mov  cx, 12[bp] ; count
00388       cmp  cx, #0x0000
00389       je   memcpyd_end
00390       mov  ax, 4[bp] ; dsegment
00391       mov  es, ax
00392       mov  ax, 6[bp] ; doffset
00393       mov  di, ax
00394       mov  ax, 8[bp] ; ssegment
00395       mov  ds, ax
00396       mov  ax, 10[bp] ; soffset
00397       mov  si, ax
00398       cld
00399       rep
00400        movsd
00401   
00402   memcpyd_end:
00403       pop si
00404       pop ds
00405       pop di
00406       pop es
00407       pop cx
00408       pop ax
00409   
00410     pop bp
00411   ASM_END
00412   }
00413 #endif
00414 #endif //BX_USE_ATADRV
00415 
00416   // read_dword and write_dword functions
00417   static Bit32u         read_dword();
00418   static void           write_dword();
00419   
00420     Bit32u
00421   read_dword(seg, offset)
00422     Bit16u seg;
00423     Bit16u offset;
00424   {
00425   ASM_START
00426     push bp
00427     mov  bp, sp
00428   
00429       push bx
00430       push ds
00431       mov  ax, 4[bp] ; segment
00432       mov  ds, ax
00433       mov  bx, 6[bp] ; offset
00434       mov  ax, [bx]
00435       inc  bx
00436       inc  bx
00437       mov  dx, [bx]
00438       ;; ax = return value (word)
00439       ;; dx = return value (word)
00440       pop  ds
00441       pop  bx
00442   
00443     pop  bp
00444   ASM_END
00445   }
00446   
00447     void
00448   write_dword(seg, offset, data)
00449     Bit16u seg;
00450     Bit16u offset;
00451     Bit32u data;
00452   {
00453   ASM_START
00454     push bp
00455     mov  bp, sp
00456   
00457       push ax
00458       push bx
00459       push ds
00460       mov  ax, 4[bp] ; segment
00461       mov  ds, ax
00462       mov  bx, 6[bp] ; offset
00463       mov  ax, 8[bp] ; data word
00464       mov  [bx], ax  ; write data word
00465       inc  bx
00466       inc  bx
00467       mov  ax, 10[bp] ; data word
00468       mov  [bx], ax  ; write data word
00469       pop  ds
00470       pop  bx
00471       pop  ax
00472   
00473     pop  bp
00474   ASM_END
00475   }
00476   
00477   // Bit32u (unsigned long) and long helper functions
00478   ASM_START
00479   
00480   ;; and function
00481   landl:
00482   landul:
00483     SEG SS 
00484       and ax,[di]
00485     SEG SS 
00486       and bx,2[di]
00487     ret
00488   
00489   ;; add function
00490   laddl:
00491   laddul:
00492     SEG SS 
00493       add ax,[di]
00494     SEG SS 
00495       adc bx,2[di]
00496     ret
00497   
00498   ;; cmp function
00499   lcmpl:
00500   lcmpul:
00501     and eax, #0x0000FFFF
00502     shl ebx, #16
00503     add eax, ebx
00504     shr ebx, #16
00505     SEG SS
00506       cmp eax, dword ptr [di]
00507     ret
00508   
00509   ;; sub function
00510   lsubl:
00511   lsubul:
00512     SEG SS
00513     sub ax,[di]
00514     SEG SS
00515     sbb bx,2[di]
00516     ret
00517   
00518   ;; mul function
00519   lmull:
00520   lmulul:
00521     and eax, #0x0000FFFF
00522     shl ebx, #16
00523     add eax, ebx
00524     SEG SS
00525     mul eax, dword ptr [di]
00526     mov ebx, eax
00527     shr ebx, #16
00528     ret
00529   
00530   ;; dec function
00531   ldecl:
00532   ldecul:
00533     SEG SS
00534     dec dword ptr [bx]
00535     ret
00536   
00537   ;; or function
00538   lorl:
00539   lorul:
00540     SEG SS
00541     or  ax,[di]
00542     SEG SS
00543     or  bx,2[di]
00544     ret
00545   
00546   ;; inc function
00547   lincl:
00548   lincul:
00549     SEG SS
00550     inc dword ptr [bx]
00551     ret
00552   
00553   ;; tst function
00554   ltstl:
00555   ltstul:
00556     and eax, #0x0000FFFF
00557     shl ebx, #16
00558     add eax, ebx
00559     shr ebx, #16
00560     test eax, eax
00561     ret
00562   
00563   ;; sr function
00564   lsrul:
00565     mov  cx,di
00566     jcxz lsr_exit
00567     and  eax, #0x0000FFFF
00568     shl  ebx, #16
00569     add  eax, ebx
00570   lsr_loop:
00571     shr  eax, #1
00572     loop lsr_loop
00573     mov  ebx, eax
00574     shr  ebx, #16
00575   lsr_exit:
00576     ret
00577   
00578   ;; sl function
00579   lsll:
00580   lslul:
00581     mov  cx,di
00582     jcxz lsl_exit
00583     and  eax, #0x0000FFFF
00584     shl  ebx, #16
00585     add  eax, ebx
00586   lsl_loop: 
00587     shl  eax, #1
00588     loop lsl_loop
00589     mov  ebx, eax
00590     shr  ebx, #16
00591   lsl_exit:
00592     ret
00593   
00594   idiv_:
00595     cwd
00596     idiv bx
00597     ret
00598 
00599   idiv_u:
00600     xor dx,dx
00601     div bx
00602     ret
00603 
00604   ldivul:
00605     and  eax, #0x0000FFFF
00606     shl  ebx, #16
00607     add  eax, ebx
00608     xor  edx, edx
00609     SEG SS
00610     mov  bx,  2[di]
00611     shl  ebx, #16
00612     SEG SS
00613     mov  bx,  [di]
00614     div  ebx
00615     mov  ebx, eax
00616     shr  ebx, #16
00617     ret
00618 
00619   ASM_END
00620 
00621 // for access to RAM area which is used by interrupt vectors
00622 // and BIOS Data Area
00623 
00624 typedef struct {
00625   unsigned char filler1[0x400];
00626   unsigned char filler2[0x6c];
00627   Bit16u ticks_low;
00628   Bit16u ticks_high;
00629   Bit8u  midnight_flag;
00630   } bios_data_t;
00631 
00632 #define BiosData ((bios_data_t  *) 0)
00633 
00634 #if BX_USE_ATADRV
00635   typedef struct {
00636     Bit16u heads;      // # heads
00637     Bit16u cylinders;  // # cylinders
00638     Bit16u spt;        // # sectors / track
00639     } chs_t;
00640 
00641   // DPTE definition
00642   typedef struct {
00643     Bit16u iobase1;
00644     Bit16u iobase2;
00645     Bit8u  prefix;
00646     Bit8u  unused;
00647     Bit8u  irq;
00648     Bit8u  blkcount;
00649     Bit8u  dma;
00650     Bit8u  pio;
00651     Bit16u options;
00652     Bit16u reserved;
00653     Bit8u  revision;
00654     Bit8u  checksum;
00655     } dpte_t;
00656  
00657   typedef struct {
00658     Bit8u  iface;        // ISA or PCI
00659     Bit16u iobase1;      // IO Base 1
00660     Bit16u iobase2;      // IO Base 2
00661     Bit8u  irq;          // IRQ
00662     } ata_channel_t;
00663 
00664   typedef struct {
00665     Bit8u  type;         // Detected type of ata (ata/atapi/none/unknown)
00666     Bit8u  device;       // Detected type of attached devices (hd/cd/none)
00667     Bit8u  removable;    // Removable device flag
00668     Bit8u  lock;         // Locks for removable devices
00669     // Bit8u  lba_capable;  // LBA capable flag - always yes for bochs devices
00670     Bit8u  mode;         // transfert mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
00671     Bit16u blksize;      // block size
00672 
00673     Bit8u  translation;  // type of translation
00674     chs_t  lchs;         // Logical CHS
00675     chs_t  pchs;         // Physical CHS
00676 
00677     Bit32u sectors;      // Total sectors count
00678     } ata_device_t;
00679 
00680   typedef struct {
00681     // ATA channels info
00682     ata_channel_t channels[BX_MAX_ATA_INTERFACES];
00683 
00684     // ATA devices info
00685     ata_device_t  devices[BX_MAX_ATA_DEVICES];
00686     //
00687     // map between (bios hd id - 0x80) and ata channels
00688     Bit8u  hdcount, hdidmap[BX_MAX_ATA_DEVICES];                
00689 
00690     // map between (bios cd id - 0xE0) and ata channels
00691     Bit8u  cdcount, cdidmap[BX_MAX_ATA_DEVICES];                
00692 
00693     // Buffer for DPTE table
00694     dpte_t dpte;
00695 
00696     // Count of transferred sectors and bytes
00697     Bit16u trsfsectors;
00698     Bit32u trsfbytes;
00699 
00700     } ata_t;
00701   
00702 #if BX_ELTORITO_BOOT
00703   // ElTorito Device Emulation data 
00704   typedef struct {
00705     Bit8u  active;
00706     Bit8u  media;
00707     Bit8u  emulated_drive;
00708     Bit8u  controller_index;
00709     Bit16u device_spec;
00710     Bit32u ilba;
00711     Bit16u buffer_segment;
00712     Bit16u load_segment;
00713     Bit16u sector_count;
00714     
00715     // Virtual device
00716     chs_t  vdevice;
00717     } cdemu_t;
00718 #endif // BX_ELTORITO_BOOT
00719   
00720   // for access to EBDA area
00721   //     The EBDA structure should conform to 
00722   //     http://www.frontiernet.net/~fys/rombios.htm document
00723   //     I made the ata and cdemu structs begin at 0x121 in the EBDA seg
00724   typedef struct {
00725     unsigned char filler1[0x3D];
00726 
00727     // FDPT - Can be splitted in data members if needed
00728     unsigned char fdpt0[0x10];
00729     unsigned char fdpt1[0x10];
00730 
00731     unsigned char filler2[0xC4];
00732 
00733     // ATA Driver data
00734     ata_t   ata;
00735 
00736 #if BX_ELTORITO_BOOT
00737     // El Torito Emulation data
00738     cdemu_t cdemu;
00739 #endif // BX_ELTORITO_BOOT
00740 
00741     } ebda_data_t;
00742   
00743   #define EbdaData ((ebda_data_t *) 0)
00744 
00745   // for access to the int13ext structure
00746   typedef struct {
00747     Bit8u  size;
00748     Bit8u  reserved;
00749     Bit16u count;
00750     Bit16u offset;
00751     Bit16u segment;
00752     Bit32u lba1;
00753     Bit32u lba2;
00754     } int13ext_t;
00755  
00756   #define Int13Ext ((int13ext_t *) 0)
00757 
00758   // Disk Physical Table definition
00759   typedef struct {
00760     Bit16u  size;
00761     Bit16u  infos;
00762     Bit32u  cylinders;
00763     Bit32u  heads;
00764     Bit32u  spt;
00765     Bit32u  sector_count1;
00766     Bit32u  sector_count2;
00767     Bit16u  blksize;
00768     Bit16u  dpte_segment;
00769     Bit16u  dpte_offset;
00770     Bit16u  key;
00771     Bit8u   dpi_length;
00772     Bit8u   reserved1;
00773     Bit16u  reserved2;
00774     Bit8u   host_bus[4];
00775     Bit8u   iface_type[8];
00776     Bit8u   iface_path[8];
00777     Bit8u   device_path[8];
00778     Bit8u   reserved3;
00779     Bit8u   checksum;
00780     } dpt_t;
00781  
00782   #define Int13DPT ((dpt_t *) 0)
00783 
00784 #endif // BX_USE_ATADRV
00785 
00786 typedef struct {
00787   union {
00788     struct {
00789       Bit16u di, si, bp, sp;
00790       Bit16u bx, dx, cx, ax;
00791       } r16;
00792     struct {
00793       Bit16u filler[4];
00794       Bit8u  bl, bh, dl, dh, cl, ch, al, ah;
00795       } r8;
00796     } u;
00797   } pusha_regs_t;
00798 
00799 typedef struct {
00800  union {
00801   struct {
00802     Bit32u edi, esi, ebp, esp;
00803     Bit32u ebx, edx, ecx, eax;
00804     } r32;
00805   struct {
00806     Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4;
00807     Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8;
00808     } r16;
00809   struct {
00810     Bit32u filler[4];
00811     Bit8u  bl, bh; 
00812     Bit16u filler1;
00813     Bit8u  dl, dh; 
00814     Bit16u filler2;
00815     Bit8u  cl, ch;
00816     Bit16u filler3;
00817     Bit8u  al, ah;
00818     Bit16u filler4;
00819     } r8;
00820   } u;
00821 } pushad_regs_t;
00822 
00823 typedef struct {
00824   union {
00825     struct {
00826       Bit16u flags;
00827       } r16;
00828     struct {
00829       Bit8u  flagsl;
00830       Bit8u  flagsh;
00831       } r8;
00832     } u;
00833   } flags_t;
00834 
00835 #define SetCF(x)   x.u.r8.flagsl |= 0x01
00836 #define SetZF(x)   x.u.r8.flagsl |= 0x40
00837 #define ClearCF(x) x.u.r8.flagsl &= 0xfe
00838 #define ClearZF(x) x.u.r8.flagsl &= 0xbf
00839 #define GetCF(x)   (x.u.r8.flagsl & 0x01)
00840 
00841 typedef struct {
00842   Bit16u ip;
00843   Bit16u cs;
00844   flags_t flags;
00845   } iret_addr_t;
00846 
00847 
00848 
00849 static Bit8u          inb();
00850 static Bit8u          inb_cmos();
00851 static void           outb();
00852 static void           outb_cmos();
00853 static Bit16u         inw();
00854 static void           outw();
00855 static void           init_rtc();
00856 static bx_bool        rtc_updating();
00857 
00858 static Bit8u          read_byte();
00859 static Bit16u         read_word();
00860 static void           write_byte();
00861 static void           write_word();
00862 static void           bios_printf();
00863 
00864 static Bit8u          inhibit_mouse_int_and_events();
00865 static void           enable_mouse_int_and_events();
00866 static Bit8u          send_to_mouse_ctrl();
00867 static Bit8u          get_mouse_data();
00868 static void           set_kbd_command_byte();
00869 
00870 static void           int09_function();
00871 static void           int13_harddisk();
00872 static void           int13_cdrom();
00873 static void           int13_cdemu();
00874 static void           int13_eltorito();
00875 static void           int13_diskette_function();
00876 static void           int14_function();
00877 static void           int15_function();
00878 static void           int16_function();
00879 static void           int17_function();
00880 static Bit32u         int19_function();
00881 static void           int1a_function();
00882 static void           int70_function();
00883 static void           int74_function();
00884 static Bit16u         get_CS();
00885 static Bit16u         get_SS();
00886 static unsigned int   enqueue_key();
00887 static unsigned int   dequeue_key();
00888 static void           get_hd_geometry();
00889 static void           set_diskette_ret_status();
00890 static void           set_diskette_current_cyl();
00891 static void           determine_floppy_media();
00892 static bx_bool        floppy_drive_exists();
00893 static bx_bool        floppy_drive_recal();
00894 static bx_bool        floppy_media_known();
00895 static bx_bool        floppy_media_sense();
00896 static bx_bool        set_enable_a20();
00897 static void           debugger_on();
00898 static void           debugger_off();
00899 static void           keyboard_init();
00900 static void           keyboard_panic();
00901 static void           shutdown_status_panic();
00902 static void           nmi_handler_msg();
00903 
00904 static void           print_bios_banner();
00905 static void           print_boot_device();
00906 static void           print_boot_failure();
00907 static void           print_cdromboot_failure();
00908 
00909 # if BX_USE_ATADRV
00910 
00911 // ATA / ATAPI driver
00912 void   ata_init();
00913 void   ata_detect();
00914 void   ata_reset();
00915 
00916 Bit16u ata_cmd_non_data();
00917 Bit16u ata_cmd_data_in();
00918 Bit16u ata_cmd_data_out();
00919 Bit16u ata_cmd_packet();
00920 
00921 Bit16u atapi_get_sense();
00922 Bit16u atapi_is_ready();
00923 Bit16u atapi_is_cdrom();
00924 
00925 #endif // BX_USE_ATADRV
00926 
00927 #if BX_ELTORITO_BOOT
00928 
00929 void   cdemu_init();
00930 Bit8u  cdemu_isactive();
00931 Bit8u  cdemu_emulated_drive();
00932 
00933 Bit16u cdrom_boot();
00934 
00935 #endif // BX_ELTORITO_BOOT
00936 
00937 static char bios_cvs_version_string[] = "$Revision: 1.163 $ $Date: 2006/07/07 16:10:37 $";
00938 
00939 #define BIOS_COPYRIGHT_STRING "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."
00940 
00941 #define BIOS_PRINTF_HALT     1
00942 #define BIOS_PRINTF_SCREEN   2
00943 #define BIOS_PRINTF_INFO     4
00944 #define BIOS_PRINTF_DEBUG    8
00945 #define BIOS_PRINTF_ALL      (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO)
00946 #define BIOS_PRINTF_DEBHALT  (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT)
00947 
00948 #define printf(format, p...)  bios_printf(BIOS_PRINTF_SCREEN, format, ##p)
00949 
00950 // Defines the output macros. 
00951 // BX_DEBUG goes to INFO port until we can easily choose debug info on a 
00952 // per-device basis. Debug info are sent only in debug mode
00953 #if DEBUG_ROMBIOS
00954 #  define BX_DEBUG(format, p...)  bios_printf(BIOS_PRINTF_INFO, format, ##p)    
00955 #else
00956 #  define BX_DEBUG(format, p...) 
00957 #endif
00958 #define BX_INFO(format, p...)   bios_printf(BIOS_PRINTF_INFO, format, ##p)
00959 #define BX_PANIC(format, p...)  bios_printf(BIOS_PRINTF_DEBHALT, format, ##p)
00960 
00961 #if DEBUG_ATA
00962 #  define BX_DEBUG_ATA(a...) BX_DEBUG(a)
00963 #else
00964 #  define BX_DEBUG_ATA(a...)
00965 #endif
00966 #if DEBUG_INT13_HD
00967 #  define BX_DEBUG_INT13_HD(a...) BX_DEBUG(a)
00968 #else
00969 #  define BX_DEBUG_INT13_HD(a...)
00970 #endif
00971 #if DEBUG_INT13_CD
00972 #  define BX_DEBUG_INT13_CD(a...) BX_DEBUG(a)
00973 #else
00974 #  define BX_DEBUG_INT13_CD(a...)
00975 #endif
00976 #if DEBUG_INT13_ET
00977 #  define BX_DEBUG_INT13_ET(a...) BX_DEBUG(a)
00978 #else
00979 #  define BX_DEBUG_INT13_ET(a...)
00980 #endif
00981 #if DEBUG_INT13_FL
00982 #  define BX_DEBUG_INT13_FL(a...) BX_DEBUG(a)
00983 #else
00984 #  define BX_DEBUG_INT13_FL(a...)
00985 #endif
00986 #if DEBUG_INT15
00987 #  define BX_DEBUG_INT15(a...) BX_DEBUG(a)
00988 #else
00989 #  define BX_DEBUG_INT15(a...)
00990 #endif
00991 #if DEBUG_INT16
00992 #  define BX_DEBUG_INT16(a...) BX_DEBUG(a)
00993 #else
00994 #  define BX_DEBUG_INT16(a...)
00995 #endif
00996 #if DEBUG_INT1A
00997 #  define BX_DEBUG_INT1A(a...) BX_DEBUG(a)
00998 #else
00999 #  define BX_DEBUG_INT1A(a...)
01000 #endif
01001 #if DEBUG_INT74
01002 #  define BX_DEBUG_INT74(a...) BX_DEBUG(a)
01003 #else
01004 #  define BX_DEBUG_INT74(a...)
01005