14d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/////////////////////////////////////////////////////////////////////////
24d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $Id$
34d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/////////////////////////////////////////////////////////////////////////
44d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
54d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  Copyright (C) 2002  MandrakeSoft S.A.
64d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
74d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//    MandrakeSoft S.A.
84d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//    43, rue d'Aboukir
94d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//    75002 Paris - France
104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//    http://www.linux-mandrake.com/
114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//    http://www.mandrakesoft.com/
124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  This library is free software; you can redistribute it and/or
144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  modify it under the terms of the GNU Lesser General Public
154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  License as published by the Free Software Foundation; either
164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  version 2 of the License, or (at your option) any later version.
174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  This library is distributed in the hope that it will be useful,
194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  but WITHOUT ANY WARRANTY; without even the implied warranty of
204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  Lesser General Public License for more details.
224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  You should have received a copy of the GNU Lesser General Public
244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  License along with this library; if not, write to the Free Software
254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ROM BIOS compatability entry points:
314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ===================================
324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e05b ; POST Entry Point
334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e2c3 ; NMI Handler Entry Point
344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e3fe ; INT 13h Fixed Disk Services Entry Point
354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e401 ; Fixed Disk Parameter Table
364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e6f2 ; INT 19h Boot Load Service Entry Point
374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e6f5 ; Configuration Data Table
384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e729 ; Baud Rate Generator Table
394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e739 ; INT 14h Serial Communications Service Entry Point
404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e82e ; INT 16h Keyboard Service Entry Point
414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $e987 ; INT 09h Keyboard Service Entry Point
424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $ec59 ; INT 13h Diskette Service Entry Point
434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $ef57 ; INT 0Eh Diskette Hardware ISR Entry Point
444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $efc7 ; Diskette Controller Parameter Table
454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $efd2 ; INT 17h Printer Service Entry Point
464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $f045 ; INT 10 Functions 0-Fh Entry Point
474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $f065 ; INT 10h Video Support Service Entry Point
484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $f0a4 ; MDA/CGA Video Parameter Table (INT 1Dh)
494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $f841 ; INT 12h Memory Size Service Entry Point
504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $f84d ; INT 11h Equipment List Service Entry Point
514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $f859 ; INT 15h System Services Entry Point
524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters)
534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fe6e ; INT 1Ah Time-of-day Service Entry Point
544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fea5 ; INT 08h System Timer ISR Entry Point
554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fef3 ; Initial Interrupt Vector Offsets Loaded by POST
564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $ff53 ; IRET Instruction for Dummy Interrupt Handler
574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $ff54 ; INT 05h Print Screen Service Entry Point
584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fff0 ; Power-up Entry Point
594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// $fffe ; System Model ID
614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// NOTES for ATA/ATAPI driver (cbbochs@free.fr)
634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   Features
644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - supports up to 4 ATA interfaces
654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - device/geometry detection
664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - 16bits/32bits device access
674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - pchs/lba access
684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - datain/dataout/packet command support
694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// NOTES for El-Torito Boot (cbbochs@free.fr)
714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - CD-ROM booting is only available if ATA/ATAPI Driver is available
724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Current code is only able to boot mono-session cds
734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Current code can not boot and emulate a hard-disk
744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     the bios will panic otherwise
754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Current code also use memory in EBDA segement.
764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - I used cmos byte 0x3D to store extended information on boot-device
774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Code has to be modified modified to handle multiple cdrom drives
784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Here are the cdrom boot failure codes:
794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       1 : no atapi device found
804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       2 : no atapi cdrom found
814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       3 : can not read cd - BRVD
824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       4 : cd is not eltorito (BRVD)
834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       5 : cd is not eltorito (ISO TAG)
844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       6 : cd is not eltorito (ELTORITO TAG)
854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       7 : can not read cd - boot catalog
864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       8 : boot catalog : bad header
874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//       9 : boot catalog : bad platform
884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//      10 : boot catalog : bad signature
894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//      11 : boot catalog : bootable flag not set
904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//      12 : can not read cd - boot image
914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   ATA driver
934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - EBDA segment.
944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     I used memory starting at 0x121 in the segment
954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - the translation policy is defined in cmos regs 0x39 & 0x3a
964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// TODO :
984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   int74
1004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - needs to be reworked.  Uses direct [bp] offsets. (?)
1014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
1024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   int13:
1034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - f04 (verify sectors) isn't complete  (?)
1044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - f02/03/04 should set current cyl,etc in BDA  (?)
1054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     - rewrite int13_relocated & clean up int13 entry code
1064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
1074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   NOTES:
1084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - NMI access (bit7 of addr written to 70h)
1094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
1104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   ATA driver
1114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - should handle the "don't detect" bit (cmos regs 0x3b & 0x3c)
1124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - could send the multiple-sector read/write commands
1134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
1144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   El-Torito
1154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Emulate a Hard-disk (currently only diskette can be emulated) see "FIXME ElTorito Harddisk"
1164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Implement remaining int13_cdemu functions (as defined by El-Torito specs)
1174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - cdrom drive is hardcoded to ide 0 device 1 in several places. see "FIXME ElTorito Hardcoded"
1184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - int13 Fix DL when emulating a cd. In that case DL is decremented before calling real int13.
1194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//     This is ok. But DL should be reincremented afterwards.
1204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - Fix all "FIXME ElTorito Various"
1214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   - should be able to boot any cdrom instead of the first one
1224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
1234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   BCC Bug: find a generic way to handle the bug of #asm after an "if"  (fixed in 0.16.7)
1244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include "rombios.h"
1264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_ATA          0
1284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT13_HD     0
1294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT13_CD     0
1304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT13_ET     0
1314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT13_FL     0
1324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT15        0
1334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT16        0
1344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT1A        0
1354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_INT74        0
1364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define DEBUG_APM          0
1374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_CPU           3
1394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_USE_PS2_MOUSE 1
1404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_CALL_INT15_4F 1
1414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_USE_EBDA      1
1424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_SUPPORT_FLOPPY 1
1434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_FLOPPY_ON_CNT 37   /* 2 seconds */
1444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_PCIBIOS       1
1454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_APM           1
1464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_USE_ATADRV    1
1484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_ELTORITO_BOOT 1
1494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_MAX_ATA_INTERFACES   4
1514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_MAX_ATA_DEVICES      (BX_MAX_ATA_INTERFACES*2)
1524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_VIRTUAL_PORTS 1 /* normal output to Bochs ports */
1544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_DEBUG_SERIAL  0 /* output to COM1 */
1554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   /* model byte 0xFC = AT */
1574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SYS_MODEL_ID     0xFC
1584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SYS_SUBMODEL_ID  0x00
1594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BIOS_REVISION    1
1604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BIOS_CONFIG_TABLE 0xe6f5
1614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifndef BIOS_BUILD_DATE
1634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BIOS_BUILD_DATE "06/23/99"
1644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
1654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // 1K of base memory used for Extended Bios Data Area (EBDA)
1674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // EBDA is used for PS/2 mouse support, and IDE BIOS, etc.
1684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define EBDA_SEG           0x9FC0
1694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define EBDA_SIZE          1              // In KiB
1704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BASE_MEM_IN_K   (640 - EBDA_SIZE)
1714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
1734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_SEG              0x9ff0
1744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_TABLE_OFFSET     0x0000
1754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_TABLE_ENTRIES    8
1764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_COUNT_OFFSET     0x0080  /* u16: number of valid table entries */
1774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_SEQUENCE_OFFSET  0x0082  /* u16: next boot device */
1784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_BOOTFIRST_OFFSET 0x0084  /* u16: user selected device */
1794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_SIZE             0xff
1804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_TYPE_FLOPPY      0x01
1814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_TYPE_HARDDISK    0x02
1824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_TYPE_CDROM       0x03
1834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IPL_TYPE_BEV         0x80
1844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Sanity Checks
1864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV && BX_CPU<3
1874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#    error The ATA/ATAPI Driver can only to be used with a 386+ cpu
1884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
1894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV && !BX_USE_EBDA
1904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#    error ATA/ATAPI Driver can only be used if EBDA is available
1914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
1924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT && !BX_USE_ATADRV
1934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#    error El-Torito Boot can only be use if ATA/ATAPI Driver is available
1944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
1954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_PCIBIOS && BX_CPU<3
1964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#    error PCI BIOS can only be used with 386+ cpu
1974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
1984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_APM && BX_CPU<3
1994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#    error APM BIOS can only be used with 386+ cpu
2004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
2014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// define this if you want to make PCIBIOS working on a specific bridge only
2034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// undef enables PCIBIOS when at least one PCI device is found
2044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// i440FX is emulated by Bochs and QEMU
2054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCI_FIXED_HOST_BRIDGE 0x12378086 ;; i440FX PCI bridge
2064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// #20  is dec 20
2084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// #$20 is hex 20 = 32
2094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// #0x20 is hex 20 = 32
2104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// LDA  #$20
2114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// JSR  $E820
2124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// LDD  .i,S
2134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// JSR  $C682
2144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// mov al, #$20
2154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// all hex literals should be prefixed with '0x'
2174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   grep "#[0-9a-fA-F][0-9a-fA-F]" rombios.c
2184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// no mov SEG-REG, #value, must mov register into seg-reg
2194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   grep -i "mov[ ]*.s" rombios.c
2204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// This is for compiling with gcc2 and gcc3
2224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ASM_START #asm
2234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ASM_END #endasm
2244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2254d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
2264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.rom
2274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0x0000
2294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_CPU >= 3
2314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause16 386
2324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
2334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause16 286
2344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
2354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2364d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaMACRO HALT
2374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; the HALT macro is called with the line number of the HALT call.
2384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex
2394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; to print a BX_PANIC message.  This will normally halt the simulation
2404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; with a message such as "BIOS panic at rombios.c, line 4091".
2414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; However, users can choose to make panics non-fatal and continue.
2424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_VIRTUAL_PORTS
2434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx,#PANIC_PORT
2444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax,#?1
2454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx,ax
2464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
2474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx,#0x80
2484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax,#?1
2494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx,al
2504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
2514d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaMEND
2524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2534d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaMACRO JMP_AP
2544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0xea
2554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw ?2
2564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw ?1
2574d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaMEND
2584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2594d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaMACRO SET_INT_VECTOR
2604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, ?3
2614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ?1*4, ax
2624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, ?2
2634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ?1*4+2, ax
2644d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaMEND
2654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2664d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
2674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef unsigned char  Bit8u;
2694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef unsigned short Bit16u;
2704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef unsigned short bx_bool;
2714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef unsigned long  Bit32u;
2724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void memsetb(seg,offset,value,count);
2754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void memcpyb(dseg,doffset,sseg,soffset,count);
2764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void memcpyd(dseg,doffset,sseg,soffset,count);
2774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // memset of count bytes
2794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    void
2804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(seg,offset,value,count)
2814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u seg;
2824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u offset;
2834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u value;
2844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u count;
2854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
2864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
2874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bp
2884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
2894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ax
2914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push cx
2924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push es
2934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push di
2944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  cx, 10[bp] ; count
2964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      test cx, cx
2974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      je   memsetb_end
2984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 4[bp] ; segment
2994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  es, ax
3004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 6[bp] ; offset
3014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  di, ax
3024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  al, 8[bp] ; value
3034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cld
3044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      rep
3054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       stosb
3064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb_end:
3084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop di
3094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop es
3104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop cx
3114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop ax
3124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop bp
3144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
3154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
3164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // memcpy of count bytes
3184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    void
3194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyb(dseg,doffset,sseg,soffset,count)
3204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u dseg;
3214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u doffset;
3224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u sseg;
3234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u soffset;
3244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u count;
3254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
3264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
3274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bp
3284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
3294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ax
3314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push cx
3324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push es
3334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push di
3344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ds
3354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push si
3364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  cx, 12[bp] ; count
3384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      test cx, cx
3394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      je   memcpyb_end
3404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 4[bp] ; dsegment
3414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  es, ax
3424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 6[bp] ; doffset
3434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  di, ax
3444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 8[bp] ; ssegment
3454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ds, ax
3464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 10[bp] ; soffset
3474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  si, ax
3484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cld
3494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      rep
3504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       movsb
3514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyb_end:
3534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop si
3544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop ds
3554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop di
3564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop es
3574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop cx
3584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop ax
3594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop bp
3614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
3624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
3634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // memcpy of count dword
3654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    void
3664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyd(dseg,doffset,sseg,soffset,count)
3674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u dseg;
3684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u doffset;
3694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u sseg;
3704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u soffset;
3714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u count;
3724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
3734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
3744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bp
3754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
3764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ax
3784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push cx
3794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push es
3804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push di
3814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ds
3824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push si
3834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  cx, 12[bp] ; count
3854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      test cx, cx
3864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      je   memcpyd_end
3874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 4[bp] ; dsegment
3884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  es, ax
3894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 6[bp] ; doffset
3904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  di, ax
3914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 8[bp] ; ssegment
3924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ds, ax
3934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 10[bp] ; soffset
3944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  si, ax
3954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cld
3964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      rep
3974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       movsd
3984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
3994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyd_end:
4004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop si
4014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop ds
4024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop di
4034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop es
4044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop cx
4054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop ax
4064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop bp
4084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
4094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
4104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // read_dword and write_dword functions
4124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  static Bit32u         read_dword();
4134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  static void           write_dword();
4144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u
4164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  read_dword(seg, offset)
4174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u seg;
4184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u offset;
4194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
4204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
4214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bp
4224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
4234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push bx
4254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ds
4264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 4[bp] ; segment
4274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ds, ax
4284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bx, 6[bp] ; offset
4294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, [bx]
4304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      add  bx, #2
4314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  dx, [bx]
4324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; ax = return value (word)
4334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; dx = return value (word)
4344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  ds
4354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  bx
4364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bp
4384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
4394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
4404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    void
4424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(seg, offset, data)
4434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u seg;
4444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u offset;
4454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u data;
4464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
4474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
4484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bp
4494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
4504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ax
4524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push bx
4534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push ds
4544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 4[bp] ; segment
4554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ds, ax
4564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bx, 6[bp] ; offset
4574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 8[bp] ; data word
4584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  [bx], ax  ; write data word
4594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      add  bx, #2
4604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, 10[bp] ; data word
4614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  [bx], ax  ; write data word
4624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  ds
4634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  bx
4644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  ax
4654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bp
4674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
4684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
4694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Bit32u (unsigned long) and long helper functions
4714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
4724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; and function
4744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  landl:
4754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  landul:
4764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
4774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      and ax,[di]
4784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
4794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      and bx,2[di]
4804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
4814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; add function
4834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  laddl:
4844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  laddul:
4854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
4864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      add ax,[di]
4874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
4884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      adc bx,2[di]
4894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
4904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
4914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; cmp function
4924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lcmpl:
4934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lcmpul:
4944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    and eax, #0x0000FFFF
4954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl ebx, #16
4964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or  eax, ebx
4974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr ebx, #16
4984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
4994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cmp eax, dword ptr [di]
5004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; sub function
5034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsubl:
5044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsubul:
5054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sub ax,[di]
5074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sbb bx,2[di]
5094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; mul function
5124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lmull:
5134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lmulul:
5144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    and eax, #0x0000FFFF
5154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl ebx, #16
5164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or  eax, ebx
5174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mul eax, dword ptr [di]
5194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov ebx, eax
5204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr ebx, #16
5214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; dec function
5244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ldecl:
5254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ldecul:
5264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    dec dword ptr [bx]
5284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; or function
5314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lorl:
5324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lorul:
5334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or  ax,[di]
5354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or  bx,2[di]
5374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; inc function
5404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lincl:
5414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lincul:
5424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
5434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    inc dword ptr [bx]
5444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; tst function
5474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ltstl:
5484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ltstul:
5494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    and eax, #0x0000FFFF
5504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl ebx, #16
5514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or  eax, ebx
5524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr ebx, #16
5534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    test eax, eax
5544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; sr function
5574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsrul:
5584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  cx,di
5594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    jcxz lsr_exit
5604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    and  eax, #0x0000FFFF
5614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl  ebx, #16
5624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or   eax, ebx
5634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsr_loop:
5644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr  eax, #1
5654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    loop lsr_loop
5664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ebx, eax
5674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr  ebx, #16
5684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsr_exit:
5694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; sl function
5724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsll:
5734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lslul:
5744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  cx,di
5754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    jcxz lsl_exit
5764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    and  eax, #0x0000FFFF
5774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl  ebx, #16
5784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or   eax, ebx
5794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsl_loop:
5804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl  eax, #1
5814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    loop lsl_loop
5824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ebx, eax
5834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr  ebx, #16
5844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lsl_exit:
5854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  idiv_:
5884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cwd
5894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    idiv bx
5904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  idiv_u:
5934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    xor dx,dx
5944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    div bx
5954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
5964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
5974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ldivul:
5984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    and  eax, #0x0000FFFF
5994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl  ebx, #16
6004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    or   eax, ebx
6014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    xor  edx, edx
6024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
6034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bx,  2[di]
6044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shl  ebx, #16
6054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SEG SS
6064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bx,  [di]
6074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    div  ebx
6084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ebx, eax
6094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    shr  ebx, #16
6104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ret
6114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
6134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// for access to RAM area which is used by interrupt vectors
6154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// and BIOS Data Area
6164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct {
6184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned char filler1[0x400];
6194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned char filler2[0x6c];
6204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ticks_low;
6214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ticks_high;
6224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  midnight_flag;
6234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } bios_data_t;
6244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BiosData ((bios_data_t  *) 0)
6264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
6284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
6294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u heads;      // # heads
6304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u cylinders;  // # cylinders
6314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u spt;        // # sectors / track
6324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } chs_t;
6334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // DPTE definition
6354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
6364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u iobase1;
6374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u iobase2;
6384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  prefix;
6394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  unused;
6404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  irq;
6414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  blkcount;
6424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  dma;
6434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  pio;
6444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u options;
6454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u reserved;
6464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  revision;
6474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  checksum;
6484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } dpte_t;
6494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
6514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  iface;        // ISA or PCI
6524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u iobase1;      // IO Base 1
6534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u iobase2;      // IO Base 2
6544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  irq;          // IRQ
6554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } ata_channel_t;
6564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
6584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  type;         // Detected type of ata (ata/atapi/none/unknown)
6594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  device;       // Detected type of attached devices (hd/cd/none)
6604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  removable;    // Removable device flag
6614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  lock;         // Locks for removable devices
6624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  mode;         // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
6634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u blksize;      // block size
6644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  translation;  // type of translation
6664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    chs_t  lchs;         // Logical CHS
6674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    chs_t  pchs;         // Physical CHS
6684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u sectors_low;  // Total sectors count
6704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u sectors_high;
6714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } ata_device_t;
6724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
6744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // ATA channels info
6754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ata_channel_t channels[BX_MAX_ATA_INTERFACES];
6764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // ATA devices info
6784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ata_device_t  devices[BX_MAX_ATA_DEVICES];
6794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    //
6804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // map between (bios hd id - 0x80) and ata channels
6814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  hdcount, hdidmap[BX_MAX_ATA_DEVICES];
6824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // map between (bios cd id - 0xE0) and ata channels
6844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  cdcount, cdidmap[BX_MAX_ATA_DEVICES];
6854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Buffer for DPTE table
6874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    dpte_t dpte;
6884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Count of transferred sectors and bytes
6904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u trsfsectors;
6914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u trsfbytes;
6924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } ata_t;
6944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
6954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
6964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // ElTorito Device Emulation data
6974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
6984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  active;
6994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  media;
7004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  emulated_drive;
7014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  controller_index;
7024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u device_spec;
7034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u ilba;
7044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u buffer_segment;
7054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u load_segment;
7064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u sector_count;
7074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Virtual device
7094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    chs_t  vdevice;
7104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } cdemu_t;
7114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
7124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // for access to EBDA area
7144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     The EBDA structure should conform to
7154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     http://www.frontiernet.net/~fys/rombios.htm document
7164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     I made the ata and cdemu structs begin at 0x121 in the EBDA seg
7174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // EBDA must be at most 768 bytes; it lives at EBDA_SEG, and the boot
7184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // device tables are at IPL_SEG
7194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
7204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    unsigned char filler1[0x3D];
7214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // FDPT - Can be splitted in data members if needed
7234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    unsigned char fdpt0[0x10];
7244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    unsigned char fdpt1[0x10];
7254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    unsigned char filler2[0xC4];
7274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // ATA Driver data
7294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ata_t   ata;
7304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
7324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // El Torito Emulation data
7334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cdemu_t cdemu;
7344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
7354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } ebda_data_t;
7374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  #define EbdaData ((ebda_data_t *) 0)
7394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // for access to the int13ext structure
7414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
7424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  size;
7434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  reserved;
7444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u count;
7454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u offset;
7464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u segment;
7474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u lba1;
7484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u lba2;
7494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } int13ext_t;
7504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  #define Int13Ext ((int13ext_t *) 0)
7524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Disk Physical Table definition
7544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  typedef struct {
7554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  size;
7564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  infos;
7574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u  cylinders;
7584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u  heads;
7594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u  spt;
7604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u  sector_count1;
7614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u  sector_count2;
7624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  blksize;
7634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  dpte_offset;
7644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  dpte_segment;
7654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  key;
7664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   dpi_length;
7674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   reserved1;
7684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u  reserved2;
7694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   host_bus[4];
7704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   iface_type[8];
7714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   iface_path[8];
7724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   device_path[8];
7734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   reserved3;
7744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u   checksum;
7754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } dpt_t;
7764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  #define Int13DPT ((dpt_t *) 0)
7784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_USE_ATADRV
7804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct {
7824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  union {
7834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    struct {
7844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u di, si, bp, sp;
7854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u bx, dx, cx, ax;
7864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } r16;
7874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    struct {
7884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u filler[4];
7894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit8u  bl, bh, dl, dh, cl, ch, al, ah;
7904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } r8;
7914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } u;
7924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } pusha_regs_t;
7934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
7944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct {
7954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union {
7964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  struct {
7974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u edi, esi, ebp, esp;
7984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u ebx, edx, ecx, eax;
7994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } r32;
8004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  struct {
8014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4;
8024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8;
8034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } r16;
8044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  struct {
8054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u filler[4];
8064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  bl, bh;
8074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u filler1;
8084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  dl, dh;
8094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u filler2;
8104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  cl, ch;
8114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u filler3;
8124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  al, ah;
8134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u filler4;
8144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } r8;
8154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } u;
8164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} pushad_regs_t;
8174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct {
8194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  union {
8204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    struct {
8214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u flags;
8224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } r16;
8234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    struct {
8244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit8u  flagsl;
8254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit8u  flagsh;
8264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } r8;
8274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } u;
8284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } flags_t;
8294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SetCF(x)   x.u.r8.flagsl |= 0x01
8314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SetZF(x)   x.u.r8.flagsl |= 0x40
8324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ClearCF(x) x.u.r8.flagsl &= 0xfe
8334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ClearZF(x) x.u.r8.flagsl &= 0xbf
8344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GetCF(x)   (x.u.r8.flagsl & 0x01)
8354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct {
8374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ip;
8384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u cs;
8394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  flags_t flags;
8404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } iret_addr_t;
8414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct {
8434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u type;
8444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u flags;
8454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u vector;
8464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u description;
8474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u reserved;
8484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } ipl_entry_t;
8494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u          inb();
8534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u          inb_cmos();
8544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           outb();
8554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           outb_cmos();
8564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit16u         inw();
8574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           outw();
8584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           init_rtc();
8594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic bx_bool        rtc_updating();
8604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u          read_byte();
8624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit16u         read_word();
8634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           write_byte();
8644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           write_word();
8654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           bios_printf();
8664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u          inhibit_mouse_int_and_events();
8684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           enable_mouse_int_and_events();
8694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u          send_to_mouse_ctrl();
8704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u          get_mouse_data();
8714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           set_kbd_command_byte();
8724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
8734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int09_function();
8744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int13_harddisk();
8754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int13_cdrom();
8764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int13_cdemu();
8774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int13_eltorito();
8784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int13_diskette_function();
8794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int14_function();
8804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int15_function();
8814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int16_function();
8824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int17_function();
8834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int19_function();
8844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int1a_function();
8854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int70_function();
8864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           int74_function();
8874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit16u         get_CS();
8884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit16u         get_SS();
8894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic unsigned int   enqueue_key();
8904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic unsigned int   dequeue_key();
8914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           get_hd_geometry();
8924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           set_diskette_ret_status();
8934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           set_diskette_current_cyl();
8944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           determine_floppy_media();
8954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic bx_bool        floppy_drive_exists();
8964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic bx_bool        floppy_drive_recal();
8974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic bx_bool        floppy_media_known();
8984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic bx_bool        floppy_media_sense();
8994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic bx_bool        set_enable_a20();
9004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           debugger_on();
9014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           debugger_off();
9024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           keyboard_init();
9034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           keyboard_panic();
9044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           shutdown_status_panic();
9054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           nmi_handler_msg();
9064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           delay_ticks();
9074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           delay_ticks_and_check_for_keystroke();
9084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           interactive_bootkey();
9104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           print_bios_banner();
9114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           print_boot_device();
9124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           print_boot_failure();
9134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void           print_cdromboot_failure();
9144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima# if BX_USE_ATADRV
9164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA / ATAPI driver
9184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid   ata_init();
9194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid   ata_detect();
9204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid   ata_reset();
9214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9224d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_non_data();
9234d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_data_in();
9244d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_data_out();
9254d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_packet();
9264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9274d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u atapi_get_sense();
9284d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u atapi_is_ready();
9294d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u atapi_is_cdrom();
9304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_USE_ATADRV
9324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
9344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid   cdemu_init();
9364d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit8u  cdemu_isactive();
9374d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit8u  cdemu_emulated_drive();
9384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9394d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u cdrom_boot();
9404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
9424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char bios_cvs_version_string[] = "$Revision$ $Date$";
9444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BIOS_COPYRIGHT_STRING "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."
9464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_ATA
9484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_ATA(a...) BX_DEBUG(a)
9494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_ATA(a...)
9514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT13_HD
9534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_HD(a...) BX_DEBUG(a)
9544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_HD(a...)
9564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT13_CD
9584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_CD(a...) BX_DEBUG(a)
9594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_CD(a...)
9614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT13_ET
9634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_ET(a...) BX_DEBUG(a)
9644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_ET(a...)
9664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT13_FL
9684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_FL(a...) BX_DEBUG(a)
9694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT13_FL(a...)
9714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT15
9734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT15(a...) BX_DEBUG(a)
9744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT15(a...)
9764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT16
9784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT16(a...) BX_DEBUG(a)
9794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT16(a...)
9814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT1A
9834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT1A(a...) BX_DEBUG(a)
9844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT1A(a...)
9864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if DEBUG_INT74
9884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT74(a...) BX_DEBUG(a)
9894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
9904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  define BX_DEBUG_INT74(a...)
9914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
9924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
9934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_AL(val8) AX = ((AX & 0xff00) | (val8))
9944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_BL(val8) BX = ((BX & 0xff00) | (val8))
9954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_CL(val8) CX = ((CX & 0xff00) | (val8))
9964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_DL(val8) DX = ((DX & 0xff00) | (val8))
9974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8))
9984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8))
9994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8))
10004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8))
10014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_AL() ( AX & 0x00ff )
10034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_BL() ( BX & 0x00ff )
10044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_CL() ( CX & 0x00ff )
10054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_DL() ( DX & 0x00ff )
10064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_AH() ( AX >> 8 )
10074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_BH() ( BX >> 8 )
10084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_CH() ( CX >> 8 )
10094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_DH() ( DX >> 8 )
10104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_ELDL() ( ELDX & 0x00ff )
10124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_ELDH() ( ELDX >> 8 )
10134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_CF()     FLAGS |= 0x0001
10154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define CLEAR_CF()   FLAGS &= 0xfffe
10164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_CF()     (FLAGS & 0x0001)
10174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_ZF()     FLAGS |= 0x0040
10194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define CLEAR_ZF()   FLAGS &= 0xffbf
10204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define GET_ZF()     (FLAGS & 0x0040)
10214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UNSUPPORTED_FUNCTION 0x86
10234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define none 0
10254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define MAX_SCAN_CODE 0x58
10264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
10274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic struct {
10284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u normal;
10294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u shift;
10304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u control;
10314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u alt;
10324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u lock_flags;
10334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } scan_to_scanascii[MAX_SCAN_CODE + 1] = {
10344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none },
10354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x011b, 0x011b, 0x011b, 0x0100, none }, /* escape */
10364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0231, 0x0221,   none, 0x7800, none }, /* 1! */
10374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0332, 0x0340, 0x0300, 0x7900, none }, /* 2@ */
10384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0433, 0x0423,   none, 0x7a00, none }, /* 3# */
10394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0534, 0x0524,   none, 0x7b00, none }, /* 4$ */
10404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0635, 0x0625,   none, 0x7c00, none }, /* 5% */
10414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0736, 0x075e, 0x071e, 0x7d00, none }, /* 6^ */
10424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0837, 0x0826,   none, 0x7e00, none }, /* 7& */
10434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0938, 0x092a,   none, 0x7f00, none }, /* 8* */
10444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0a39, 0x0a28,   none, 0x8000, none }, /* 9( */
10454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0b30, 0x0b29,   none, 0x8100, none }, /* 0) */
10464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200, none }, /* -_ */
10474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0d3d, 0x0d2b,   none, 0x8300, none }, /* =+ */
10484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0e08, 0x0e08, 0x0e7f,   none, none }, /* backspace */
10494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x0f09, 0x0f00,   none,   none, none }, /* tab */
10504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1071, 0x1051, 0x1011, 0x1000, 0x40 }, /* Q */
10514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1177, 0x1157, 0x1117, 0x1100, 0x40 }, /* W */
10524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1265, 0x1245, 0x1205, 0x1200, 0x40 }, /* E */
10534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1372, 0x1352, 0x1312, 0x1300, 0x40 }, /* R */
10544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1474, 0x1454, 0x1414, 0x1400, 0x40 }, /* T */
10554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1579, 0x1559, 0x1519, 0x1500, 0x40 }, /* Y */
10564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1675, 0x1655, 0x1615, 0x1600, 0x40 }, /* U */
10574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1769, 0x1749, 0x1709, 0x1700, 0x40 }, /* I */
10584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x186f, 0x184f, 0x180f, 0x1800, 0x40 }, /* O */
10594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1970, 0x1950, 0x1910, 0x1900, 0x40 }, /* P */
10604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1a5b, 0x1a7b, 0x1a1b,   none, none }, /* [{ */
10614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1b5d, 0x1b7d, 0x1b1d,   none, none }, /* ]} */
10624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1c0d, 0x1c0d, 0x1c0a,   none, none }, /* Enter */
10634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* L Ctrl */
10644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1e61, 0x1e41, 0x1e01, 0x1e00, 0x40 }, /* A */
10654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x1f73, 0x1f53, 0x1f13, 0x1f00, 0x40 }, /* S */
10664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2064, 0x2044, 0x2004, 0x2000, 0x40 }, /* D */
10674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2166, 0x2146, 0x2106, 0x2100, 0x40 }, /* F */
10684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2267, 0x2247, 0x2207, 0x2200, 0x40 }, /* G */
10694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2368, 0x2348, 0x2308, 0x2300, 0x40 }, /* H */
10704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x246a, 0x244a, 0x240a, 0x2400, 0x40 }, /* J */
10714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x256b, 0x254b, 0x250b, 0x2500, 0x40 }, /* K */
10724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x266c, 0x264c, 0x260c, 0x2600, 0x40 }, /* L */
10734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x273b, 0x273a,   none,   none, none }, /* ;: */
10744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2827, 0x2822,   none,   none, none }, /* '" */
10754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2960, 0x297e,   none,   none, none }, /* `~ */
10764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* L shift */
10774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2b5c, 0x2b7c, 0x2b1c,   none, none }, /* |\ */
10784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00, 0x40 }, /* Z */
10794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2d78, 0x2d58, 0x2d18, 0x2d00, 0x40 }, /* X */
10804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2e63, 0x2e43, 0x2e03, 0x2e00, 0x40 }, /* C */
10814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x2f76, 0x2f56, 0x2f16, 0x2f00, 0x40 }, /* V */
10824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3062, 0x3042, 0x3002, 0x3000, 0x40 }, /* B */
10834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x316e, 0x314e, 0x310e, 0x3100, 0x40 }, /* N */
10844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x326d, 0x324d, 0x320d, 0x3200, 0x40 }, /* M */
10854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x332c, 0x333c,   none,   none, none }, /* ,< */
10864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x342e, 0x343e,   none,   none, none }, /* .> */
10874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x352f, 0x353f,   none,   none, none }, /* /? */
10884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* R Shift */
10894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x372a, 0x372a,   none,   none, none }, /* * */
10904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* L Alt */
10914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3920, 0x3920, 0x3920, 0x3920, none }, /* space */
10924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* caps lock */
10934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3b00, 0x5400, 0x5e00, 0x6800, none }, /* F1 */
10944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3c00, 0x5500, 0x5f00, 0x6900, none }, /* F2 */
10954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3d00, 0x5600, 0x6000, 0x6a00, none }, /* F3 */
10964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3e00, 0x5700, 0x6100, 0x6b00, none }, /* F4 */
10974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x3f00, 0x5800, 0x6200, 0x6c00, none }, /* F5 */
10984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4000, 0x5900, 0x6300, 0x6d00, none }, /* F6 */
10994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4100, 0x5a00, 0x6400, 0x6e00, none }, /* F7 */
11004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4200, 0x5b00, 0x6500, 0x6f00, none }, /* F8 */
11014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4300, 0x5c00, 0x6600, 0x7000, none }, /* F9 */
11024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4400, 0x5d00, 0x6700, 0x7100, none }, /* F10 */
11034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* Num Lock */
11044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none }, /* Scroll Lock */
11054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4700, 0x4737, 0x7700,   none, 0x20 }, /* 7 Home */
11064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4800, 0x4838,   none,   none, 0x20 }, /* 8 UP */
11074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4900, 0x4939, 0x8400,   none, 0x20 }, /* 9 PgUp */
11084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4a2d, 0x4a2d,   none,   none, none }, /* - */
11094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4b00, 0x4b34, 0x7300,   none, 0x20 }, /* 4 Left */
11104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4c00, 0x4c35,   none,   none, 0x20 }, /* 5 */
11114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4d00, 0x4d36, 0x7400,   none, 0x20 }, /* 6 Right */
11124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4e2b, 0x4e2b,   none,   none, none }, /* + */
11134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x4f00, 0x4f31, 0x7500,   none, 0x20 }, /* 1 End */
11144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x5000, 0x5032,   none,   none, 0x20 }, /* 2 Down */
11154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x5100, 0x5133, 0x7600,   none, 0x20 }, /* 3 PgDn */
11164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x5200, 0x5230,   none,   none, 0x20 }, /* 0 Ins */
11174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x5300, 0x532e,   none,   none, 0x20 }, /* Del */
11184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none },
11194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {   none,   none,   none,   none, none },
11204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x565c, 0x567c,   none,   none, none }, /* \| */
11214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */
11224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      { 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */
11234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      };
11244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
11264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainb(port)
11274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u port;
11284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
11294d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
11304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
11314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
11324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push dx
11344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dx, 4[bp]
11354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    in   al, dx
11364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  dx
11374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
11394d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
11404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
11414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
11434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
11444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainw(port)
11454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u port;
11464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
11474d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
11484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
11494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
11504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push dx
11524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dx, 4[bp]
11534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    in   ax, dx
11544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  dx
11554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
11574d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
11584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
11594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
11604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
11624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaoutb(port, val)
11634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u port;
11644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  val;
11654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
11664d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
11674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
11684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
11694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
11714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push dx
11724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dx, 4[bp]
11734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, 6[bp]
11744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    out  dx, al
11754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  dx
11764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ax
11774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
11794d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
11804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
11814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
11834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
11844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaoutw(port, val)
11854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u port;
11864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  val;
11874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
11884d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
11894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
11904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
11914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
11924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
11934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push dx
11944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dx, 4[bp]
11954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, 6[bp]
11964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    out  dx, ax
11974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  dx
11984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ax
11994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
12014d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
12024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
12034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
12044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
12064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaoutb_cmos(cmos_reg, val)
12074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u cmos_reg;
12084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u val;
12094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
12104d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
12114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
12124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
12134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, 4[bp] ;; cmos_reg
12154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    out  0x70, al
12164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, 6[bp] ;; val
12174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    out  0x71, al
12184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
12204d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
12214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
12224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
12244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainb_cmos(cmos_reg)
12254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u cmos_reg;
12264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
12274d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
12284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
12294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
12304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, 4[bp] ;; cmos_reg
12324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    out 0x70, al
12334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    in  al, 0x71
12344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
12364d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
12374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
12384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
12404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainit_rtc()
12414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
12424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb_cmos(0x0a, 0x26);
12434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb_cmos(0x0b, 0x02);
12444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inb_cmos(0x0c);
12454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inb_cmos(0x0d);
12464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
12474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool
12494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimartc_updating()
12504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
12514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // This function checks to see if the update-in-progress bit
12524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // is set in CMOS Status Register A.  If not, it returns 0.
12534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // If it is set, it tries to wait until there is a transition
12544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // to 0, and will return 0 if such a transition occurs.  A 1
12554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // is returned only after timing out.  The maximum period
12564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // that this bit should be set is constrained to 244useconds.
12574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // The count I use below guarantees coverage or more than
12584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // this time, with any reasonable IPS setting.
12594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u count;
12614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  count = 25000;
12634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (--count != 0) {
12644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ( (inb_cmos(0x0a) & 0x80) == 0 )
12654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return(0);
12664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
12674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(1); // update-in-progress never transitioned to 0
12684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
12694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
12724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaread_byte(seg, offset)
12734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u seg;
12744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u offset;
12754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
12764d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
12774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
12784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
12794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bx
12814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ds
12824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, 4[bp] ; segment
12834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ds, ax
12844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bx, 6[bp] ; offset
12854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, [bx]
12864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; al = return value (byte)
12874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ds
12884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bx
12894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
12914d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
12924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
12934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
12944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
12954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaread_word(seg, offset)
12964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u seg;
12974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u offset;
12984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
12994d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
13004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
13014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
13024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bx
13044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ds
13054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, 4[bp] ; segment
13064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ds, ax
13074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bx, 6[bp] ; offset
13084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, [bx]
13094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; ax = return value (word)
13104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ds
13114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bx
13124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
13144d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
13154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
13164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
13184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimawrite_byte(seg, offset, data)
13194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u seg;
13204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u offset;
13214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u data;
13224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
13234d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
13244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
13254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
13264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
13284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bx
13294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ds
13304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, 4[bp] ; segment
13314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ds, ax
13324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bx, 6[bp] ; offset
13334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, 8[bp] ; data byte
13344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  [bx], al  ; write data byte
13354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ds
13364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bx
13374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ax
13384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
13404d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
13414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
13424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
13444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimawrite_word(seg, offset, data)
13454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u seg;
13464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u offset;
13474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u data;
13484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
13494d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
13504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
13514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
13524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
13544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bx
13554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ds
13564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, 4[bp] ; segment
13574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ds, ax
13584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bx, 6[bp] ; offset
13594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, 8[bp] ; data word
13604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  [bx], ax  ; write data word
13614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ds
13624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bx
13634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ax
13644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
13664d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
13674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
13684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
13704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaget_CS()
13714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
13724d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
13734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, cs
13744d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
13754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
13764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
13784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaget_SS()
13794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
13804d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
13814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, ss
13824d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
13834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
13844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_DEBUG_SERIAL
13864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* serial debug port*/
13874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BX_DEBUG_PORT 0x03f8
13884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* data */
13904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_RBR 0x00
13914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_THR 0x00
13924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
13934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* control */
13944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_IER 0x01
13954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_IIR 0x02
13964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_FCR 0x02
13974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_LCR 0x03
13984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_MCR 0x04
13994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_DLL 0x00
14004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_DLM 0x01
14014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* status */
14034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_LSR 0x05
14044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_MSR 0x06
14054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define UART_SCR 0x07
14064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint uart_can_tx_byte(base_port)
14084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u base_port;
14094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return inb(base_port + UART_LSR) & 0x20;
14114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid uart_wait_to_tx_byte(base_port)
14144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u base_port;
14154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while (!uart_can_tx_byte(base_port));
14174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid uart_wait_until_sent(base_port)
14204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u base_port;
14214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while (!(inb(base_port + UART_LSR) & 0x40));
14234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid uart_tx_byte(base_port, data)
14264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u base_port;
14274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u data;
14284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    uart_wait_to_tx_byte(base_port);
14304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(base_port + UART_THR, data);
14314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    uart_wait_until_sent(base_port);
14324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
14344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
14364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimawrch(c)
14374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  c;
14384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
14404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
14414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
14424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx
14444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, #0x0e
14454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, 4[bp]
14464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  bx,bx
14474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  #0x10
14484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bx
14494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
14514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
14524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
14554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimasend(action, c)
14564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u action;
14574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  c;
14584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_DEBUG_SERIAL
14604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r');
14614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  uart_tx_byte(BX_DEBUG_PORT, c);
14624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
14634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_VIRTUAL_PORTS
14644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (action & BIOS_PRINTF_DEBUG) outb(DEBUG_PORT, c);
14654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (action & BIOS_PRINTF_INFO) outb(INFO_PORT, c);
14664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
14674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (action & BIOS_PRINTF_SCREEN) {
14684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (c == '\n') wrch('\r');
14694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    wrch(c);
14704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
14714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
14744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaput_int(action, val, width, neg)
14754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u action;
14764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  short val, width;
14774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool neg;
14784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  short nval = val / 10;
14804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (nval)
14814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    put_int(action, nval, width - 1, neg);
14824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
14834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while (--width > 0) send(action, ' ');
14844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (neg) send(action, '-');
14854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
14864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  send(action, val - (nval * 10) + '0');
14874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
14884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
14894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
14904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaput_uint(action, val, width, neg)
14914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u action;
14924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned short val;
14934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  short width;
14944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool neg;
14954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
14964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned short nval = val / 10;
14974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (nval)
14984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    put_uint(action, nval, width - 1, neg);
14994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
15004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while (--width > 0) send(action, ' ');
15014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (neg) send(action, '-');
15024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
15034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  send(action, val - (nval * 10) + '0');
15044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
15054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
15074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaput_luint(action, val, width, neg)
15084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u action;
15094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned long val;
15104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  short width;
15114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool neg;
15124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
15134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned long nval = val / 10;
15144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (nval)
15154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    put_luint(action, nval, width - 1, neg);
15164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
15174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while (--width > 0) send(action, ' ');
15184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (neg) send(action, '-');
15194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
15204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  send(action, val - (nval * 10) + '0');
15214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
15224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid put_str(action, segment, offset)
15244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u action;
15254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u segment;
15264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u offset;
15274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
15284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u c;
15294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (c = read_byte(segment, offset)) {
15314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    send(action, c);
15324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    offset++;
15334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
15344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
15354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
15374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadelay_ticks(ticks)
15384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ticks;
15394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
15404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  long ticks_to_wait, delta;
15414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u prev_ticks, t;
15424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   /*
15444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock.
15454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    * We also have to be careful about interrupt storms.
15464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    */
15474d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
15484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushf
15494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
15504d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
15514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ticks_to_wait = ticks;
15524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  prev_ticks = read_dword(0x0, 0x46c);
15534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  do
15544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
15554d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
15564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hlt
15574d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
15584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    t = read_dword(0x0, 0x46c);
15594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (t > prev_ticks)
15604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    {
15614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      delta = t - prev_ticks;     /* The temp var is required or bcc screws up. */
15624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ticks_to_wait -= delta;
15634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
15644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (t < prev_ticks)
15654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    {
15664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ticks_to_wait -= t;         /* wrapped */
15674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
15684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    prev_ticks = t;
15704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } while (ticks_to_wait > 0);
15714d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
15724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
15734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popf
15744d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
15754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
15764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
15784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacheck_for_keystroke()
15794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
15804d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
15814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x100
15824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  #0x16
15834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   no_key
15844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #1
15854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  done
15864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimano_key:
15874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  al, al
15884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadone:
15894d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
15904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
15914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
15924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
15934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaget_keystroke()
15944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
15954d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
15964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x0
15974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  #0x16
15984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xchg ah, al
15994d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
16004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
16014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
16024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
16034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadelay_ticks_and_check_for_keystroke(ticks, count)
16044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ticks, count;
16054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
16064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u i;
16074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for (i = 1; i <= count; i++) {
16084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    delay_ticks(ticks);
16094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (check_for_keystroke())
16104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
16114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
16124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
16134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
16144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
16154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// bios_printf()
16164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   A compact variable argument printf function.
16174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
16184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   Supports %[format_width][length]format
16194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   where format can be x,X,u,d,s,S,c
16204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   and the optional length modifier is l (ell)
16214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
16224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
16234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabios_printf(action, s)
16244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u action;
16254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u *s;
16264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
16274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u c, format_char;
16284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool  in_format;
16294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  short i;
16304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  *arg_ptr;
16314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   arg_seg, arg, nibble, hibyte, shift_count, format_width, hexadd;
16324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
16334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  arg_ptr = &s;
16344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  arg_seg = get_SS();
16354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
16364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in_format = 0;
16374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  format_width = 0;
16384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
16394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) {
16404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_VIRTUAL_PORTS
16414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(PANIC_PORT2, 0x00);
16424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
16434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bios_printf (BIOS_PRINTF_SCREEN, "FATAL: ");
16444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
16454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
16464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (c = read_byte(get_CS(), s)) {
16474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ( c == '%' ) {
16484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      in_format = 1;
16494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      format_width = 0;
16504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
16514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (in_format) {
16524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (c>='0') && (c<='9') ) {
16534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        format_width = (format_width * 10) + (c - '0');
16544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
16554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
16564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        arg_ptr++; // increment to next arg
16574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        arg = read_word(arg_seg, arg_ptr);
16584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (c == 'x' || c == 'X') {
16594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (format_width == 0)
16604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            format_width = 4;
16614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (c == 'x')
16624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            hexadd = 'a';
16634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else
16644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            hexadd = 'A';
16654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          for (i=format_width-1; i>=0; i--) {
16664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            nibble = (arg >> (4 * i)) & 0x000f;
16674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
16684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
16694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
16704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (c == 'u') {
16714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          put_uint(action, arg, format_width, 0);
16724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
16734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (c == 'l') {
16744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          s++;
16754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          c = read_byte(get_CS(), s); /* is it ld,lx,lu? */
16764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          arg_ptr++; /* increment to next arg */
16774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          hibyte = read_word(arg_seg, arg_ptr);
16784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (c == 'd') {
16794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (hibyte & 0x8000)
16804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              put_luint(action, 0L-(((Bit32u) hibyte << 16) | arg), format_width-1, 1);
16814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            else
16824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
16834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           }
16844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else if (c == 'u') {
16854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
16864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           }
16874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else if (c == 'x' || c == 'X')
16884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           {
16894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (format_width == 0)
16904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              format_width = 8;
16914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (c == 'x')
16924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              hexadd = 'a';
16934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            else
16944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              hexadd = 'A';
16954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            for (i=format_width-1; i>=0; i--) {
16964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f;
16974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
16984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              }
16994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           }
17004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
17014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (c == 'd') {
17024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (arg & 0x8000)
17034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            put_int(action, -arg, format_width - 1, 1);
17044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else
17054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            put_int(action, arg, format_width, 0);
17064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
17074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (c == 's') {
17084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          put_str(action, get_CS(), arg);
17094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
17104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (c == 'S') {
17114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          hibyte = arg;
17124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          arg_ptr++;
17134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          arg = read_word(arg_seg, arg_ptr);
17144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          put_str(action, hibyte, arg);
17154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
17164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (c == 'c') {
17174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          send(action, arg);
17184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
17194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else
17204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_PANIC("bios_printf: unknown format\n");
17214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          in_format = 0;
17224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
17234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
17244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else {
17254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      send(action, c);
17264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
17274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    s ++;
17284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
17294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (action & BIOS_PRINTF_HALT) {
17314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // freeze in a busy loop.
17324d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
17334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cli
17344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima halt2_loop:
17354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hlt
17364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    jmp halt2_loop
17374d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
17384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
17394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
17404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
17424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// keyboard_init
17434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
17444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// this file is based on LinuxBIOS implementation of keyboard.c
17454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// could convert to #asm to gain space
17464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
17474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimakeyboard_init()
17484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
17494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u max;
17504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* ------------------- Flush buffers ------------------------*/
17524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
17534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
17544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
17554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* flush incoming keys */
17574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0x2000;
17584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while (--max > 0) {
17594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x80, 0x00);
17604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (inb(0x64) & 0x01) {
17614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            inb(0x60);
17624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            max = 0x2000;
17634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
17644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
17654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Due to timer issues, and if the IPS setting is > 15000000,
17674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // the incoming keys might not be flushed here. That will
17684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // cause a panic a few lines below.  See sourceforge bug report :
17694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // [ 642031 ] FATAL: Keyboard RESET error:993
17704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* ------------------- controller side ----------------------*/
17724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* send cmd = 0xAA, self test 8042 */
17734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x64, 0xaa);
17744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
17764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
17774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
17784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(00);
17794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait for data */
17814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
17824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x01);
17834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(01);
17844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* read self-test result, 0x55 should be returned from 0x60 */
17864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) != 0x55)){
17874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        keyboard_panic(991);
17884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
17894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* send cmd = 0xAB, keyboard interface test */
17914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x64,0xab);
17924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
17944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
17954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x10);
17964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(10);
17974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
17984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait for data */
17994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x11);
18014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(11);
18024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* read keyboard interface test result, */
18044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* 0x00 should be returned form 0x60 */
18054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) != 0x00)) {
18064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        keyboard_panic(992);
18074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
18084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Enable Keyboard clock */
18104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x64,0xae);
18114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x64,0xa8);
18124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* ------------------- keyboard side ------------------------*/
18144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* reset kerboard and self test  (keyboard side) */
18154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x60, 0xff);
18164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
18184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x20);
18204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(20);
18214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait for data */
18234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x21);
18254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(21);
18264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* keyboard should return ACK */
18284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) != 0xfa)) {
18294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        keyboard_panic(993);
18304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
18314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait for data */
18334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x31);
18354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(31);
18364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) != 0xaa)) {
18384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        keyboard_panic(994);
18394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
18404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Disable keyboard */
18424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x60, 0xf5);
18434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
18454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x40);
18474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(40);
18484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait for data */
18504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x41);
18524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(41);
18534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* keyboard should return ACK */
18554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) != 0xfa)) {
18564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        keyboard_panic(995);
18574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
18584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Write Keyboard Mode */
18604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x64, 0x60);
18614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
18634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x50);
18654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(50);
18664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* send cmd: scan code convert, disable mouse, enable IRQ 1 */
18684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x60, 0x61);
18694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
18714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x60);
18734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(60);
18744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Enable keyboard */
18764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x60, 0xf4);
18774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait until buffer is empty */
18794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x70);
18814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(70);
18824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Wait for data */
18844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    max=0xffff;
18854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x71);
18864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (max==0x0) keyboard_panic(70);
18874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* keyboard should return ACK */
18894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) != 0xfa)) {
18904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        keyboard_panic(996);
18914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
18924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x80, 0x77);
18944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
18954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
18964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
18974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// keyboard_panic
18984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
18994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
19004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimakeyboard_panic(status)
19014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u status;
19024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
19034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // If you're getting a 993 keyboard panic here,
19044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // please see the comment in keyboard_init
19054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_PANIC("Keyboard error:%u\n",status);
19074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
19084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
19104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// shutdown_status_panic
19114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   called when the shutdown statsu is not implemented, displays the status
19124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
19134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
19144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimashutdown_status_panic(status)
19154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u status;
19164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
19174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status);
19184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
19194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid s3_resume_panic()
19214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
19224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_PANIC("Returned from s3_resume.\n");
19234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
19244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
19264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// print_bios_banner
19274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   displays a the bios version
19284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
19294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid
19304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaprint_bios_banner()
19314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
19324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ",
19334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BIOS_BUILD_DATE, bios_cvs_version_string);
19344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf(
19354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_APM
19364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  "apmbios "
19374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
19384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_PCIBIOS
19394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  "pcibios "
19404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
19414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
19424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  "eltorito "
19434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
19444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ROMBIOS32
19454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  "rombios32 "
19464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
19474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  "\n\n");
19484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
19494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
19514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// BIOS Boot Specification 1.0.1 compatibility
19524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
19534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Very basic support for the BIOS Boot Specification, which allows expansion
19544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ROMs to register themselves as boot devices, instead of just stealing the
19554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// INT 19h boot vector.
19564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
19574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// This is a hack: to do it properly requires a proper PnP BIOS and we aren't
19584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// one; we just lie to the option ROMs to make them behave correctly.
19594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// We also don't support letting option ROMs register as bootable disk
19604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// drives (BCVs), only as bootable devices (BEVs).
19614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
19624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm
19634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
19644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"};
19664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void
19684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainit_boot_vectors()
19694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
19704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ipl_entry_t e;
19714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u count = 0;
19724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss = get_SS();
19734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Clear out the IPL table. */
19754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE);
19764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* User selected device not set */
19784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF);
19794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Floppy drive */
19814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
19824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
19834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  count++;
19844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* First HDD */
19864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
19874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
19884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  count++;
19894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
19914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* CDROM */
19924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  e.type = IPL_TYPE_CDROM; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
19934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
19944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  count++;
19954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
19964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
19974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Remember how many devices we have */
19984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(IPL_SEG, IPL_COUNT_OFFSET, count);
19994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Not tried booting anything yet */
20004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff);
20014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
20024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u
20044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaget_boot_vector(i, e)
20054d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u i; ipl_entry_t *e;
20064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
20074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u count;
20084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss = get_SS();
20094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Get the count of boot devices, and refuse to overrun the array */
20104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
20114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (i >= count) return 0;
20124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* OK to read this device */
20134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
20144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 1;
20154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
20164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
20184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
20194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainteractive_bootkey()
20204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
20214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ipl_entry_t e;
20224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u count;
20234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  char description[33];
20244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u scan_code;
20254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u i;
20264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss = get_SS();
20274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u valid_choice = 0;
20284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (check_for_keystroke())
20304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    get_keystroke();
20314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf("Press F12 for boot menu.\n\n");
20334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */
20354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (check_for_keystroke())
20364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
20374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    scan_code = get_keystroke();
20384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (scan_code == 0x86) /* F12 */
20394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    {
20404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (check_for_keystroke())
20414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        get_keystroke();
20424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf("Select boot device:\n\n");
20444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
20464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      for (i = 0; i < count; i++)
20474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {
20484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e));
20494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        printf("%d. ", i+1);
20504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        switch(e.type)
20514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        {
20524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          case IPL_TYPE_FLOPPY:
20534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          case IPL_TYPE_HARDDISK:
20544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          case IPL_TYPE_CDROM:
20554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            printf("%s\n", drivetypes[e.type]);
20564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            break;
20574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          case IPL_TYPE_BEV:
20584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            printf("%s", drivetypes[4]);
20594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (e.description != 0)
20604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            {
20614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32);
20624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              description[32] = 0;
20634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              printf(" [%S]", ss, description);
20644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           }
20654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           printf("\n");
20664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           break;
20674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
20684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
20694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count++;
20714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (!valid_choice) {
20724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        scan_code = get_keystroke();
20734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */
20744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        {
20754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          valid_choice = 1;
20764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
20774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (scan_code <= count)
20784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        {
20794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          valid_choice = 1;
20804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          scan_code -= 1;
20814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          /* Set user selected device */
20824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code);
20834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
20844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
20854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("\n");
20864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
20874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
20884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
20894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
20904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
20924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// print_boot_device
20934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   displays the boot device
20944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
20954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
20964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid
20974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaprint_boot_device(e)
20984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ipl_entry_t *e;
20994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u type;
21014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  char description[33];
21024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss = get_SS();
21034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  type = e->type;
21044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* NIC appears as type 0x80 */
21054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (type == IPL_TYPE_BEV) type = 0x4;
21064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");
21074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf("Booting from %s", drivetypes[type]);
21084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* print product string if BEV */
21094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (type == 4 && e->description != 0) {
21104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* first 32 bytes are significant */
21114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    memcpyb(ss, &description, (Bit16u)(e->description >> 16), (Bit16u)(e->description & 0xffff), 32);
21124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* terminate string */
21134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    description[32] = 0;
21144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf(" [%S]", ss, description);
21154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
21164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf("...\n");
21174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
21204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// print_boot_failure
21214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   displays the reason why boot failed
21224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
21234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
21244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaprint_boot_failure(type, reason)
21254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u type; Bit8u reason;
21264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n");
21284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf("Boot failed");
21304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (type < 4) {
21314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Report the reason too */
21324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (reason==0)
21334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf(": not a bootable disk");
21344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else
21354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf(": could not read the boot disk");
21364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
21374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf("\n\n");
21384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
21414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// print_cdromboot_failure
21424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//   displays the reason why boot failed
21434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//--------------------------------------------------------------------------
21444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
21454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaprint_cdromboot_failure( code )
21464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u code;
21474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "CDROM boot failure code : %04x\n",code);
21494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return;
21514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid
21544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanmi_handler_msg()
21554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_PANIC("NMI Handler called\n");
21574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid
21604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint18_panic_msg()
21614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_PANIC("INT18: BOOT FAILURE\n");
21634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid
21664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalog_bios_start()
21674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_DEBUG_SERIAL
21694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(BX_DEBUG_PORT+UART_LCR, 0x03); /* setup for serial logging: 8N1 */
21704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
21714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_INFO("%s\n", bios_cvs_version_string);
21724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool
21754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaset_enable_a20(val)
21764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool val;
21774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  oldval;
21794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Use PS2 System Control port A to set A20 enable
21814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // get current setting first
21834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  oldval = inb(0x92);
21844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // change A20 status
21864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (val)
21874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x92, oldval | 0x02);
21884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
21894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x92, oldval & 0xfd);
21904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return((oldval & 0x02) != 0);
21924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
21944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
21954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadebugger_on()
21964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
21974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0xfedc, 0x01);
21984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
21994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
22014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadebugger_off()
22024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
22034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0xfedc, 0x00);
22044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
22054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint
22074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimas3_resume()
22084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
22094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit32u s3_wakeup_vector;
22104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u s3_resume_flag;
22114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    s3_resume_flag = read_byte(0x40, 0xb0);
22134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    s3_wakeup_vector = read_dword(0x40, 0xb2);
22144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("S3 resume called %x 0x%lx\n", s3_resume_flag, s3_wakeup_vector);
22164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (s3_resume_flag != 0xFE || !s3_wakeup_vector)
22174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima	    return 0;
22184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(0x40, 0xb0, 0);
22204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* setup wakeup vector */
22224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(0x40, 0xb6, (s3_wakeup_vector & 0xF)); /* IP */
22234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(0x40, 0xb8, (s3_wakeup_vector >> 4)); /* CS */
22244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("S3 resume jump to %x:%x\n", (s3_wakeup_vector >> 4),
22264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima		    (s3_wakeup_vector & 0xF));
22274d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
22284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    jmpf [0x04b6]
22294d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
22304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 1;
22314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
22324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
22344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
22364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Start of ATA/ATAPI Driver
22374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
22384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Global defines -- ATA register and register bits.
22404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// command block & control block regs
22414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DATA  0   // data reg         in/out pio_base_addr1+0
22424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ERR   1   // error            in     pio_base_addr1+1
22434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_FR    1   // feature reg         out pio_base_addr1+1
22444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_SC    2   // sector count     in/out pio_base_addr1+2
22454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_SN    3   // sector number    in/out pio_base_addr1+3
22464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_CL    4   // cylinder low     in/out pio_base_addr1+4
22474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_CH    5   // cylinder high    in/out pio_base_addr1+5
22484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DH    6   // device head      in/out pio_base_addr1+6
22494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT  7   // primary status   in     pio_base_addr1+7
22504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_CMD   7   // command             out pio_base_addr1+7
22514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ASTAT 6   // alternate status in     pio_base_addr2+6
22524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DC    6   // device control      out pio_base_addr2+6
22534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DA    7   // device address   in     pio_base_addr2+7
22544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_ICRC 0x80    // ATA Ultra DMA bad CRC
22564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_BBK  0x80    // ATA bad block
22574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_UNC  0x40    // ATA uncorrected error
22584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_MC   0x20    // ATA media change
22594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_IDNF 0x10    // ATA id not found
22604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_MCR  0x08    // ATA media change request
22614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_ABRT 0x04    // ATA command aborted
22624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_NTK0 0x02    // ATA track 0 not found
22634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_NDAM 0x01    // ATA address mark not found
22644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_P_SNSKEY 0xf0   // ATAPI sense key (mask)
22664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_P_MCR    0x08   // ATAPI Media Change Request
22674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_P_ABRT   0x04   // ATAPI command abort
22684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_P_EOM    0x02   // ATAPI End of Media
22694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_ER_P_ILI    0x01   // ATAPI Illegal Length Indication
22704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATAPI Interrupt Reason bits in the Sector Count reg (CB_SC)
22724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_SC_P_TAG    0xf8   // ATAPI tag (mask)
22734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_SC_P_REL    0x04   // ATAPI release
22744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_SC_P_IO     0x02   // ATAPI I/O
22754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_SC_P_CD     0x01   // ATAPI C/D
22764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// bits 7-4 of the device/head (CB_DH) reg
22784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DH_DEV0 0xa0    // select device 0
22794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DH_DEV1 0xb0    // select device 1
22804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DH_LBA 0x40    // use LBA
22814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// status reg (CB_STAT and CB_ASTAT) bits
22834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_BSY  0x80  // busy
22844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_RDY  0x40  // ready
22854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_DF   0x20  // device fault
22864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_WFT  0x20  // write fault (old name)
22874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_SKC  0x10  // seek complete
22884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_SERV 0x10  // service
22894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_DRQ  0x08  // data request
22904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_CORR 0x04  // corrected
22914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_IDX  0x02  // index
22924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_ERR  0x01  // error (ATA)
22934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_STAT_CHK  0x01  // check (ATAPI)
22944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
22954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// device control reg (CB_DC) bits
22964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DC_HD15   0x08  // bit should always be set to one
22974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DC_SRST   0x04  // soft reset
22984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CB_DC_NIEN   0x02  // disable interrupts
22994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Most mandtory and optional ATA commands (from ATA-3),
23014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CFA_ERASE_SECTORS            0xC0
23024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CFA_REQUEST_EXT_ERR_CODE     0x03
23034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CFA_TRANSLATE_SECTOR         0x87
23044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CFA_WRITE_MULTIPLE_WO_ERASE  0xCD
23054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CFA_WRITE_SECTORS_WO_ERASE   0x38
23064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CHECK_POWER_MODE1            0xE5
23074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_CHECK_POWER_MODE2            0x98
23084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_DEVICE_RESET                 0x08
23094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC    0x90
23104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_FLUSH_CACHE                  0xE7
23114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_FORMAT_TRACK                 0x50
23124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDENTIFY_DEVICE              0xEC
23134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDENTIFY_DEVICE_PACKET       0xA1
23144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDENTIFY_PACKET_DEVICE       0xA1
23154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDLE1                        0xE3
23164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDLE2                        0x97
23174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDLE_IMMEDIATE1              0xE1
23184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_IDLE_IMMEDIATE2              0x95
23194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_INITIALIZE_DRIVE_PARAMETERS  0x91
23204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91
23214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_NOP                          0x00
23224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_PACKET                       0xA0
23234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_READ_BUFFER                  0xE4
23244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_READ_DMA                     0xC8
23254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_READ_DMA_QUEUED              0xC7
23264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_READ_MULTIPLE                0xC4
23274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_READ_SECTORS                 0x20
23284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_READ_VERIFY_SECTORS          0x40
23294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_RECALIBRATE                  0x10
23304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_REQUEST_SENSE                0x03
23314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_SEEK                         0x70
23324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_SET_FEATURES                 0xEF
23334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_SET_MULTIPLE_MODE            0xC6
23344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_SLEEP1                       0xE6
23354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_SLEEP2                       0x99
23364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_STANDBY1                     0xE2
23374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_STANDBY2                     0x96
23384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_STANDBY_IMMEDIATE1           0xE0
23394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_STANDBY_IMMEDIATE2           0x94
23404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_WRITE_BUFFER                 0xE8
23414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_WRITE_DMA                    0xCA
23424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_WRITE_DMA_QUEUED             0xCC
23434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_WRITE_MULTIPLE               0xC5
23444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_WRITE_SECTORS                0x30
23454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_CMD_WRITE_VERIFY                 0x3C
23464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_IFACE_NONE    0x00
23484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_IFACE_ISA     0x00
23494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_IFACE_PCI     0x01
23504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TYPE_NONE     0x00
23524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TYPE_UNKNOWN  0x01
23534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TYPE_ATA      0x02
23544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TYPE_ATAPI    0x03
23554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_DEVICE_NONE  0x00
23574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_DEVICE_HD    0xFF
23584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_DEVICE_CDROM 0x05
23594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_MODE_NONE    0x00
23614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_MODE_PIO16   0x00
23624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_MODE_PIO32   0x01
23634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_MODE_ISADMA  0x02
23644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_MODE_PCIDMA  0x03
23654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_MODE_USEIRQ  0x10
23664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TRANSLATION_NONE  0
23684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TRANSLATION_LBA   1
23694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TRANSLATION_LARGE 2
23704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_TRANSLATION_RECHS 3
23714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_DATA_NO      0x00
23734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_DATA_IN      0x01
23744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define ATA_DATA_OUT     0x02
23754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
23774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : initialization
23784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
23794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid ata_init( )
23804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
23814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
23824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  channel, device;
23834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Channels info init.
23854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) {
23864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.channels[channel].iface,ATA_IFACE_NONE);
23874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1,0x0);
23884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2,0x0);
23894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.channels[channel].irq,0);
23904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
23914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
23924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Devices info init.
23934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for (device=0; device<BX_MAX_ATA_DEVICES; device++) {
23944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE);
23954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_NONE);
23964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.devices[device].removable,0);
23974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.devices[device].lock,0);
23984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.devices[device].mode,ATA_MODE_NONE);
23994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0);
24004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.devices[device].translation,ATA_TRANSLATION_NONE);
24014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads,0);
24024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders,0);
24034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt,0);
24044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads,0);
24054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders,0);
24064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt,0);
24074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low,0L);
24094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high,0L);
24104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
24114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // hdidmap  and cdidmap init.
24134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for (device=0; device<BX_MAX_ATA_DEVICES; device++) {
24144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.hdidmap[device],BX_MAX_ATA_DEVICES);
24154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->ata.cdidmap[device],BX_MAX_ATA_DEVICES);
24164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
24174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.hdcount,0);
24194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.cdcount,0);
24204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
24214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define TIMEOUT 0
24234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BSY 1
24244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define NOT_BSY 2
24254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define NOT_BSY_DRQ 3
24264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define NOT_BSY_NOT_DRQ 4
24274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define NOT_BSY_RDY 5
24284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IDE_TIMEOUT 32000u //32 seconds max for IDE ops
24304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint await_ide();
24324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic int await_ide(when_done,base,timeout)
24334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u when_done;
24344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u base;
24354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u timeout;
24364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
24374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u time=0,last=0;
24384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u status;
24394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u result;
24404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(base + ATA_CB_STAT); // for the times you're supposed to throw one away
24414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for(;;) {
24424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = inb(base+ATA_CB_STAT);
24434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    time++;
24444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (when_done == BSY)
24454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = status & ATA_CB_STAT_BSY;
24464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (when_done == NOT_BSY)
24474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = !(status & ATA_CB_STAT_BSY);
24484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (when_done == NOT_BSY_DRQ)
24494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ);
24504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (when_done == NOT_BSY_NOT_DRQ)
24514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ);
24524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (when_done == NOT_BSY_RDY)
24534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY);
24544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else if (when_done == TIMEOUT)
24554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = 0;
24564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (result) return 0;
24584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (time>>16 != last) // mod 2048 each 16 ms
24594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    {
24604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      last = time >>16;
24614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_DEBUG_ATA("await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout);
24624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
24634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (status & ATA_CB_STAT_ERR)
24644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    {
24654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_DEBUG_ATA("await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout);
24664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return -1;
24674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
24684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((timeout == 0) || ((time>>11) > timeout)) break;
24694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
24704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_INFO("IDE time out\n");
24714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return -1;
24724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
24734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
24754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : device detection
24764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
24774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid ata_detect( )
24794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
24804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
24814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  hdcount, cdcount, device, type;
24824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  buffer[0x0200];
24834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
24844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_MAX_ATA_INTERFACES > 0
24854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[0].iface,ATA_IFACE_ISA);
24864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[0].iobase1,0x1f0);
24874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[0].iobase2,0x3f0);
24884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[0].irq,14);
24894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
24904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_MAX_ATA_INTERFACES > 1
24914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[1].iface,ATA_IFACE_ISA);
24924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[1].iobase1,0x170);
24934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[1].iobase2,0x370);
24944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[1].irq,15);
24954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
24964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_MAX_ATA_INTERFACES > 2
24974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[2].iface,ATA_IFACE_ISA);
24984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[2].iobase1,0x1e8);
24994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[2].iobase2,0x3e0);
25004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[2].irq,12);
25014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
25024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_MAX_ATA_INTERFACES > 3
25034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[3].iface,ATA_IFACE_ISA);
25044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[3].iobase1,0x168);
25054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->ata.channels[3].iobase2,0x360);
25064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.channels[3].irq,11);
25074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
25084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_MAX_ATA_INTERFACES > 4
25094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#error Please fill the ATA interface informations
25104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
25114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Device detection
25134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  hdcount=cdcount=0;
25144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for(device=0; device<BX_MAX_ATA_DEVICES; device++) {
25164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit16u iobase1, iobase2;
25174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  channel, slave, shift;
25184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Bit8u  sc, sn, cl, ch, st;
25194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    channel = device / 2;
25214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    slave = device % 2;
25224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    iobase1 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1);
25244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    iobase2 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2);
25254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Disable interrupts
25274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
25284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Look for device
25304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
25314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_SC, 0x55);
25324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_SN, 0xaa);
25334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_SC, 0xaa);
25344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_SN, 0x55);
25354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_SC, 0x55);
25364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_SN, 0xaa);
25374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // If we found something
25394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sc = inb(iobase1+ATA_CB_SC);
25404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sn = inb(iobase1+ATA_CB_SN);
25414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ( (sc == 0x55) && (sn == 0xaa) ) {
25434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_UNKNOWN);
25444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // reset the channel
25464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ata_reset(device);
25474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // check for ATA or ATAPI
25494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
25504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sc = inb(iobase1+ATA_CB_SC);
25514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sn = inb(iobase1+ATA_CB_SN);
25524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((sc==0x01) && (sn==0x01)) {
25534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cl = inb(iobase1+ATA_CB_CL);
25544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ch = inb(iobase1+ATA_CB_CH);
25554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        st = inb(iobase1+ATA_CB_STAT);
25564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ((cl==0x14) && (ch==0xeb)) {
25584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATAPI);
25594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) {
25604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATA);
25614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else if ((cl==0xff) && (ch==0xff)) {
25624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE);
25634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
25644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
25654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
25664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type);
25684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Now we send a IDENTIFY command to ATA device
25704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if(type == ATA_TYPE_ATA) {
25714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit32u sectors_low, sectors_high;
25724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u cylinders, heads, spt, blksize;
25734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit8u  translation, removable, mode;
25744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //Temporary values to do the transfer
25764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD);
25774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16);
25784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) !=0 )
25804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("ata-detect: Failed to detect ATA device\n");
25814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0;
25834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mode      = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
25844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      blksize   = read_word(get_SS(),buffer+10);
25854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinders = read_word(get_SS(),buffer+(1*2)); // word 1
25874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      heads     = read_word(get_SS(),buffer+(3*2)); // word 3
25884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      spt       = read_word(get_SS(),buffer+(6*2)); // word 6
25894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (read_word(get_SS(),buffer+(83*2)) & (1 << 10)) { // word 83 - lba48 support
25914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sectors_low  = read_dword(get_SS(),buffer+(100*2)); // word 100 and word 101
25924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sectors_high = read_dword(get_SS(),buffer+(102*2)); // word 102 and word 103
25934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else {
25944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sectors_low = read_dword(get_SS(),buffer+(60*2)); // word 60 and word 61
25954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sectors_high = 0;
25964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
25974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
25984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD);
25994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable);
26004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode);
26014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize);
26024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads, heads);
26034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders, cylinders);
26044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt, spt);
26054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors_low);
26064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high, sectors_high);
26074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation=", channel, slave,cylinders, heads, spt);
26084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      translation = inb_cmos(0x39 + channel/2);
26104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      for (shift=device%4; shift>0; shift--) translation >>= 2;
26114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      translation &= 0x03;
26124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].translation, translation);
26144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (translation) {
26164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_NONE:
26174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("none");
26184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_LBA:
26204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("lba");
26214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_LARGE:
26234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("large");
26244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_RECHS:
26264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("r-echs");
26274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
26294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (translation) {
26304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_NONE:
26314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_LBA:
26334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          spt = 63;
26344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          sectors_low /= 63;
26354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          heads = sectors_low / 1024;
26364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (heads>128) heads = 255;
26374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else if (heads>64) heads = 128;
26384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else if (heads>32) heads = 64;
26394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else if (heads>16) heads = 32;
26404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else heads=16;
26414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinders = sectors_low / heads;
26424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_RECHS:
26444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Take care not to overflow
26454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (heads==16) {
26464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if(cylinders>61439) cylinders=61439;
26474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            heads=15;
26484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            cylinders = (Bit16u)((Bit32u)(cylinders)*16/15);
26494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
26504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // then go through the large bitshift process
26514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TRANSLATION_LARGE:
26524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          while(cylinders > 1024) {
26534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            cylinders >>= 1;
26544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            heads <<= 1;
26554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // If we max out the head count
26574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (heads > 127) break;
26584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
26594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
26604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
26614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // clip to 1024 cylinders in lchs
26624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (cylinders > 1024) cylinders=1024;
26634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO(" LCHS=%d/%d/%d\n", cylinders, heads, spt);
26644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads, heads);
26664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders, cylinders);
26674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt, spt);
26684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // fill hdidmap
26704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.hdidmap[hdcount], device);
26714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      hdcount++;
26724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
26734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Now we send a IDENTIFY command to ATAPI device
26754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if(type == ATA_TYPE_ATAPI) {
26764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit8u  type, removable, mode;
26784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u blksize;
26794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //Temporary values to do the transfer
26814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_CDROM);
26824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16);
26834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE_PACKET, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) != 0)
26854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
26864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      type      = read_byte(get_SS(),buffer+1) & 0x1f;
26884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0;
26894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mode      = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
26904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      blksize   = 2048;
26914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].device, type);
26934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable);
26944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode);
26954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize);
26964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
26974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // fill cdidmap
26984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg,&EbdaData->ata.cdidmap[cdcount], device);
26994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cdcount++;
27004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
27014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      {
27034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit32u sizeinmb;
27044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit16u ataversion;
27054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      Bit8u  c, i, version, model[41];
27064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (type) {
27084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TYPE_ATA:
27094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          sizeinmb = (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high) << 21)
27104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            | (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low) >> 11);
27114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TYPE_ATAPI:
27124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Read ATA/ATAPI version
27134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          ataversion=((Bit16u)(read_byte(get_SS(),buffer+161))<<8)|read_byte(get_SS(),buffer+160);
27144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          for(version=15;version>0;version--) {
27154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if((ataversion&(1<<version))!=0)
27164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            break;
27174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
27184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Read model name
27204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          for(i=0;i<20;i++){
27214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            write_byte(get_SS(),model+(i*2),read_byte(get_SS(),buffer+(i*2)+54+1));
27224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            write_byte(get_SS(),model+(i*2)+1,read_byte(get_SS(),buffer+(i*2)+54));
27234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
27244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Reformat
27264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(get_SS(),model+40,0x00);
27274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          for(i=39;i>0;i--){
27284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if(read_byte(get_SS(),model+i)==0x20)
27294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              write_byte(get_SS(),model+i,0x00);
27304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            else break;
27314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
27324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (i>36) {
27334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            write_byte(get_SS(),model+36,0x00);
27344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            for(i=35;i>32;i--){
27354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              write_byte(get_SS(),model+i,0x2E);
27364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
27374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
27384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
27394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
27404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (type) {
27424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TYPE_ATA:
27434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          printf("ata%d %s: ",channel,slave?" slave":"master");
27444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c);
27454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima	  if (sizeinmb < (1UL<<16))
27464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            printf(" ATA-%d Hard-Disk (%4u MBytes)\n", version, (Bit16u)sizeinmb);
27474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima	  else
27484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            printf(" ATA-%d Hard-Disk (%4u GBytes)\n", version, (Bit16u)(sizeinmb>>10));
27494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
27504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TYPE_ATAPI:
27514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          printf("ata%d %s: ",channel,slave?" slave":"master");
27524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c);
27534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if(read_byte(ebda_seg,&EbdaData->ata.devices[device].device)==ATA_DEVICE_CDROM)
27544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            printf(" ATAPI-%d CD-Rom/DVD-Rom\n",version);
27554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else
27564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            printf(" ATAPI-%d Device\n",version);
27574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
27584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case ATA_TYPE_UNKNOWN:
27594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master");
27604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
27614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
27624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
27634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
27644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Store the devices counts
27664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.hdcount, hdcount);
27674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->ata.cdcount, cdcount);
27684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x40,0x75, hdcount);
27694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  printf("\n");
27714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // FIXME : should use bios=cmos|auto|disable bits
27734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // FIXME : should know about translation bits
27744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // FIXME : move hard_drive_post here
27754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
27774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
27794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : software reset
27804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
27814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA-3
27824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// 8.2.1 Software reset - Device 0
27834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid   ata_reset(device)
27854d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u device;
27864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
27874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
27884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u iobase1, iobase2;
27894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  channel, slave, sn, sc;
27904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  type;
27914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u max;
27924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  channel = device / 2;
27944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  slave = device % 2;
27954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
27974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
27984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
27994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Reset
28004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// 8.2.1 (a) -- set SRST in DC
28024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST);
28034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// 8.2.1 (b) -- wait for BSY
28054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  await_ide(BSY, iobase1, 20);
28064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// 8.2.1 (f) -- clear SRST
28084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
28094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type);
28114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (type != ATA_TYPE_NONE) {
28124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// 8.2.1 (g) -- check for sc==sn==0x01
28144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // select device
28154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0);
28164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sc = inb(iobase1+ATA_CB_SC);
28174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sn = inb(iobase1+ATA_CB_SN);
28184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ( (sc==0x01) && (sn==0x01) ) {
28204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (type == ATA_TYPE_ATA) //ATA
28214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT);
28224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else //ATAPI
28234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
28244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
28254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// 8.2.1 (h) -- wait for not BSY
28274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
28284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
28294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Enable interrupts
28314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
28324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
28334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
28354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : execute a non data command
28364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
28374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28384d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_non_data()
28394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{return 0;}
28404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
28424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : execute a data-in command
28434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
28444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // returns
28454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 0 : no error
28464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 1 : BUSY bit set
28474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 2 : read error
28484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 3 : expected DRQ=1
28494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 4 : no sectors left to read/verify
28504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 5 : more sectors to read/verify
28514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 6 : no sectors left to write
28524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 7 : more sectors to write
28534d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_data_in(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset)
28544d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u device, command, count, cylinder, head, sector, segment, offset;
28554d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit32u lba_low, lba_high;
28564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
28574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
28584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u iobase1, iobase2, blksize;
28594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  channel, slave;
28604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  status, current, mode;
28614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  channel = device / 2;
28634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  slave   = device % 2;
28644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
28664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
28674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mode    = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
28684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  blksize = 0x200; // was = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize);
28694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (mode == ATA_MODE_PIO32) blksize>>=2;
28704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else blksize>>=1;
28714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Reset count of transferred data
28734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg, &EbdaData->ata.trsfsectors,0);
28744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L);
28754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  current = 0;
28764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(iobase1 + ATA_CB_STAT);
28784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (status & ATA_CB_STAT_BSY) return 1;
28794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
28814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // sector will be 0 only on lba access. Convert to lba-chs
28834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (sector == 0) {
28844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((count >= 1 << 8) || lba_high || (lba_low + count >= 1UL << 28)) {
28854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_FR, 0x00);
28864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff);
28874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_SN, lba_low >> 24);
28884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_CL, lba_high & 0xff);
28894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_CH, lba_high >> 8);
28904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      command |= 0x04;
28914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count &= (1UL << 8) - 1;
28924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba_low &= (1UL << 24) - 1;
28934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
28944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sector = (Bit16u) (lba_low & 0x000000ffL);
28954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cylinder = (Bit16u) ((lba_low>>8) & 0x0000ffffL);
28964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    head = ((Bit16u) ((lba_low>>24) & 0x0000000fL)) | ATA_CB_DH_LBA;
28974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
28984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
28994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_FR, 0x00);
29004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_SC, count);
29014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_SN, sector);
29024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
29034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CH, cylinder >> 8);
29044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head );
29054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CMD, command);
29064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
29084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(iobase1 + ATA_CB_STAT);
29094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (status & ATA_CB_STAT_ERR) {
29114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_data_in : read error\n");
29124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 2;
29134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } else if ( !(status & ATA_CB_STAT_DRQ) ) {
29144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_data_in : DRQ not set (status %02x)\n", (unsigned) status);
29154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 3;
29164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
29174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // FIXME : move seg/off translation here
29194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29204d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
29214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sti  ;; enable higher priority interrupts
29224d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
29234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (1) {
29254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29264d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
29274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
29284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
29294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  di, _ata_cmd_data_in.offset + 2[bp]
29304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ax, _ata_cmd_data_in.segment + 2[bp]
29314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, _ata_cmd_data_in.blksize + 2[bp]
29324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; adjust if there will be an overrun. 2K max sector size
29344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp   di, #0xf800 ;;
29354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jbe   ata_in_no_adjust
29364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_in_adjust:
29384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sub   di, #0x0800 ;; sub 2 kbytes from offset
29394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        add   ax, #0x0080 ;; add 2 Kbytes to segment
29404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_in_no_adjust:
29424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   es, ax      ;; segment in es
29434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   dx, _ata_cmd_data_in.iobase1 + 2[bp] ;; ATA data read port
29454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ah, _ata_cmd_data_in.mode + 2[bp]
29474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp  ah, #ATA_MODE_PIO32
29484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        je   ata_in_32
29494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_in_16:
29514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
29524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          insw ;; CX words transfered from port(DX) to ES:[DI]
29534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jmp ata_in_done
29544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_in_32:
29564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
29574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          insd ;; CX dwords transfered from port(DX) to ES:[DI]
29584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_in_done:
29604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  _ata_cmd_data_in.offset + 2[bp], di
29614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  _ata_cmd_data_in.segment + 2[bp], es
29624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
29634d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
29644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    current++;
29664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg, &EbdaData->ata.trsfsectors,current);
29674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    count--;
29684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
29694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = inb(iobase1 + ATA_CB_STAT);
29704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (count == 0) {
29714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
29724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          != ATA_CB_STAT_RDY ) {
29734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_ATA("ata_cmd_data_in : no sectors left (status %02x)\n", (unsigned) status);
29744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return 4;
29754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
29764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
29774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
29784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else {
29794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
29804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
29814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_ATA("ata_cmd_data_in : more sectors left (status %02x)\n", (unsigned) status);
29824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return 5;
29834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
29844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      continue;
29854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
29864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
29874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Enable interrupts
29884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
29894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 0;
29904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
29914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
29924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
29934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : execute a data-out command
29944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
29954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // returns
29964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 0 : no error
29974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 1 : BUSY bit set
29984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 2 : read error
29994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 3 : expected DRQ=1
30004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 4 : no sectors left to read/verify
30014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 5 : more sectors to read/verify
30024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 6 : no sectors left to write
30034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 7 : more sectors to write
30044d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_data_out(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset)
30054d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u device, command, count, cylinder, head, sector, segment, offset;
30064d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit32u lba_low, lba_high;
30074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
30084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
30094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u iobase1, iobase2, blksize;
30104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  channel, slave;
30114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  status, current, mode;
30124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  channel = device / 2;
30144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  slave   = device % 2;
30154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
30174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
30184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mode    = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
30194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  blksize = 0x200; // was = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize);
30204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (mode == ATA_MODE_PIO32) blksize>>=2;
30214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else blksize>>=1;
30224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Reset count of transferred data
30244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg, &EbdaData->ata.trsfsectors,0);
30254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L);
30264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  current = 0;
30274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(iobase1 + ATA_CB_STAT);
30294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (status & ATA_CB_STAT_BSY) return 1;
30304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
30324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // sector will be 0 only on lba access. Convert to lba-chs
30344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (sector == 0) {
30354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((count >= 1 << 8) || lba_high || (lba_low + count >= 1UL << 28)) {
30364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_FR, 0x00);
30374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff);
30384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_SN, lba_low >> 24);
30394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_CL, lba_high & 0xff);
30404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(iobase1 + ATA_CB_CH, lba_high >> 8);
30414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      command |= 0x04;
30424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count &= (1UL << 8) - 1;
30434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba_low &= (1UL << 24) - 1;
30444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
30454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sector = (Bit16u) (lba_low & 0x000000ffL);
30464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cylinder = (Bit16u) ((lba_low>>8) & 0x0000ffffL);
30474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    head = ((Bit16u) ((lba_low>>24) & 0x0000000fL)) | ATA_CB_DH_LBA;
30484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
30494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_FR, 0x00);
30514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_SC, count);
30524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_SN, sector);
30534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
30544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CH, cylinder >> 8);
30554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head );
30564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CMD, command);
30574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
30594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(iobase1 + ATA_CB_STAT);
30604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (status & ATA_CB_STAT_ERR) {
30624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_data_out : read error\n");
30634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 2;
30644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } else if ( !(status & ATA_CB_STAT_DRQ) ) {
30654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_data_out : DRQ not set (status %02x)\n", (unsigned) status);
30664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 3;
30674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
30684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // FIXME : move seg/off translation here
30704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30714d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
30724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sti  ;; enable higher priority interrupts
30734d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
30744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (1) {
30764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30774d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
30784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
30794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
30804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  si, _ata_cmd_data_out.offset + 2[bp]
30814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ax, _ata_cmd_data_out.segment + 2[bp]
30824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, _ata_cmd_data_out.blksize + 2[bp]
30834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; adjust if there will be an overrun. 2K max sector size
30854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp   si, #0xf800 ;;
30864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jbe   ata_out_no_adjust
30874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_out_adjust:
30894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sub   si, #0x0800 ;; sub 2 kbytes from offset
30904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        add   ax, #0x0080 ;; add 2 Kbytes to segment
30914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_out_no_adjust:
30934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   es, ax      ;; segment in es
30944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   dx, _ata_cmd_data_out.iobase1 + 2[bp] ;; ATA data write port
30964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
30974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ah, _ata_cmd_data_out.mode + 2[bp]
30984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp  ah, #ATA_MODE_PIO32
30994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        je   ata_out_32
31004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_out_16:
31024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        seg ES
31034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
31044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outsw ;; CX words transfered from port(DX) to ES:[SI]
31054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jmp ata_out_done
31064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_out_32:
31084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        seg ES
31094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
31104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outsd ;; CX dwords transfered from port(DX) to ES:[SI]
31114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_out_done:
31134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  _ata_cmd_data_out.offset + 2[bp], si
31144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  _ata_cmd_data_out.segment + 2[bp], es
31154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
31164d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
31174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    current++;
31194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ebda_seg, &EbdaData->ata.trsfsectors,current);
31204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    count--;
31214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = inb(iobase1 + ATA_CB_STAT);
31224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (count == 0) {
31234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
31244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          != ATA_CB_STAT_RDY ) {
31254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_ATA("ata_cmd_data_out : no sectors left (status %02x)\n", (unsigned) status);
31264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return 6;
31274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
31284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
31294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
31304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else {
31314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
31324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
31334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_ATA("ata_cmd_data_out : more sectors left (status %02x)\n", (unsigned) status);
31344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return 7;
31354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
31364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      continue;
31374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
31384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
31394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Enable interrupts
31404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
31414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 0;
31424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
31434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
31454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ATA/ATAPI driver : execute a packet command
31464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
31474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // returns
31484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 0 : no error
31494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 1 : error in parameters
31504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 2 : BUSY bit set
31514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 3 : error
31524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 4 : not ready
31534d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u ata_cmd_packet(device, cmdlen, cmdseg, cmdoff, header, length, inout, bufseg, bufoff)
31544d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit8u  cmdlen,inout;
31554d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u device,cmdseg, cmdoff, bufseg, bufoff;
31564d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u header;
31574d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit32u length;
31584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
31594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
31604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u iobase1, iobase2;
31614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u lcount, lbefore, lafter, count;
31624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  channel, slave;
31634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  status, mode, lmode;
31644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u total, transfer;
31654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  channel = device / 2;
31674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  slave = device % 2;
31684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Data out is not supported yet
31704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (inout == ATA_DATA_OUT) {
31714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("ata_cmd_packet: DATA_OUT not supported yet\n");
31724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 1;
31734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
31744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // The header length must be even
31764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (header & 1) {
31774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_packet : header must be even (%04x)\n",header);
31784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 1;
31794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
31804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
31824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
31834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mode    = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
31844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  transfer= 0L;
31854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (cmdlen < 12) cmdlen=12;
31874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (cmdlen > 12) cmdlen=16;
31884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmdlen>>=1;
31894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Reset count of transferred data
31914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg, &EbdaData->ata.trsfsectors,0);
31924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L);
31934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(iobase1 + ATA_CB_STAT);
31954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (status & ATA_CB_STAT_BSY) return 2;
31964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
31974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
31984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_FR, 0x00);
31994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_SC, 0x00);
32004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_SN, 0x00);
32014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
32024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
32034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
32044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
32054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Device should ok to receive command
32074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
32084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  status = inb(iobase1 + ATA_CB_STAT);
32094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (status & ATA_CB_STAT_ERR) {
32114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status);
32124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 3;
32134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } else if ( !(status & ATA_CB_STAT_DRQ) ) {
32144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_packet : DRQ not set (status %02x)\n", (unsigned) status);
32154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 4;
32164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
32174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Normalize address
32194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmdseg += (cmdoff / 16);
32204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmdoff %= 16;
32214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Send command to device
32234d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
32244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sti  ;; enable higher priority interrupts
32254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push bp
32274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bp, sp
32284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  si, _ata_cmd_packet.cmdoff + 2[bp]
32304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, _ata_cmd_packet.cmdseg + 2[bp]
32314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  cx, _ata_cmd_packet.cmdlen + 2[bp]
32324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  es, ax      ;; segment in es
32334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  dx, _ata_cmd_packet.iobase1 + 2[bp] ;; ATA data write port
32354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      seg ES
32374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      rep
32384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outsw ;; CX words transfered from port(DX) to ES:[SI]
32394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  bp
32414d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
32424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (inout == ATA_DATA_NO) {
32444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
32454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = inb(iobase1 + ATA_CB_STAT);
32464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
32474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
32484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u loops = 0;
32494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit8u sc;
32504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (1) {
32514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (loops == 0) {//first time through
32534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status = inb(iobase2 + ATA_CB_ASTAT);
32544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
32554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
32564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else
32574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
32584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      loops++;
32594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = inb(iobase1 + ATA_CB_STAT);
32614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sc = inb(iobase1 + ATA_CB_SC);
32624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Check if command completed
32644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) &&
32654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         ((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY)) break;
32664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status & ATA_CB_STAT_ERR) {
32684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
32694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return 3;
32704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
32714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Normalize address
32734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bufseg += (bufoff / 16);
32744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bufoff %= 16;
32754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get the byte count
32774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lcount =  ((Bit16u)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
32784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // adjust to read what we want
32804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(header>lcount) {
32814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         lbefore=lcount;
32824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         header-=lcount;
32834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         lcount=0;
32844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         }
32854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
32864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lbefore=header;
32874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        header=0;
32884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lcount-=lbefore;
32894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
32904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
32914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(lcount>length) {
32924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lafter=lcount-length;
32934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lcount=length;
32944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        length=0;
32954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
32964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
32974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lafter=0;
32984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        length-=lcount;
32994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
33004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Save byte count
33024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count = lcount;
33034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
33054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_DEBUG_ATA("to 0x%04x:0x%04x\n",bufseg,bufoff);
33064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // If counts not dividable by 4, use 16bits mode
33084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lmode = mode;
33094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lbefore & 0x03) lmode=ATA_MODE_PIO16;
33104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lcount  & 0x03) lmode=ATA_MODE_PIO16;
33114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lafter  & 0x03) lmode=ATA_MODE_PIO16;
33124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // adds an extra byte if count are odd. before is always even
33144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lcount & 0x01) {
33154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lcount+=1;
33164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ((lafter > 0) && (lafter & 0x01)) {
33174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          lafter-=1;
33184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
33194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
33204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lmode == ATA_MODE_PIO32) {
33224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lcount>>=2; lbefore>>=2; lafter>>=2;
33234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
33244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
33254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lcount>>=1; lbefore>>=1; lafter>>=1;
33264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
33274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       ;  // FIXME bcc bug
33294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33304d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
33314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
33324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
33334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  dx, _ata_cmd_packet.iobase1 + 2[bp] ;; ATA data read port
33354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, _ata_cmd_packet.lbefore + 2[bp]
33374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jcxz ata_packet_no_before
33384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ah, _ata_cmd_packet.lmode + 2[bp]
33404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp  ah, #ATA_MODE_PIO32
33414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        je   ata_packet_in_before_32
33424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_before_16:
33444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        in   ax, dx
33454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        loop ata_packet_in_before_16
33464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jmp  ata_packet_no_before
33474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_before_32:
33494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push eax
33504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_before_32_loop:
33514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        in   eax, dx
33524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        loop ata_packet_in_before_32_loop
33534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  eax
33544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_no_before:
33564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, _ata_cmd_packet.lcount + 2[bp]
33574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jcxz ata_packet_after
33584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  di, _ata_cmd_packet.bufoff + 2[bp]
33604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ax, _ata_cmd_packet.bufseg + 2[bp]
33614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  es, ax
33624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ah, _ata_cmd_packet.lmode + 2[bp]
33644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp  ah, #ATA_MODE_PIO32
33654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        je   ata_packet_in_32
33664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_16:
33684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
33694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          insw ;; CX words transfered tp port(DX) to ES:[DI]
33704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jmp ata_packet_after
33714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_32:
33734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
33744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          insd ;; CX dwords transfered to port(DX) to ES:[DI]
33754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_after:
33774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, _ata_cmd_packet.lafter + 2[bp]
33784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jcxz ata_packet_done
33794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ah, _ata_cmd_packet.lmode + 2[bp]
33814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp  ah, #ATA_MODE_PIO32
33824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        je   ata_packet_in_after_32
33834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_after_16:
33854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        in   ax, dx
33864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        loop ata_packet_in_after_16
33874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jmp  ata_packet_done
33884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_after_32:
33904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push eax
33914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_in_after_32_loop:
33924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        in   eax, dx
33934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        loop ata_packet_in_after_32_loop
33944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  eax
33954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
33964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaata_packet_done:
33974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
33984d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
33994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Compute new buffer address
34014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bufoff += count;
34024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Save transferred bytes count
34044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      transfer += count;
34054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_dword(ebda_seg, &EbdaData->ata.trsfbytes,transfer);
34064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
34074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
34084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Final check, device must be ready
34104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
34114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         != ATA_CB_STAT_RDY ) {
34124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", (unsigned) status);
34134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 4;
34144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
34154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Enable interrupts
34174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
34184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 0;
34194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
34204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
34224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// End of ATA/ATAPI Driver
34234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
34244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
34264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Start of ATA/ATAPI generic functions
34274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
34284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
34304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaatapi_get_sense(device, seg, asc, ascq)
34314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u device;
34324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
34334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  atacmd[12];
34344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  buffer[18];
34354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u i;
34364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(get_SS(),atacmd,0,12);
34384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Request SENSE
34404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[0]=ATA_CMD_REQUEST_SENSE;
34414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[4]=sizeof(buffer);
34424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 18L, ATA_DATA_IN, get_SS(), buffer) != 0)
34434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 0x0002;
34444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(seg,asc,buffer[12]);
34464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(seg,ascq,buffer[13]);
34474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 0;
34494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
34504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
34524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaatapi_is_ready(device)
34534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u device;
34544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
34554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u packet[12];
34564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u buf[8];
34574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u block_len;
34584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u sectors;
34594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u timeout; //measured in ms
34604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u time;
34614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u asc, ascq;
34624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u in_progress;
34634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg = read_word(0x0040,0x000E);
34644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) {
34654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("not implemented for non-ATAPI device\n");
34664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return -1;
34674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
34684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_ATA("ata_detect_medium: begin\n");
34704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(get_SS(),packet, 0, sizeof packet);
34714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  packet[0] = 0x25; /* READ CAPACITY */
34724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Retry READ CAPACITY 50 times unless MEDIUM NOT PRESENT
34744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   * is reported by the device. If the device reports "IN PROGRESS",
34754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   * 30 seconds is added. */
34764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  timeout = 5000;
34774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  time = 0;
34784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in_progress = 0;
34794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while (time < timeout) {
34804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (ata_cmd_packet(device, sizeof(packet), get_SS(), packet, 0, 8L, ATA_DATA_IN, get_SS(), buf) == 0)
34814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto ok;
34824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (atapi_get_sense(device, get_SS(), &asc, &ascq) == 0) {
34844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (asc == 0x3a) { /* MEDIUM NOT PRESENT */
34854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_ATA("Device reports MEDIUM NOT PRESENT\n");
34864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return -1;
34874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
34884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
34894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (asc == 0x04 && ascq == 0x01 && !in_progress) {
34904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        /* IN PROGRESS OF BECOMING READY */
34914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        printf("Waiting for device to detect medium... ");
34924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        /* Allow 30 seconds more */
34934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        timeout = 30000;
34944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        in_progress = 1;
34954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
34964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
34974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    time += 100;
34984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
34994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_ATA("read capacity failed\n");
35004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return -1;
35014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaok:
35024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  block_len = (Bit32u) buf[4] << 24
35044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    | (Bit32u) buf[5] << 16
35054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    | (Bit32u) buf[6] << 8
35064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    | (Bit32u) buf[7] << 0;
35074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_ATA("block_len=%u\n", block_len);
35084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (block_len!= 2048 && block_len!= 512)
35104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  {
35114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("Unsupported sector size %u\n", block_len);
35124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return -1;
35134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
35144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(ebda_seg,&EbdaData->ata.devices[device].blksize, block_len);
35154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sectors = (Bit32u) buf[0] << 24
35174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    | (Bit32u) buf[1] << 16
35184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    | (Bit32u) buf[2] << 8
35194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    | (Bit32u) buf[3] << 0;
35204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_ATA("sectors=%u\n", sectors);
35224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (block_len == 2048)
35234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sectors <<= 2; /* # of sectors in 512-byte "soft" sector */
35244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (sectors != read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low))
35254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("%dMB medium detected\n", sectors>>(20-9));
35264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors);
35274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 0;
35284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
35294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
35314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaatapi_is_cdrom(device)
35324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u device;
35334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
35344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
35354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (device >= BX_MAX_ATA_DEVICES)
35374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 0;
35384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI)
35404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 0;
35414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM)
35434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 0;
35444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return 1;
35464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
35474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
35494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// End of ATA/ATAPI generic functions
35504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
35514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_USE_ATADRV
35534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
35554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
35574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Start of El-Torito boot functions
35584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
35594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
35614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacdemu_init()
35624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
35634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
35644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // the only important data is this one for now
35664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->cdemu.active,0x00);
35674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
35684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
35704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacdemu_isactive()
35714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
35724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
35734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(read_byte(ebda_seg,&EbdaData->cdemu.active));
35754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
35764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
35784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacdemu_emulated_drive()
35794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
35804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
35814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive));
35834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
35844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char isotag[6]="CD001";
35864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char eltorito[24]="EL TORITO SPECIFICATION";
35874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
35884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Returns ah: emulated drive, al: error code
35894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//
35904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u
35914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacdrom_boot()
35924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
35934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
35944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  atacmd[12], buffer[2048];
35954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u lba;
35964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u boot_segment, nbsectors, i, error;
35974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  device;
35984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
35994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Find out the first cdrom
36004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
36014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (atapi_is_cdrom(device)) break;
36024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
36034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // if not found
36054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(device >= BX_MAX_ATA_DEVICES) return 2;
36064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(error = atapi_is_ready(device) != 0)
36084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("ata_is_ready returned %d\n",error);
36094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Read the Boot Record Volume Descriptor
36114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(get_SS(),atacmd,0,12);
36124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[0]=0x28;                      // READ command
36134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[7]=(0x01 & 0xff00) >> 8;      // Sectors
36144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[8]=(0x01 & 0x00ff);           // Sectors
36154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[2]=(0x11 & 0xff000000) >> 24; // LBA
36164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[3]=(0x11 & 0x00ff0000) >> 16;
36174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[4]=(0x11 & 0x0000ff00) >> 8;
36184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[5]=(0x11 & 0x000000ff);
36194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
36204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 3;
36214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Validity checks
36234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0]!=0)return 4;
36244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for(i=0;i<5;i++){
36254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if(buffer[1+i]!=read_byte(0xf000,&isotag[i]))return 5;
36264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   }
36274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for(i=0;i<23;i++)
36284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if(buffer[7+i]!=read_byte(0xf000,&eltorito[i]))return 6;
36294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // ok, now we calculate the Boot catalog address
36314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lba=buffer[0x4A]*0x1000000+buffer[0x49]*0x10000+buffer[0x48]*0x100+buffer[0x47];
36324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // And we read the Boot Catalog
36344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(get_SS(),atacmd,0,12);
36354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[0]=0x28;                      // READ command
36364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[7]=(0x01 & 0xff00) >> 8;      // Sectors
36374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[8]=(0x01 & 0x00ff);           // Sectors
36384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
36394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[3]=(lba & 0x00ff0000) >> 16;
36404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[4]=(lba & 0x0000ff00) >> 8;
36414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[5]=(lba & 0x000000ff);
36424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
36434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 7;
36444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Validation entry
36464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0x00]!=0x01)return 8;   // Header
36474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0x01]!=0x00)return 9;   // Platform
36484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0x1E]!=0x55)return 10;  // key 1
36494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0x1F]!=0xAA)return 10;  // key 2
36504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Initial/Default Entry
36524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0x20]!=0x88)return 11; // Bootable
36534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]);
36554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(buffer[0x21]==0){
36564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0.
36574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Win2000 cd boot needs to know it booted from cd
36584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0xE0);
36594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
36604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if(buffer[0x21]<4)
36614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0x00);
36624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
36634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0x80);
36644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->cdemu.controller_index,device/2);
36664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg,&EbdaData->cdemu.device_spec,device%2);
36674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  boot_segment=buffer[0x23]*0x100+buffer[0x22];
36694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(boot_segment==0x0000)boot_segment=0x07C0;
36704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->cdemu.load_segment,boot_segment);
36724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->cdemu.buffer_segment,0x0000);
36734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  nbsectors=buffer[0x27]*0x100+buffer[0x26];
36754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ebda_seg,&EbdaData->cdemu.sector_count,nbsectors);
36764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lba=buffer[0x2B]*0x1000000+buffer[0x2A]*0x10000+buffer[0x29]*0x100+buffer[0x28];
36784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_dword(ebda_seg,&EbdaData->cdemu.ilba,lba);
36794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // And we read the image in memory
36814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memsetb(get_SS(),atacmd,0,12);
36824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[0]=0x28;                      // READ command
36834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[7]=((1+(nbsectors-1)/4) & 0xff00) >> 8;      // Sectors
36844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[8]=((1+(nbsectors-1)/4) & 0x00ff);           // Sectors
36854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
36864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[3]=(lba & 0x00ff0000) >> 16;
36874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[4]=(lba & 0x0000ff00) >> 8;
36884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  atacmd[5]=(lba & 0x000000ff);
36894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0)
36904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return 12;
36914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
36924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Remember the media type
36934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
36944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01:  // 1.2M floppy
36954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,15);
36964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80);
36974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2);
36984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
36994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02:  // 1.44M floppy
37004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,18);
37014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80);
37024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2);
37034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
37044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x03:  // 2.88M floppy
37054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,36);
37064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80);
37074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2);
37084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
37094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x04:  // Harddrive
37104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,read_byte(boot_segment,446+6)&0x3f);
37114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,
37124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              (read_byte(boot_segment,446+6)<<2) + read_byte(boot_segment,446+7) + 1);
37134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,read_byte(boot_segment,446+5) + 1);
37144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
37154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   }
37164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(read_byte(ebda_seg,&EbdaData->cdemu.media)!=0) {
37184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Increase bios installed hardware number of devices
37194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)==0x00)
37204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x40,0x10,read_byte(0x40,0x10)|0x41);
37214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    else
37224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ebda_seg, &EbdaData->ata.hdcount, read_byte(ebda_seg, &EbdaData->ata.hdcount) + 1);
37234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   }
37244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // everything is ok, so from now on, the emulation is active
37274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if(read_byte(ebda_seg,&EbdaData->cdemu.media)!=0)
37284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ebda_seg,&EbdaData->cdemu.active,0x01);
37294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // return the boot drive + no error
37314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)*0x100)+0;
37324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
37334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
37354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// End of El-Torito boot functions
37364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
37374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
37384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
37404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint14_function(regs, ds, iret_addr)
37414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha_regs_t regs; // regs pushed from PUSHA instruction
37424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
37434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret_addr_t  iret_addr; // CS,IP,Flags pushed from original INT call
37444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
37454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u addr,timer,val16;
37464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u timeout;
37474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
37494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
37504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
37514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
37524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  addr = read_word(0x0040, (regs.u.r16.dx << 1));
37534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  timeout = read_byte(0x0040, 0x007C + regs.u.r16.dx);
37544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((regs.u.r16.dx < 4) && (addr > 0)) {
37554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    switch (regs.u.r8.ah) {
37564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      case 0:
37574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(addr+3, inb(addr+3) | 0x80);
37584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (regs.u.r8.al & 0xE0 == 0) {
37594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb(addr, 0x17);
37604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb(addr+1, 0x04);
37614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
37624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val16 = 0x600 >> ((regs.u.r8.al & 0xE0) >> 5);
37634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb(addr, val16 & 0xFF);
37644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb(addr+1, val16 >> 8);
37654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
37664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(addr+3, regs.u.r8.al & 0x1F);
37674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.ah = inb(addr+5);
37684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.al = inb(addr+6);
37694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ClearCF(iret_addr.flags);
37704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
37714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      case 1:
37724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        timer = read_word(0x0040, 0x006C);
37734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        while (((inb(addr+5) & 0x60) != 0x60) && (timeout)) {
37744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val16 = read_word(0x0040, 0x006C);
37754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (val16 != timer) {
37764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            timer = val16;
37774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            timeout--;
37784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
37794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
37804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (timeout) outb(addr, regs.u.r8.al);
37814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.ah = inb(addr+5);
37824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (!timeout) regs.u.r8.ah |= 0x80;
37834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ClearCF(iret_addr.flags);
37844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
37854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      case 2:
37864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        timer = read_word(0x0040, 0x006C);
37874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        while (((inb(addr+5) & 0x01) == 0) && (timeout)) {
37884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val16 = read_word(0x0040, 0x006C);
37894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (val16 != timer) {
37904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            timer = val16;
37914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            timeout--;
37924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
37934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
37944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (timeout) {
37954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 0;
37964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.al = inb(addr);
37974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
37984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = inb(addr+5);
37994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
38004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ClearCF(iret_addr.flags);
38014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
38024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      case 3:
38034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.ah = inb(addr+5);
38044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.al = inb(addr+6);
38054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ClearCF(iret_addr.flags);
38064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
38074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      default:
38084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SetCF(iret_addr.flags); // Unsupported
38094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
38104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } else {
38114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SetCF(iret_addr.flags); // Unsupported
38124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
38134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
38144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
38164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_function(regs, ES, DS, FLAGS)
38174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha_regs_t regs; // REGS pushed via pusha
38184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ES, DS, FLAGS;
38194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
38204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
38214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool prev_a20_enable;
38224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  base15_00;
38234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u   base23_16;
38244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  ss;
38254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  CX,DX;
38264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u bRegister;
38284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u irqDisable;
38294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38304d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax);
38314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (regs.u.r8.ah) {
38334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x24: /* A20 Control */
38344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (regs.u.r8.al) {
38354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x00:
38364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_enable_a20(0);
38374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF();
38384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 0;
38394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
38404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x01:
38414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_enable_a20(1);
38424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF();
38434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 0;
38444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
38454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x02:
38464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.al = (inb(0x92) >> 1) & 0x01;
38474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF();
38484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 0;
38494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
38504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x03:
38514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF();
38524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 0;
38534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r16.bx = 3;
38544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
38554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        default:
38564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("int15: Func 24h, subfunc %02xh, A20 gate control not supported\n", (unsigned) regs.u.r8.al);
38574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF();
38584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = UNSUPPORTED_FUNCTION;
38594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
38604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
38614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x41:
38634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
38644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
38654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
38664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4f:
38684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* keyboard intercept */
38694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_CPU < 2
38704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
38714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
38724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // nop
38734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
38744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
38754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
38764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x52:    // removable media eject
38784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
38794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;  // "ok ejection may proceed"
38804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
38814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
38824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x83: {
38834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if( regs.u.r8.al == 0 ) {
38844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Set Interval requested.
38854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if( ( read_byte( 0x40, 0xA0 ) & 1 ) == 0 ) {
38864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Interval not already set.
38874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte( 0x40, 0xA0, 1 );  // Set status byte.
38884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word( 0x40, 0x98, ES ); // Byte location, segment
38894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word( 0x40, 0x9A, regs.u.r16.bx ); // Byte location, offset
38904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word( 0x40, 0x9C, regs.u.r16.dx ); // Low word, delay
38914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word( 0x40, 0x9E, regs.u.r16.cx ); // High word, delay.
38924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF( );
38934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          irqDisable = inb( 0xA1 );
38944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb( 0xA1, irqDisable & 0xFE );
38954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          bRegister = inb_cmos( 0xB );  // Unmask IRQ8 so INT70 will get through.
38964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb_cmos( 0xB, bRegister | 0x40 ); // Turn on the Periodic Interrupt timer
38974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
38984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Interval already set.
38994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_DEBUG_INT15("int15: Func 83h, failed, already waiting.\n" );
39004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF();
39014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = UNSUPPORTED_FUNCTION;
39024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
39034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if( regs.u.r8.al == 1 ) {
39044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Clear Interval requested
39054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte( 0x40, 0xA0, 0 );  // Clear status byte
39064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CLEAR_CF( );
39074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        bRegister = inb_cmos( 0xB );
39084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb_cmos( 0xB, bRegister & ~0x40 );  // Turn off the Periodic Interrupt timer
39094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else {
39104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT15("int15: Func 83h, failed.\n" );
39114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
39124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.ah = UNSUPPORTED_FUNCTION;
39134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r8.al--;
39144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
39154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
39174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
39184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x87:
39204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_CPU < 3
39214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#  error "Int15 function 87h not supported on < 80386"
39224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
39234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // +++ should probably have descriptor checks
39244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // +++ should have exception handlers
39254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima // turn off interrupts
39274d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
39284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
39294d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
39304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      prev_a20_enable = set_enable_a20(1); // enable A20 line
39324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 128K max of transfer on 386+ ???
39344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // source == destination ???
39354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // ES:SI points to descriptor table
39374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // offset   use     initially  comments
39384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // ==============================================
39394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 00..07   Unused  zeros      Null descriptor
39404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 08..0f   GDT     zeros      filled in by BIOS
39414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 10..17   source  ssssssss   source of data
39424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 18..1f   dest    dddddddd   destination of data
39434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 20..27   CS      zeros      filled in by BIOS
39444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 28..2f   SS      zeros      filled in by BIOS
39454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //es:si
39474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //eeee0
39484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //0ssss
39494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //-----
39504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// check for access rights of source & dest here
39524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Initialize GDT descriptor
39544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base15_00 = (ES << 4) + regs.u.r16.si;
39554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base23_16 = ES >> 12;
39564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (base15_00 < (ES<<4))
39574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base23_16++;
39584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x08+0, 47);       // limit 15:00 = 6 * 8bytes/descriptor
39594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x08+2, base15_00);// base 15:00
39604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ES, regs.u.r16.si+0x08+4, base23_16);// base 23:16
39614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ES, regs.u.r16.si+0x08+5, 0x93);     // access
39624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x08+6, 0x0000);   // base 31:24/reserved/limit 19:16
39634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Initialize CS descriptor
39654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x20+0, 0xffff);// limit 15:00 = normal 64K limit
39664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x20+2, 0x0000);// base 15:00
39674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ES, regs.u.r16.si+0x20+4, 0x000f);// base 23:16
39684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ES, regs.u.r16.si+0x20+5, 0x9b);  // access
39694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x20+6, 0x0000);// base 31:24/reserved/limit 19:16
39704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Initialize SS descriptor
39724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ss = get_SS();
39734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base15_00 = ss << 4;
39744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base23_16 = ss >> 12;
39754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x28+0, 0xffff);   // limit 15:00 = normal 64K limit
39764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x28+2, base15_00);// base 15:00
39774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ES, regs.u.r16.si+0x28+4, base23_16);// base 23:16
39784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(ES, regs.u.r16.si+0x28+5, 0x93);     // access
39794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(ES, regs.u.r16.si+0x28+6, 0x0000);   // base 31:24/reserved/limit 19:16
39804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CX = regs.u.r16.cx;
39824d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
39834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Compile generates locals offset info relative to SP.
39844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get CX (word count) from stack.
39854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bx, sp
39864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SEG SS
39874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, _int15_function.CX [bx]
39884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // since we need to set SS:SP, save them to the BDA
39904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // for future restore
39914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push eax
39924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      xor eax, eax
39934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ds, ax
39944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov 0x0469, ss
39954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov 0x0467, sp
39964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
39974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SEG ES
39984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lgdt [si + 0x08]
39994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SEG CS
40004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lidt [pmode_IDT_info]
40014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;;  perhaps do something with IDT here
40024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; set PE bit in CR0
40044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  eax, cr0
40054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      or   al, #0x01
40064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  cr0, eax
40074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; far jump to flush CPU queue after transition to protected mode
40084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      JMP_AP(0x0020, protected_mode)
40094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaprotected_mode:
40114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; GDT points to valid descriptor table, now load SS, DS, ES
40124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, #0x28 ;; 101 000 = 5th descriptor in table, TI=GDT, RPL=00
40134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ss, ax
40144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, #0x10 ;; 010 000 = 2nd descriptor in table, TI=GDT, RPL=00
40154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ds, ax
40164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ax, #0x18 ;; 011 000 = 3rd descriptor in table, TI=GDT, RPL=00
40174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  es, ax
40184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      xor  si, si
40194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      xor  di, di
40204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cld
40214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      rep
40224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        movsw  ;; move CX words from DS:SI to ES:DI
40234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; make sure DS and ES limits are 64KB
40254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ax, #0x28
40264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ds, ax
40274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov es, ax
40284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; reset PG bit in CR0 ???
40304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  eax, cr0
40314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      and  al, #0xFE
40324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  cr0, eax
40334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; far jump to flush CPU queue after transition to real mode
40354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      JMP_AP(0xf000, real_mode)
40364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimareal_mode:
40384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; restore IDT to normal real-mode defaults
40394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SEG CS
40404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lidt [rmode_IDT_info]
40414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // restore SS:SP from the BDA
40434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      xor ax, ax
40444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ds, ax
40454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ss, 0x0469
40464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov sp, 0x0467
40474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop eax
40484d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
40494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_enable_a20(prev_a20_enable);
40514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima // turn back on interrupts
40534d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
40544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
40554d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
40564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
40584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
40594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
40604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x88:
40634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get the amount of extended memory (above 1M)
40644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_CPU < 2
40654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
40664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
40674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
40684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al = inb_cmos(0x30);
40694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = inb_cmos(0x31);
40704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // According to Ralf Brown's interrupt the limit should be 15M,
40724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // but real machines mostly return max. 63M.
40734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(regs.u.r16.ax > 0xffc0)
40744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        regs.u.r16.ax = 0xffc0;
40754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
40774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
40784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
40794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x90:
40814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* Device busy interrupt.  Called by Int 16h when no key available */
40824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
40834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x91:
40854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* Interrupt complete.  Called by Int 16h when key becomes available */
40864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
40874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xbf:
40894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("*** int 15h function AH=bf not yet supported!\n");
40904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
40914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
40924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
40934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
40944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xC0:
40954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
40964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
40974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
40984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
40994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
41004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
41014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
41024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r16.bx =  BIOS_CONFIG_TABLE;
41034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ES = 0xF000;
41044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
41054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xc1:
41074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ES = ebda_seg;
41084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
41094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
41104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xd8:
41124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_printf(BIOS_PRINTF_DEBUG, "EISA BIOS not present\n");
41134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
41144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
41154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
41164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
41184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n",
41194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx);
41204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
41214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
41224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
41234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
41244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
41254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_PS2_MOUSE
41274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
41284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_function_mouse(regs, ES, DS, FLAGS)
41294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha_regs_t regs; // REGS pushed via pusha
41304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ES, DS, FLAGS;
41314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
41324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
41334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  mouse_flags_1, mouse_flags_2;
41344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u mouse_driver_seg;
41354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u mouse_driver_offset;
41364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  comm_byte, prev_command_byte;
41374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  ret, mouse_data1, mouse_data2, mouse_data3;
41384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41394d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax);
41404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (regs.u.r8.ah) {
41424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xC2:
41434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Return Codes status in AH
41444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // =========================
41454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 00: success
41464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 01: invalid subfunction (AL > 7)
41474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 02: invalid input value (out of allowable range)
41484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 03: interface error
41494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 04: resend command received from mouse controller,
41504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //     device driver should attempt command again
41514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 05: cannot enable mouse, since no far call has been installed
41524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // 80/86: mouse service not implemented
41534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (regs.u.r8.al) {
41554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0: // Disable/Enable Mouse
41564d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 0:\n");
41574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          switch (regs.u.r8.bh) {
41584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 0: // Disable Mouse
41594d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 0: disable mouse\n");
41604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              inhibit_mouse_int_and_events(); // disable IRQ12 and packets
41614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = send_to_mouse_ctrl(0xF5); // disable mouse command
41624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (ret == 0) {
41634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = get_mouse_data(&mouse_data1);
41644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if ( (ret == 0) || (mouse_data1 == 0xFA) ) {
41654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  CLEAR_CF();
41664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  regs.u.r8.ah = 0;
41674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  return;
41684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  }
41694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
41704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              // error
41724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
41734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = ret;
41744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              return;
41754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              break;
41764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
41774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 1: // Enable Mouse
41784d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 1: enable mouse\n");
41794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              mouse_flags_2 = read_byte(ebda_seg, 0x0027);
41804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if ( (mouse_flags_2 & 0x80) == 0 ) {
41814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                BX_DEBUG_INT15("INT 15h C2 Enable Mouse, no far call handler\n");
41824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                SET_CF();  // error
41834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                regs.u.r8.ah = 5; // no far call installed
41844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                return;
41854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
41864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              inhibit_mouse_int_and_events(); // disable IRQ12 and packets
41874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = send_to_mouse_ctrl(0xF4); // enable mouse command
41884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (ret == 0) {
41894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = get_mouse_data(&mouse_data1);
41904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if ( (ret == 0) && (mouse_data1 == 0xFA) ) {
41914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  enable_mouse_int_and_events(); // turn IRQ12 and packet generation on
41924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  CLEAR_CF();
41934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  regs.u.r8.ah = 0;
41944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  return;
41954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  }
41964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
41974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
41984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = ret;
41994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              return;
42004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
42014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            default: // invalid subfunction
42024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              BX_DEBUG_INT15("INT 15h C2 AL=0, BH=%02x\n", (unsigned) regs.u.r8.bh);
42034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();  // error
42044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = 1; // invalid subfunction
42054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              return;
42064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
42074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
42084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
42094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 1: // Reset Mouse
42104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 5: // Initialize Mouse
42114d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 1 or 5:\n");
42124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (regs.u.r8.al == 5) {
42134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (regs.u.r8.bh != 3) {
42144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
42154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = 0x02; // invalid input
42164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              return;
42174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
42184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            mouse_flags_2 = read_byte(ebda_seg, 0x0027);
42194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            mouse_flags_2 = (mouse_flags_2 & 0x00) | regs.u.r8.bh;
42204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            mouse_flags_1 = 0x00;
42214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            write_byte(ebda_seg, 0x0026, mouse_flags_1);
42224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            write_byte(ebda_seg, 0x0027, mouse_flags_2);
42234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
42244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
42254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          inhibit_mouse_int_and_events(); // disable IRQ12 and packets
42264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          ret = send_to_mouse_ctrl(0xFF); // reset mouse command
42274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (ret == 0) {
42284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            ret = get_mouse_data(&mouse_data3);
42294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // if no mouse attached, it will return RESEND
42304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (mouse_data3 == 0xfe) {
42314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
42324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              return;
42334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
42344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (mouse_data3 != 0xfa)
42354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              BX_PANIC("Mouse reset returned %02x (should be ack)\n", (unsigned)mouse_data3);
42364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if ( ret == 0 ) {
42374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = get_mouse_data(&mouse_data1);
42384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if ( ret == 0 ) {
42394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = get_mouse_data(&mouse_data2);
42404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if ( ret == 0 ) {
42414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  // turn IRQ12 and packet generation on
42424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  enable_mouse_int_and_events();
42434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  CLEAR_CF();
42444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  regs.u.r8.ah = 0;
42454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  regs.u.r8.bl = mouse_data1;
42464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  regs.u.r8.bh = mouse_data2;
42474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  return;
42484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  }
42494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
42504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              }
42514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
42524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
42534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // error
42544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF();
42554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = ret;
42564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
42574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
42584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 2: // Set Sample Rate
42594d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 2:\n");
42604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          switch (regs.u.r8.bh) {
42614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 0: mouse_data1 = 10; break; //  10 reports/sec
42624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 1: mouse_data1 = 20; break; //  20 reports/sec
42634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 2: mouse_data1 = 40; break; //  40 reports/sec
42644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 3: mouse_data1 = 60; break; //  60 reports/sec
42654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 4: mouse_data1 = 80; break; //  80 reports/sec
42664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 5: mouse_data1 = 100; break; // 100 reports/sec (default)
42674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 6: mouse_data1 = 200; break; // 200 reports/sec
42684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            default: mouse_data1 = 0;
42694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
42704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (mouse_data1 > 0) {
42714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            ret = send_to_mouse_ctrl(0xF3); // set sample rate command
42724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (ret == 0) {
42734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = get_mouse_data(&mouse_data2);
42744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = send_to_mouse_ctrl(mouse_data1);
42754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = get_mouse_data(&mouse_data2);
42764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              CLEAR_CF();
42774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = 0;
42784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            } else {
42794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              // error
42804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
42814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = UNSUPPORTED_FUNCTION;
42824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
42834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          } else {
42844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // error
42854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_CF();
42864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            regs.u.r8.ah = UNSUPPORTED_FUNCTION;
42874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
42884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
42894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
42904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 3: // Set Resolution
42914d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 3:\n");
42924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // BH:
42934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          //      0 =  25 dpi, 1 count  per millimeter
42944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          //      1 =  50 dpi, 2 counts per millimeter
42954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          //      2 = 100 dpi, 4 counts per millimeter
42964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          //      3 = 200 dpi, 8 counts per millimeter
42974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
42984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (regs.u.r8.bh < 4) {
42994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            ret = send_to_mouse_ctrl(0xE8); // set resolution command
43004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (ret == 0) {
43014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = get_mouse_data(&mouse_data1);
43024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (mouse_data1 != 0xfa)
43034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1);
43044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = send_to_mouse_ctrl(regs.u.r8.bh);
43054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = get_mouse_data(&mouse_data1);
43064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (mouse_data1 != 0xfa)
43074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1);
43084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              CLEAR_CF();
43094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = 0;
43104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            } else {
43114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              // error
43124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
43134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = UNSUPPORTED_FUNCTION;
43144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
43154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          } else {
43164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // error
43174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_CF();
43184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            regs.u.r8.ah = UNSUPPORTED_FUNCTION;
43194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
43204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
43214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
43224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
43234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 4: // Get Device ID
43244d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 4:\n");
43254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          inhibit_mouse_int_and_events(); // disable IRQ12 and packets
43264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          ret = send_to_mouse_ctrl(0xF2); // get mouse ID command
43274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (ret == 0) {
43284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            ret = get_mouse_data(&mouse_data1);
43294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            ret = get_mouse_data(&mouse_data2);
43304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            CLEAR_CF();
43314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            regs.u.r8.ah = 0;
43324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            regs.u.r8.bh = mouse_data2;
43334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          } else {
43344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // error
43354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_CF();
43364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            regs.u.r8.ah = UNSUPPORTED_FUNCTION;
43374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
43384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
43394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
43404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 6: // Return Status & Set Scaling Factor...
43414d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 6:\n");
43424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          switch (regs.u.r8.bh) {
43434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 0: // Return Status
43444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
43454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              ret = send_to_mouse_ctrl(0xE9); // get mouse info command
43464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (ret == 0) {
43474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = get_mouse_data(&mouse_data1);
43484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if (mouse_data1 != 0xfa)
43494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1);
43504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if (ret == 0) {
43514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  ret = get_mouse_data(&mouse_data1);
43524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  if ( ret == 0 ) {
43534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    ret = get_mouse_data(&mouse_data2);
43544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    if ( ret == 0 ) {
43554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                      ret = get_mouse_data(&mouse_data3);
43564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                      if ( ret == 0 ) {
43574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        CLEAR_CF();
43584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r8.ah = 0;
43594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r8.bl = mouse_data1;
43604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r8.cl = mouse_data2;
43614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r8.dl = mouse_data3;
43624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
43634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        return;
43644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        }
43654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                      }
43664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    }
43674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                  }
43684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
43694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
43704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              // error
43714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              SET_CF();
43724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              regs.u.r8.ah = ret;
43734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
43744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              return;
43754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
43764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 1: // Set Scaling Factor to 1:1
43774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            case 2: // Set Scaling Factor to 2:1
43784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
43794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (regs.u.r8.bh == 1) {
43804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = send_to_mouse_ctrl(0xE6);
43814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              } else {
43824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = send_to_mouse_ctrl(0xE7);
43834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              }
43844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (ret == 0) {
43854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                get_mouse_data(&mouse_data1);
43864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ret = (mouse_data1 != 0xFA);
43874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              }
43884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              if (ret == 0) {
43894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                CLEAR_CF();
43904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                regs.u.r8.ah = 0;
43914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              } else {
43924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                // error
43934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                SET_CF();
43944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                regs.u.r8.ah = UNSUPPORTED_FUNCTION;
43954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              }
43964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
43974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              break;
43984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
43994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            default:
44004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              BX_PANIC("INT 15h C2 AL=6, BH=%02x\n", (unsigned) regs.u.r8.bh);
44014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
44024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
44034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 7: // Set Mouse Handler Address
44054d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case 7:\n");
44064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mouse_driver_seg = ES;
44074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mouse_driver_offset = regs.u.r16.bx;
44084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(ebda_seg, 0x0022, mouse_driver_offset);
44094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(ebda_seg, 0x0024, mouse_driver_seg);
44104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mouse_flags_2 = read_byte(ebda_seg, 0x0027);
44114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (mouse_driver_offset == 0 && mouse_driver_seg == 0) {
44124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            /* remove handler */
44134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if ( (mouse_flags_2 & 0x80) != 0 ) {
44144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              mouse_flags_2 &= ~0x80;
44154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              inhibit_mouse_int_and_events(); // disable IRQ12 and packets
44164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              }
44174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
44184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          else {
44194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            /* install handler */
44204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            mouse_flags_2 |= 0x80;
44214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
44224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg, 0x0027, mouse_flags_2);
44234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF();
44244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 0;
44254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
44264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        default:
44284d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("case default:\n");
44294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ah = 1; // invalid function
44304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF();
44314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
44324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
44334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
44354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n",
44364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx);
44374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
44384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
44394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
44404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
44414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
44424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_USE_PS2_MOUSE
44434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid set_e820_range(ES, DI, start, end, extra_start, extra_end, type)
44464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit16u ES;
44474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit16u DI;
44484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit32u start;
44494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit32u end;
44504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit8u extra_start;
44514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit8u extra_end;
44524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     Bit16u type;
44534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
44544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI, start);
44554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+2, start >> 16);
44564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+4, extra_start);
44574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+6, 0x00);
44584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    end -= start;
44604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    extra_end -= extra_start;
44614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+8, end);
44624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+10, end >> 16);
44634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+12, extra_end);
44644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+14, 0x0000);
44654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+16, type);
44674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(ES, DI+18, 0x0);
44684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
44694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
44714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_function32(regs, ES, DS, FLAGS)
44724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushad_regs_t regs; // REGS pushed via pushad
44734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ES, DS, FLAGS;
44744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
44754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u  extended_memory_size=0; // 64bits long
44764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u  extra_lowbits_memory_size=0;
44774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  CX,DX;
44784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u   extra_highbits_memory_size=0;
44794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44804d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax);
44814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (regs.u.r8.ah) {
44834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x86:
44844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Wait for CX:DX microseconds. currently using the
44854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // refresh request port 0x61 bit4, toggling every 15usec
44864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CX = regs.u.r16.cx;
44884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      DX = regs.u.r16.dx;
44894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44904d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
44914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sti
44924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
44934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; Get the count in eax
44944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bx, sp
44954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SEG SS
44964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ax, _int15_function32.CX [bx]
44974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shl  eax, #16
44984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SEG SS
44994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  ax, _int15_function32.DX [bx]
45004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; convert to numbers of 15usec ticks
45024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ebx, #15
45034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      xor edx, edx
45044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      div eax, ebx
45054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ecx, eax
45064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; wait for ecx number of refresh requests
45084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      in al, #0x61
45094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      and al,#0x10
45104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ah, al
45114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      or ecx, ecx
45134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      je int1586_tick_end
45144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1586_tick:
45154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      in al, #0x61
45164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      and al,#0x10
45174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cmp al, ah
45184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      je  int1586_tick
45194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ah, al
45204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      dec ecx
45214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      jnz int1586_tick
45224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1586_tick_end:
45234d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
45244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
45264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xe8:
45284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        switch(regs.u.r8.al)
45294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        {
45304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         case 0x20: // coded by osmaker aka K.J.
45314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if(regs.u.r32.edx == 0x534D4150)
45324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            {
45334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extended_memory_size = inb_cmos(0x35);
45344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extended_memory_size <<= 8;
45354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extended_memory_size |= inb_cmos(0x34);
45364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extended_memory_size *= 64;
45374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                // greater than EFF00000???
45384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if(extended_memory_size > 0x3bc000) {
45394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
45404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
45414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extended_memory_size *= 1024;
45424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extended_memory_size += (16L * 1024 * 1024);
45434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                if(extended_memory_size <= (16L * 1024 * 1024)) {
45454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    extended_memory_size = inb_cmos(0x31);
45464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    extended_memory_size <<= 8;
45474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    extended_memory_size |= inb_cmos(0x30);
45484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    extended_memory_size *= 1024;
45494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    extended_memory_size += (1L * 1024 * 1024);
45504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
45514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extra_lowbits_memory_size = inb_cmos(0x5c);
45534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extra_lowbits_memory_size <<= 8;
45544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extra_lowbits_memory_size |= inb_cmos(0x5b);
45554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extra_lowbits_memory_size *= 64;
45564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extra_lowbits_memory_size *= 1024;
45574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                extra_highbits_memory_size = inb_cmos(0x5d);
45584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
45594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                switch(regs.u.r16.bx)
45604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                {
45614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 0:
45624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       0x0000000L, 0x0009f000L, 0, 0, 1);
45644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 1;
45654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
45664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 1:
45674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       0x0009f000L, 0x000a0000L, 0, 0, 2);
45694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 2;
45704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
45714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 2:
45724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       0x000e8000L, 0x00100000L, 0, 0, 2);
45744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 3;
45754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
45764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 3:
45774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ROMBIOS32
45784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       0x00100000L,
45804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       extended_memory_size - ACPI_DATA_SIZE ,0, 0, 1);
45814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 4;
45824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
45834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       0x00100000L,
45854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       extended_memory_size, 1);
45864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 5;
45874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
45884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
45894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 4:
45904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       extended_memory_size - ACPI_DATA_SIZE,
45924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       extended_memory_size ,0, 0, 3); // ACPI RAM
45934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 5;
45944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
45954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 5:
45964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        /* 256KB BIOS area at the end of 4 GB */
45974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di,
45984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       0xfffc0000L, 0x00000000L ,0, 0, 2);
45994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        if (extra_highbits_memory_size || extra_lowbits_memory_size)
46004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                            regs.u.r32.ebx = 6;
46014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        else
46024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                            regs.u.r32.ebx = 0;
46034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
46044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    case 6:
46054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        /* Maping of memory above 4 GB */
46064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        set_e820_range(ES, regs.u.r16.di, 0x00000000L,
46074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        extra_lowbits_memory_size, 1, extra_highbits_memory_size
46084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                       + 1, 1);
46094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        regs.u.r32.ebx = 0;
46104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
46114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                    default:  /* AX=E820, DX=534D4150, BX unrecognized */
46124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        goto int15_unimplemented;
46134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        break;
46144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                }
46154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                regs.u.r32.eax = 0x534D4150;
46164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                regs.u.r32.ecx = 0x14;
46174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                CLEAR_CF();
46184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            } else {
46194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              // if DX != 0x534D4150)
46204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              goto int15_unimplemented;
46214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
46224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            break;
46234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x01:
46254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // do we have any reason to fail here ?
46264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CLEAR_CF();
46274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // my real system sets ax and bx to 0
46294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // this is confirmed by Ralph Brown list
46304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // but syslinux v1.48 is known to behave
46314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // strangely if ax is set to 0
46324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // regs.u.r16.ax = 0;
46334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // regs.u.r16.bx = 0;
46344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Get the amount of extended memory (above 1M)
46364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.cl = inb_cmos(0x30);
46374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.ch = inb_cmos(0x31);
46384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // limit to 15M
46404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if(regs.u.r16.cx > 0x3c00)
46414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          {
46424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            regs.u.r16.cx = 0x3c00;
46434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
46444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Get the amount of extended memory above 16M in 64k blocs
46464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.dl = inb_cmos(0x34);
46474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r8.dh = inb_cmos(0x35);
46484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Set configured memory equal to extended memory
46504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r16.ax = regs.u.r16.cx;
46514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          regs.u.r16.bx = regs.u.r16.dx;
46524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
46534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        default:  /* AH=0xE8?? but not implemented */
46544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          goto int15_unimplemented;
46554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       }
46564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       break;
46574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    int15_unimplemented:
46584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       // fall into the default
46594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
46604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n",
46614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx);
46624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
46634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
46644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
46654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
46664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
46674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
46694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_function(DI, SI, BP, SP, BX, DX, CX, AX, FLAGS)
46704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u DI, SI, BP, SP, BX, DX, CX, AX, FLAGS;
46714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
46724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u scan_code, ascii_code, shift_flags, led_flags, count;
46734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u kbd_code, max;
46744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT16("int16: AX=%04x BX=%04x CX=%04x DX=%04x \n", AX, BX, CX, DX);
46764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shift_flags = read_byte(0x0040, 0x17);
46784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  led_flags = read_byte(0x0040, 0x97);
46794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((((shift_flags >> 4) & 0x07) ^ (led_flags & 0x07)) != 0) {
46804d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
46814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cli
46824d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
46834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    outb(0x60, 0xed);
46844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    while ((inb(0x64) & 0x01) == 0) outb(0x80, 0x21);
46854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((inb(0x60) == 0xfa)) {
46864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      led_flags &= 0xf8;
46874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      led_flags |= ((shift_flags >> 4) & 0x07);
46884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x60, led_flags & 0x07);
46894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while ((inb(0x64) & 0x01) == 0) outb(0x80, 0x21);
46904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      inb(0x60);
46914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x97, led_flags);
46924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
46934d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
46944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sti
46954d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
46964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
46974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
46984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (GET_AH()) {
46994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x00: /* read keyboard input */
47004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( !dequeue_key(&scan_code, &ascii_code, 1) ) {
47024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("KBD: int16h: out of keyboard input\n");
47034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
47054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else if (ascii_code == 0xE0) ascii_code = 0;
47064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      AX = (scan_code << 8) | ascii_code;
47074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: /* check keyboard status */
47104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( !dequeue_key(&scan_code, &ascii_code, 0) ) {
47114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_ZF();
47124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
47134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
47154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else if (ascii_code == 0xE0) ascii_code = 0;
47164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      AX = (scan_code << 8) | ascii_code;
47174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_ZF();
47184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02: /* get shift flag status */
47214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags = read_byte(0x0040, 0x17);
47224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(shift_flags);
47234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x05: /* store key-stroke into buffer */
47264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( !enqueue_key(GET_CH(), GET_CL()) ) {
47274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AL(1);
47284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
47304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AL(0);
47314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x09: /* GET KEYBOARD FUNCTIONALITY */
47354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // bit Bochs Description
47364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  7    0   reserved
47374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  6    0   INT 16/AH=20h-22h supported (122-key keyboard support)
47384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  5    1   INT 16/AH=10h-12h supported (enhanced keyboard support)
47394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  4    1   INT 16/AH=0Ah supported
47404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  3    0   INT 16/AX=0306h supported
47414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  2    0   INT 16/AX=0305h supported
47424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  1    0   INT 16/AX=0304h supported
47434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //  0    0   INT 16/AX=0300h supported
47444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
47454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(0x30);
47464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0A: /* GET KEYBOARD ID */
47494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count = 2;
47504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      kbd_code = 0x0;
47514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x60, 0xf2);
47524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* Wait for data */
47534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      max=0xffff;
47544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x00);
47554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (max>0x0) {
47564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ((inb(0x60) == 0xfa)) {
47574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          do {
47584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            max=0xffff;
47594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x00);
47604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            if (max>0x0) {
47614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              kbd_code >>= 8;
47624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              kbd_code |= (inb(0x60) << 8);
47634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
47644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          } while (--count>0);
47654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
47674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX=kbd_code;
47684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x10: /* read MF-II keyboard input */
47714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( !dequeue_key(&scan_code, &ascii_code, 1) ) {
47734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("KBD: int16h: out of keyboard input\n");
47744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
47764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      AX = (scan_code << 8) | ascii_code;
47774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x11: /* check MF-II keyboard status */
47804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( !dequeue_key(&scan_code, &ascii_code, 0) ) {
47814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_ZF();
47824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
47834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
47844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
47854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      AX = (scan_code << 8) | ascii_code;
47864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_ZF();
47874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x12: /* get extended keyboard status */
47904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags = read_byte(0x0040, 0x17);
47914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(shift_flags);
47924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags = read_byte(0x0040, 0x18) & 0x73;
47934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags |= read_byte(0x0040, 0x96) & 0x0c;
47944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(shift_flags);
47954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_DEBUG_INT16("int16: func 12 sending %04x\n",AX);
47964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
47974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
47984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x92: /* keyboard capability check called by DOS 5.0+ keyb */
47994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x80); // function int16 ah=0x10-0x12 supported
48004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
48014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xA2: /* 122 keys capability check called by DOS 5.0+ keyb */
48034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // don't change AH : function int16 ah=0x20-0x22 NOT supported
48044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
48054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x6F:
48074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (GET_AL() == 0x08)
48084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x02); // unsupported, aka normal keyboard
48094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
48114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("KBD: unsupported int 16h function %02x\n", GET_AH());
48124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
48134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
48144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned int
48164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadequeue_key(scan_code, ascii_code, incr)
48174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u *scan_code;
48184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u *ascii_code;
48194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned int incr;
48204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
48214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u buffer_start, buffer_end, buffer_head, buffer_tail;
48224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss;
48234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  acode, scode;
48244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_CPU < 2
48264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_start = 0x001E;
48274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_end   = 0x003E;
48284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
48294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_start = read_word(0x0040, 0x0080);
48304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_end   = read_word(0x0040, 0x0082);
48314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
48324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_head = read_word(0x0040, 0x001a);
48344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_tail = read_word(0x0040, 0x001c);
48354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (buffer_head != buffer_tail) {
48374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ss = get_SS();
48384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    acode = read_byte(0x0040, buffer_head);
48394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    scode = read_byte(0x0040, buffer_head+1);
48404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ss, ascii_code, acode);
48414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(ss, scan_code, scode);
48424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (incr) {
48444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      buffer_head += 2;
48454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (buffer_head >= buffer_end)
48464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        buffer_head = buffer_start;
48474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(0x0040, 0x001a, buffer_head);
48484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
48494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(1);
48504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
48514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
48524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(0);
48534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
48544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
48554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char panic_msg_keyb_buffer_full[] = "%s: keyboard input buffer full\n";
48574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
48594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainhibit_mouse_int_and_events()
48604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
48614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u command_byte, prev_command_byte;
48624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Turn off IRQ generation and aux data line
48644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( inb(0x64) & 0x02 )
48654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse");
48664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0x20); // get command byte
48674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while ( (inb(0x64) & 0x01) != 0x01 );
48684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  prev_command_byte = inb(0x60);
48694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  command_byte = prev_command_byte;
48704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //while ( (inb(0x64) & 0x02) );
48714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( inb(0x64) & 0x02 )
48724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse");
48734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  command_byte &= 0xfd; // turn off IRQ 12 generation
48744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  command_byte |= 0x20; // disable mouse serial clock line
48754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0x60); // write command byte
48764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x60, command_byte);
48774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(prev_command_byte);
48784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
48794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
48814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaenable_mouse_int_and_events()
48824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
48834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u command_byte;
48844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
48854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Turn on IRQ generation and aux data line
48864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( inb(0x64) & 0x02 )
48874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse");
48884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0x20); // get command byte
48894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while ( (inb(0x64) & 0x01) != 0x01 );
48904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  command_byte = inb(0x60);
48914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //while ( (inb(0x64) & 0x02) );
48924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( inb(0x64) & 0x02 )
48934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse");
48944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  command_byte |= 0x02; // turn on IRQ 12 generation
48954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  command_byte &= 0xdf; // enable mouse serial clock line
48964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0x60); // write command byte
48974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x60, command_byte);
48984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
48994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
49014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimasend_to_mouse_ctrl(sendbyte)
49024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u sendbyte;
49034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
49044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u response;
49054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // wait for chance to write to ctrl
49074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( inb(0x64) & 0x02 )
49084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC(panic_msg_keyb_buffer_full,"sendmouse");
49094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0xD4);
49104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x60, sendbyte);
49114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(0);
49124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
49134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u
49164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaget_mouse_data(data)
49174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u *data;
49184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
49194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u response;
49204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss;
49214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while ( (inb(0x64) & 0x21) != 0x21 ) {
49234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
49244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  response = inb(0x60);
49264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ss = get_SS();
49284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ss, data, response);
49294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(0);
49304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
49314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
49334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaset_kbd_command_byte(command_byte)
49344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u command_byte;
49354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
49364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( inb(0x64) & 0x02 )
49374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC(panic_msg_keyb_buffer_full,"setkbdcomm");
49384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0xD4);
49394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x64, 0x60); // write command byte
49414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x60, command_byte);
49424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
49434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
49454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint09_function(DI, SI, BP, SP, BX, DX, CX, AX)
49464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u DI, SI, BP, SP, BX, DX, CX, AX;
49474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
49484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u scancode, asciicode, shift_flags;
49494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u mf2_flags, mf2_state;
49504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //
49524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // DS has been set to F000 before call
49534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //
49544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  scancode = GET_AL();
49574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (scancode == 0) {
49594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("KBD: int09 handler: AL=0\n");
49604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
49614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
49624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shift_flags = read_byte(0x0040, 0x17);
49654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mf2_flags = read_byte(0x0040, 0x18);
49664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mf2_state = read_byte(0x0040, 0x96);
49674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  asciicode = 0;
49684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (scancode) {
49704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x3a: /* Caps Lock press */
49714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags ^= 0x40;
49724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
49734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mf2_flags |= 0x40;
49744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x18, mf2_flags);
49754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
49764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xba: /* Caps Lock release */
49774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mf2_flags &= ~0x40;
49784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x18, mf2_flags);
49794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
49804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x2a: /* L Shift press */
49824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags |= 0x02;
49834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
49844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
49854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xaa: /* L Shift release */
49864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags &= ~0x02;
49874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
49884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
49894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x36: /* R Shift press */
49914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags |= 0x01;
49924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
49934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
49944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xb6: /* R Shift release */
49954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags &= ~0x01;
49964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
49974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
49984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
49994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x1d: /* Ctrl press */
50004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((mf2_state & 0x01) == 0) {
50014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        shift_flags |= 0x04;
50024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x17, shift_flags);
50034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (mf2_state & 0x02) {
50044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mf2_state |= 0x04;
50054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(0x0040, 0x96, mf2_state);
50064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
50074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mf2_flags |= 0x01;
50084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(0x0040, 0x18, mf2_flags);
50094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
50104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x9d: /* Ctrl release */
50134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((mf2_state & 0x01) == 0) {
50144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        shift_flags &= ~0x04;
50154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x17, shift_flags);
50164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (mf2_state & 0x02) {
50174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mf2_state &= ~0x04;
50184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(0x0040, 0x96, mf2_state);
50194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
50204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          mf2_flags &= ~0x01;
50214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(0x0040, 0x18, mf2_flags);
50224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
50234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
50264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x38: /* Alt press */
50274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags |= 0x08;
50284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
50294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (mf2_state & 0x02) {
50304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mf2_state |= 0x08;
50314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x96, mf2_state);
50324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else {
50334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mf2_flags |= 0x02;
50344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x18, mf2_flags);
50354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xb8: /* Alt release */
50384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags &= ~0x08;
50394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
50404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (mf2_state & 0x02) {
50414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mf2_state &= ~0x08;
50424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x96, mf2_state);
50434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else {
50444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mf2_flags &= ~0x02;
50454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x18, mf2_flags);
50464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
50494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x45: /* Num Lock press */
50504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((mf2_state & 0x03) == 0) {
50514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mf2_flags |= 0x20;
50524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x18, mf2_flags);
50534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        shift_flags ^= 0x20;
50544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x17, shift_flags);
50554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xc5: /* Num Lock release */
50584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((mf2_state & 0x03) == 0) {
50594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mf2_flags &= ~0x20;
50604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x18, mf2_flags);
50614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
50644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x46: /* Scroll Lock press */
50654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mf2_flags |= 0x10;
50664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x18, mf2_flags);
50674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      shift_flags ^= 0x10;
50684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x17, shift_flags);
50694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
50714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xc6: /* Scroll Lock release */
50724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mf2_flags &= ~0x10;
50734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x18, mf2_flags);
50744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
50754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
50764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
50774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scancode & 0x80) {
50784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break; /* toss key releases ... */
50794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scancode > MAX_SCAN_CODE) {
50814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("KBD: int09h_handler(): unknown scancode read: 0x%02x!\n", scancode);
50824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
50834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
50844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (shift_flags & 0x08) { /* ALT */
50854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        asciicode = scan_to_scanascii[scancode].alt;
50864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        scancode = scan_to_scanascii[scancode].alt >> 8;
50874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (shift_flags & 0x04) { /* CONTROL */
50884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        asciicode = scan_to_scanascii[scancode].control;
50894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        scancode = scan_to_scanascii[scancode].control >> 8;
50904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (((mf2_state & 0x02) > 0) && ((scancode >= 0x47) && (scancode <= 0x53))) {
50914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        /* extended keys handling */
50924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        asciicode = 0xe0;
50934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        scancode = scan_to_scanascii[scancode].normal >> 8;
50944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (shift_flags & 0x03) { /* LSHIFT + RSHIFT */
50954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        /* check if lock state should be ignored
50964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima         * because a SHIFT key are pressed */
50974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
50984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (shift_flags & scan_to_scanascii[scancode].lock_flags) {
50994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          asciicode = scan_to_scanascii[scancode].normal;
51004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          scancode = scan_to_scanascii[scancode].normal >> 8;
51014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
51024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          asciicode = scan_to_scanascii[scancode].shift;
51034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          scancode = scan_to_scanascii[scancode].shift >> 8;
51044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
51054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else {
51064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        /* check if lock is on */
51074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (shift_flags & scan_to_scanascii[scancode].lock_flags) {
51084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          asciicode = scan_to_scanascii[scancode].shift;
51094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          scancode = scan_to_scanascii[scancode].shift >> 8;
51104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
51114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          asciicode = scan_to_scanascii[scancode].normal;
51124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          scancode = scan_to_scanascii[scancode].normal >> 8;
51134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
51144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
51154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (scancode==0 && asciicode==0) {
51164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("KBD: int09h_handler(): scancode & asciicode are zero?\n");
51174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
51184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      enqueue_key(scancode, asciicode);
51194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
51204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
51214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((scancode & 0x7f) != 0x1d) {
51224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mf2_state &= ~0x01;
51234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
51244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mf2_state &= ~0x02;
51254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x96, mf2_state);
51264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
51274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned int
51294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaenqueue_key(scan_code, ascii_code)
51304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u scan_code, ascii_code;
51314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
51324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u buffer_start, buffer_end, buffer_head, buffer_tail, temp_tail;
51334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_CPU < 2
51354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_start = 0x001E;
51364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_end   = 0x003E;
51374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
51384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_start = read_word(0x0040, 0x0080);
51394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_end   = read_word(0x0040, 0x0082);
51404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
51414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_head = read_word(0x0040, 0x001A);
51434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_tail = read_word(0x0040, 0x001C);
51444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  temp_tail = buffer_tail;
51464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  buffer_tail += 2;
51474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (buffer_tail >= buffer_end)
51484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    buffer_tail = buffer_start;
51494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (buffer_tail == buffer_head) {
51514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(0);
51524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
51534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   write_byte(0x0040, temp_tail, ascii_code);
51554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   write_byte(0x0040, temp_tail+1, scan_code);
51564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   write_word(0x0040, 0x001C, buffer_tail);
51574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   return(1);
51584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
51594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
51624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint74_function(make_farcall, Z, Y, X, status)
51634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u make_farcall, Z, Y, X, status;
51644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
51654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
51664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  in_byte, index, package_count;
51674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  mouse_flags_1, mouse_flags_2;
51684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51694d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT74("entering int74_function\n");
51704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  make_farcall = 0;
51714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in_byte = inb(0x64);
51734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( (in_byte & 0x21) != 0x21 ) {
51744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
51754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
51764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in_byte = inb(0x60);
51774d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT74("int74: read byte %02x\n", in_byte);
51784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mouse_flags_1 = read_byte(ebda_seg, 0x0026);
51804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mouse_flags_2 = read_byte(ebda_seg, 0x0027);
51814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( (mouse_flags_2 & 0x80) != 0x80 ) {
51834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
51844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
51854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  package_count = mouse_flags_2 & 0x07;
51874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  index = mouse_flags_1 & 0x07;
51884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg, 0x28 + index, in_byte);
51894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
51904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( (index+1) >= package_count ) {
51914d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT74("int74_function: make_farcall=1\n");
51924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = read_byte(ebda_seg, 0x0028 + 0);
51934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    X      = read_byte(ebda_seg, 0x0028 + 1);
51944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Y      = read_byte(ebda_seg, 0x0028 + 2);
51954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    Z      = 0;
51964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mouse_flags_1 = 0;
51974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // check if far call handler installed
51984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (mouse_flags_2 & 0x80)
51994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      make_farcall = 1;
52004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
52014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
52024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mouse_flags_1++;
52034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
52044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ebda_seg, 0x0026, mouse_flags_1);
52054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
52064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
52084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
52104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
52124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_harddisk(EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
52134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
52144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
52154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u lba_low, lba_high;
52164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
52174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u cylinder, head, sector;
52184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u segment, offset;
52194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u npc, nph, npspt, nlc, nlh, nlspt;
52204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u size, count;
52214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  device, status;
52224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_HD("int13_harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
52244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x008e, 0);  // clear completion flag
52264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // basic check : device has to be defined
52284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( (GET_ELDL() < 0x80) || (GET_ELDL() >= 0x80 + BX_MAX_ATA_DEVICES) ) {
52294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("int13_harddisk: function %02x, ELDL out of range %02x\n", GET_AH(), GET_ELDL());
52304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    goto int13_fail;
52314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
52324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Get the ata channel
52344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  device=read_byte(ebda_seg,&EbdaData->ata.hdidmap[GET_ELDL()-0x80]);
52354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // basic check : device has to be valid
52374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (device >= BX_MAX_ATA_DEVICES) {
52384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("int13_harddisk: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_ELDL());
52394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    goto int13_fail;
52404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
52414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (GET_AH()) {
52434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x00: /* disk controller reset */
52454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ata_reset (device);
52464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
52474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
52484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: /* read disk status */
52504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = read_byte(0x0040, 0x0074);
52514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(status);
52524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
52534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* set CF if error status read */
52544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status) goto int13_fail_nostatus;
52554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else        goto int13_success_noah;
52564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
52574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02: // read disk sectors
52594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x03: // write disk sectors
52604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x04: // verify disk sectors
52614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count       = GET_AL();
52634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinder    = GET_CH();
52644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinder   |= ( ((Bit16u) GET_CL()) << 2) & 0x300;
52654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector      = (GET_CL() & 0x3f);
52664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      head        = GET_DH();
52674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      segment = ES;
52694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      offset  = BX;
52704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((count > 128) || (count == 0) || (sector == 0)) {
52724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_harddisk: function %02x, parameter out of range!\n",GET_AH());
52734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
52744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
52754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlc   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders);
52774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlh   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads);
52784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt);
52794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // sanity check on cyl heads, sec
52814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt )) {
52824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_harddisk: function %02x, parameters out of range %04x/%04x/%04x!\n", GET_AH(), cylinder, head, sector);
52834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
52844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
52854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME verify
52874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( GET_AH() == 0x04 ) goto int13_success;
52884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nph   = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads);
52904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt);
52914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // if needed, translate lchs to lba, and execute command
52934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (nph != nlh) || (npspt != nlspt)) {
52944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lba_low = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1;
52954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lba_high = 0;
52964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sector = 0; // this forces the command to be lba
52974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
52984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
52994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( GET_AH() == 0x02 )
53004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset);
53014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else
53024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset);
53034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Set nb of sector transferred
53054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(read_word(ebda_seg, &EbdaData->ata.trsfsectors));
53064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status != 0) {
53084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status);
53094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x0c);
53104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
53114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
53124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
53144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
53154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x05: /* format disk track */
53174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("format disk track called\n");
53184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
53194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
53204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
53214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x08: /* read disk drive parameters */
53234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get logical geometry from table
53254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlc   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders);
53264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlh   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads);
53274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt);
53284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count = read_byte(ebda_seg, &EbdaData->ata.hdcount);
53294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlc = nlc - 2; /* 0 based , last sector not used */
53314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(0);
53324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CH(nlc & 0xff);
53334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f));
53344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DH(nlh - 1);
53354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DL(count); /* FIXME returns 0, 1, or n hard drives */
53364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME should set ES & DI
53384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
53404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
53414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x10: /* check drive ready */
53434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // should look at 40:8E also???
53444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Read the status from controller
53464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = inb(read_word(ebda_seg, &EbdaData->ata.channels[device/2].iobase1) + ATA_CB_STAT);
53474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (status & ( ATA_CB_STAT_BSY | ATA_CB_STAT_RDY )) == ATA_CB_STAT_RDY ) {
53484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_success;
53494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
53504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
53514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0xAA);
53524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
53534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
53544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
53554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x15: /* read disk drive size */
53574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get logical geometry from table
53594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlc   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders);
53604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlh   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads);
53614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt);
53624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Compute sector count seen by int13
53644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba_low = (Bit32u)(nlc - 1) * (Bit32u)nlh * (Bit32u)nlspt;
53654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CX = lba_low >> 16;
53664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      DX = lba_low & 0xffff;
53674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(3);  // hard disk accessible
53694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success_noah;
53704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
53714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x41: // IBM/MS installation check
53734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX=0xaa55;     // install check
53744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x30);  // EDD 3.0
53754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CX=0x0007;     // ext disk access and edd, removable supported
53764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success_noah;
53774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
53784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x42: // IBM/MS extended read
53804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x43: // IBM/MS extended write
53814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x44: // IBM/MS verify
53824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x47: // IBM/MS extended seek
53834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count=read_word(DS, SI+(Bit16u)&Int13Ext->count);
53854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment);
53864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset);
53874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get 32 msb lba and check
53894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba_high=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2);
53904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lba_high > read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high) ) {
53914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH());
53924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
53934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
53944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
53954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get 32 lsb lba and check
53964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba_low=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1);
53974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lba_high == read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high)
53984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          && lba_low >= read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low) ) {
53994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH());
54004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
54014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
54024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // If verify or seek
54044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
54054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_success;
54064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Execute the command
54084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( GET_AH() == 0x42 )
54094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset);
54104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else
54114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset);
54124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count=read_word(ebda_seg, &EbdaData->ata.trsfsectors);
54144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(DS, SI+(Bit16u)&Int13Ext->count, count);
54154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status != 0) {
54174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status);
54184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x0c);
54194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
54204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
54214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
54234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
54244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x45: // IBM/MS lock/unlock drive
54264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x49: // IBM/MS extended media change
54274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;    // Always success for HD
54284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
54294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x46: // IBM/MS eject media
54314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0xb2);          // Volume Not Removable
54324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail_noah;  // Always fail for HD
54334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
54344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x48: // IBM/MS get drive parameters
54364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      size=read_word(DS,SI+(Bit16u)&Int13DPT->size);
54374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Buffer is too small
54394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size < 0x1a)
54404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
54414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // EDD 1.x
54434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size >= 0x1a) {
54444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u   blksize;
54454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        npc     = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.cylinders);
54474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        nph     = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads);
54484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        npspt   = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt);
54494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lba_low = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low);
54504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        lba_high = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high);
54514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        blksize = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize);
54524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a);
54544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (lba_high || (lba_low/npspt)/nph > 0x3fff)
54554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        {
54564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x00); // geometry is invalid
54574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, 0x3fff);
54584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
54594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else
54604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        {
54614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
54624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
54634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
54644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph);
54654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt);
54664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba_low);
54674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, lba_high);
54684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->blksize, blksize);
54694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
54704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // EDD 2.x
54724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size >= 0x1e) {
54734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit8u  channel, dev, irq, mode, checksum, i, translation;
54744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u iobase1, iobase2, options;
54754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1e);
54774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->dpte_segment, ebda_seg);
54794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->dpte_offset, &EbdaData->ata.dpte);
54804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Fill in dpte
54824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        channel = device / 2;
54834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
54844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
54854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        irq = read_byte(ebda_seg, &EbdaData->ata.channels[channel].irq);
54864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
54874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        translation = read_byte(ebda_seg, &EbdaData->ata.devices[device].translation);
54884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options  = (translation==ATA_TRANSLATION_NONE?0:1)<<3; // chs translation
54904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (1<<4); // lba translation
54914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (mode==ATA_MODE_PIO32?1:0)<<7;
54924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (translation==ATA_TRANSLATION_LBA?1:0)<<9;
54934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (translation==ATA_TRANSLATION_RECHS?3:0)<<9;
54944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
54954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
54964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC);
54974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 );
54984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
54994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
55004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.blkcount, 1 );
55014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.dma, 0 );
55024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 );
55034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.options, options);
55044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0);
55054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (size >=0x42)
55064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
55074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else
55084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x10);
55094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum=0;
55114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, ((Bit8u*)(&EbdaData->ata.dpte)) + i);
55124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum = ~checksum;
55134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
55144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
55154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // EDD 3.x
55174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size >= 0x42) {
55184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit8u channel, iface, checksum, i;
55194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u iobase1;
55204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        channel = device / 2;
55224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iface = read_byte(ebda_seg, &EbdaData->ata.channels[channel].iface);
55234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
55244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x42);
55264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->key, 0xbedd);
55274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->dpi_length, 0x24);
55284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->reserved1, 0);
55294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->reserved2, 0);
55304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (iface==ATA_IFACE_ISA) {
55324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[0], 'I');
55334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[1], 'S');
55344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[2], 'A');
55354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[3], 0);
55364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
55374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else {
55384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // FIXME PCI
55394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
55404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[0], 'A');
55414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[1], 'T');
55424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[2], 'A');
55434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[3], 0);
55444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (iface==ATA_IFACE_ISA) {
55464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[0], iobase1);
55474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[2], 0);
55484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_dword(DS, SI+(Bit16u)&Int13DPT->iface_path[4], 0L);
55494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
55504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else {
55514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // FIXME PCI
55524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
55534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[0], device%2);
55544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[1], 0);
55554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->device_path[2], 0);
55564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->device_path[4], 0L);
55574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum=0;
55594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
55604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum = ~checksum;
55614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->checksum, checksum);
55624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
55634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
55654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
55664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4e: // // IBM/MS set hardware configuration
55684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // DMA, prefetch, PIO maximum not supported
55694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (GET_AL()) {
55704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x01:
55714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x03:
55724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x04:
55734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x06:
55744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          goto int13_success;
55754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
55764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        default :
55774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          goto int13_fail;
55784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
55794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
55804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x09: /* initialize drive parameters */
55824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0c: /* seek to specified cylinder */
55834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0d: /* alternate disk reset */
55844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x11: /* recalibrate */
55854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x14: /* controller internal diagnostic */
55864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13_harddisk: function %02xh unimplemented, returns success\n", GET_AH());
55874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
55884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
55894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
55904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0a: /* read disk sectors with ECC */
55914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0b: /* write disk sectors with ECC */
55924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x18: // set media type for format
55934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x50: // IBM/MS send packet command
55944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
55954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13_harddisk: function %02xh unsupported, returns fail\n", GET_AH());
55964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail;
55974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
55984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
55994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail:
56014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
56024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail_noah:
56034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(GET_AH());
56044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail_nostatus:
56054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_CF();     // error occurred
56064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
56074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success:
56094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x00); // no error
56104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success_noah:
56114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(0x00);
56124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    CLEAR_CF();   // no error
56134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
56144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
56154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
56174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Start of int13 for cdrom
56184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
56194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
56214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_cdrom(EHBX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
56224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u EHBX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
56234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
56244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
56254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  device, status, locks;
56264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  atacmd[12];
56274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u lba;
56284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u count, segment, offset, i, size;
56294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_CD("int13_cdrom: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
56314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_DISK_RET_STATUS(0x00);
56334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* basic check : device should be 0xE0+ */
56354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0+BX_MAX_ATA_DEVICES) ) {
56364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("int13_cdrom: function %02x, ELDL out of range %02x\n", GET_AH(), GET_ELDL());
56374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    goto int13_fail;
56384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
56394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Get the ata channel
56414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  device=read_byte(ebda_seg,&EbdaData->ata.cdidmap[GET_ELDL()-0xE0]);
56424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* basic check : device has to be valid  */
56444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (device >= BX_MAX_ATA_DEVICES) {
56454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("int13_cdrom: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_ELDL());
56464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    goto int13_fail;
56474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
56484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (GET_AH()) {
56504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // all those functions return SUCCESS
56524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x00: /* disk controller reset */
56534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x09: /* initialize drive parameters */
56544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0c: /* seek to specified cylinder */
56554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0d: /* alternate disk reset */
56564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x10: /* check drive ready */
56574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x11: /* recalibrate */
56584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x14: /* controller internal diagnostic */
56594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x16: /* detect disk change */
56604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
56614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
56624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // all those functions return disk write-protected
56644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x03: /* write disk sectors */
56654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x05: /* format disk track */
56664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x43: // IBM/MS extended write
56674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x03);
56684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail_noah;
56694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
56704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: /* read disk status */
56724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = read_byte(0x0040, 0x0074);
56734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(status);
56744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
56754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* set CF if error status read */
56774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status) goto int13_fail_nostatus;
56784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else        goto int13_success_noah;
56794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
56804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x15: /* read disk drive size */
56824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x02);
56834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail_noah;
56844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
56854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x41: // IBM/MS installation check
56874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX=0xaa55;     // install check
56884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x30);  // EDD 2.1
56894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CX=0x0007;     // ext disk access, removable and edd
56904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success_noah;
56914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
56924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x42: // IBM/MS extended read
56944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x44: // IBM/MS verify sectors
56954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x47: // IBM/MS extended seek
56964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
56974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count=read_word(DS, SI+(Bit16u)&Int13Ext->count);
56984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment);
56994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset);
57004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Can't use 64 bits lba
57024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2);
57034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (lba != 0L) {
57044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("int13_cdrom: function %02x. Can't use 64bits lba\n",GET_AH());
57054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
57064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
57074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Get 32 bits lba
57094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1);
57104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // If verify or seek
57124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
57134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_success;
57144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      memsetb(get_SS(),atacmd,0,12);
57164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[0]=0x28;                      // READ command
57174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[7]=(count & 0xff00) >> 8;     // Sectors
57184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[8]=(count & 0x00ff);          // Sectors
57194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
57204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[3]=(lba & 0x00ff0000) >> 16;
57214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[4]=(lba & 0x0000ff00) >> 8;
57224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[5]=(lba & 0x000000ff);
57234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, count*2048L, ATA_DATA_IN, segment,offset);
57244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      count = (Bit16u)(read_dword(ebda_seg, &EbdaData->ata.trsfbytes) >> 11);
57264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(DS, SI+(Bit16u)&Int13Ext->count, count);
57274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status != 0) {
57294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_cdrom: function %02x, status %02x !\n",GET_AH(),status);
57304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x0c);
57314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
57324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
57334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
57354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
57364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x45: // IBM/MS lock/unlock drive
57384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (GET_AL() > 2) goto int13_fail;
57394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      locks = read_byte(ebda_seg, &EbdaData->ata.devices[device].lock);
57414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (GET_AL()) {
57434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0 :  // lock
57444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (locks == 0xff) {
57454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AH(0xb4);
57464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AL(1);
57474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            goto int13_fail_noah;
57484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
57494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg, &EbdaData->ata.devices[device].lock, ++locks);
57504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(1);
57514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
57524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 1 :  // unlock
57534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (locks == 0x00) {
57544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AH(0xb0);
57554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AL(0);
57564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            goto int13_fail_noah;
57574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            }
57584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(ebda_seg, &EbdaData->ata.devices[device].lock, --locks);
57594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(locks==0?0:1);
57604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
57614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 2 :  // status
57624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(locks==0?0:1);
57634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
57644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
57654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
57664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
57674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x46: // IBM/MS eject media
57694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      locks = read_byte(ebda_seg, &EbdaData->ata.devices[device].lock);
57704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (locks != 0) {
57724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0xb1); // media locked
57734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
57744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
57754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME should handle 0x31 no media in device
57764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME should handle 0xb5 valid request failed
57774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Call removable media eject
57794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
57804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
57814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
57824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov ah, #0x52
57844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        int #0x15
57854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov _int13_cdrom.status + 2[bp], ah
57864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jnc int13_cdrom_rme_end
57874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov _int13_cdrom.status, #1
57884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_cdrom_rme_end:
57894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop bp
57904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
57914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status != 0) {
57934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0xb1); // media locked
57944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
57954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
57964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
57974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
57984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
57994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x48: // IBM/MS get drive parameters
58014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      size = read_word(DS,SI+(Bit16u)&Int13Ext->size);
58024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Buffer is too small
58044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size < 0x1a)
58054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
58064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // EDD 1.x
58084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size >= 0x1a) {
58094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u   cylinders, heads, spt, blksize;
58104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        blksize   = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize);
58124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a);
58144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x74); // removable, media change, lockable, max values
58154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, 0xffffffff);
58164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->heads, 0xffffffff);
58174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->spt, 0xffffffff);
58184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, 0xffffffff);  // FIXME should be Bit64
58194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, 0xffffffff);
58204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->blksize, blksize);
58214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
58224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // EDD 2.x
58244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size >= 0x1e) {
58254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit8u  channel, dev, irq, mode, checksum, i;
58264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u iobase1, iobase2, options;
58274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1e);
58294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->dpte_segment, ebda_seg);
58314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->dpte_offset, &EbdaData->ata.dpte);
58324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Fill in dpte
58344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        channel = device / 2;
58354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
58364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
58374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        irq = read_byte(ebda_seg, &EbdaData->ata.channels[channel].irq);
58384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
58394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // FIXME atapi device
58414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options  = (1<<4); // lba translation
58424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (1<<5); // removable device
58434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (1<<6); // atapi device
58444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        options |= (mode==ATA_MODE_PIO32?1:0<<7);
58454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
58474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC);
58484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 );
58494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
58504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
58514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.blkcount, 1 );
58524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.dma, 0 );
58534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 );
58544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.options, options);
58554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0);
58564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
58574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum=0;
58594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, ((Bit8u*)(&EbdaData->ata.dpte)) + i);
58604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum = ~checksum;
58614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
58624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
58634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // EDD 3.x
58654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(size >= 0x42) {
58664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit8u channel, iface, checksum, i;
58674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit16u iobase1;
58684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        channel = device / 2;
58704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iface = read_byte(ebda_seg, &EbdaData->ata.channels[channel].iface);
58714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
58724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x42);
58744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->key, 0xbedd);
58754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->dpi_length, 0x24);
58764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->reserved1, 0);
58774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->reserved2, 0);
58784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (iface==ATA_IFACE_ISA) {
58804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[0], 'I');
58814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[1], 'S');
58824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[2], 'A');
58834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[3], 0);
58844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
58854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else {
58864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // FIXME PCI
58874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
58884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[0], 'A');
58894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[1], 'T');
58904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[2], 'A');
58914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[3], 0);
58924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
58934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (iface==ATA_IFACE_ISA) {
58944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[0], iobase1);
58954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[2], 0);
58964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_dword(DS, SI+(Bit16u)&Int13DPT->iface_path[4], 0L);
58974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
58984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else {
58994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // FIXME PCI
59004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
59014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[0], device%2);
59024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[1], 0);
59034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_word(DS, SI+(Bit16u)&Int13DPT->device_path[2], 0);
59044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_dword(DS, SI+(Bit16u)&Int13DPT->device_path[4], 0L);
59054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum=0;
59074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
59084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        checksum = ~checksum;
59094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(DS, SI+(Bit16u)&Int13DPT->checksum, checksum);
59104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
59114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
59134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
59144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x49: // IBM/MS extended media change
59164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // always send changed ??
59174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(06);
59184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail_nostatus;
59194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
59204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4e: // // IBM/MS set hardware configuration
59224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // DMA, prefetch, PIO maximum not supported
59234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (GET_AL()) {
59244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x01:
59254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x03:
59264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x04:
59274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x06:
59284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          goto int13_success;
59294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
59304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        default :
59314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          goto int13_fail;
59324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
59334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
59344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // all those functions return unimplemented
59364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02: /* read sectors */
59374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x04: /* verify sectors */
59384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x08: /* read disk drive parameters */
59394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0a: /* read disk sectors with ECC */
59404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0b: /* write disk sectors with ECC */
59414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x18: /* set media type for format */
59424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x50: // ? - send packet command
59434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
59444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13_cdrom: unsupported AH=%02x\n", GET_AH());
59454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail;
59464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
59474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
59484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail:
59504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
59514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail_noah:
59524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(GET_AH());
59534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail_nostatus:
59544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_CF();     // error occurred
59554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
59564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success:
59584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x00); // no error
59594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success_noah:
59604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(0x00);
59614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    CLEAR_CF();   // no error
59624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
59634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
59644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
59664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// End of int13 for cdrom
59674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
59684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
59704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
59714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Start of int13 for eltorito functions
59724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
59734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
59754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_eltorito(DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS)
59764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS;
59774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
59784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
59794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_ET("int13_eltorito: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
59814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // BX_DEBUG_INT13_ET("int13_eltorito: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), DS, ES, DI, SI);
59824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (GET_AH()) {
59844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // FIXME ElTorito Various. Should be implemented
59864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4a: // ElTorito - Initiate disk emu
59874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4c: // ElTorito - Initiate disk emu and boot
59884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4d: // ElTorito - Return Boot catalog
59894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_PANIC("Int13 eltorito call with AX=%04x. Please report\n",AX);
59904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail;
59914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
59924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
59934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4b: // ElTorito - Terminate disk emu
59944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME ElTorito Hardcoded
59954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x00,0x13);
59964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x01,read_byte(ebda_seg,&EbdaData->cdemu.media));
59974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x02,read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive));
59984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x03,read_byte(ebda_seg,&EbdaData->cdemu.controller_index));
59994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_dword(DS,SI+0x04,read_dword(ebda_seg,&EbdaData->cdemu.ilba));
60004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(DS,SI+0x08,read_word(ebda_seg,&EbdaData->cdemu.device_spec));
60014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(DS,SI+0x0a,read_word(ebda_seg,&EbdaData->cdemu.buffer_segment));
60024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(DS,SI+0x0c,read_word(ebda_seg,&EbdaData->cdemu.load_segment));
60034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_word(DS,SI+0x0e,read_word(ebda_seg,&EbdaData->cdemu.sector_count));
60044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x10,read_byte(ebda_seg,&EbdaData->cdemu.vdevice.cylinders));
60054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x11,read_byte(ebda_seg,&EbdaData->cdemu.vdevice.spt));
60064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(DS,SI+0x12,read_byte(ebda_seg,&EbdaData->cdemu.vdevice.heads));
60074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // If we have to terminate emulation
60094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(GET_AL() == 0x00) {
60104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // FIXME ElTorito Various. Should be handled accordingly to spec
60114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(ebda_seg,&EbdaData->cdemu.active, 0x00); // bye bye
60124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
60134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
60154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
60164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
60184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13_eltorito: unsupported AH=%02x\n", GET_AH());
60194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail;
60204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
60214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
60224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail:
60244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
60254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(GET_AH());
60264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_CF();     // error occurred
60274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
60284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success:
60304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x00); // no error
60314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(0x00);
60324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    CLEAR_CF();   // no error
60334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
60344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
60354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
60374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// End of int13 for eltorito functions
60384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
60394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
60414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// Start of int13 when emulating a device from the cd
60424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
60434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
60454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_cdemu(DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS)
60464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS;
60474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
60484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
60494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  device, status;
60504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u vheads, vspt, vcylinders;
60514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u head, sector, cylinder, nbsectors;
60524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u vlba, ilba, slba, elba;
60534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u before, segment, offset;
60544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  atacmd[12];
60554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_ET("int13_cdemu: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
60574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* at this point, we are emulating a floppy/harddisk */
60594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Recompute the device number
60614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  device  = read_byte(ebda_seg,&EbdaData->cdemu.controller_index) * 2;
60624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  device += read_byte(ebda_seg,&EbdaData->cdemu.device_spec);
60634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_DISK_RET_STATUS(0x00);
60654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* basic checks : emulation should be active, dl should equal the emulated drive */
60674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if( (read_byte(ebda_seg,&EbdaData->cdemu.active) ==0 )
60684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   || (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive ) != GET_DL())) {
60694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("int13_cdemu: function %02x, emulation not active for DL= %02x\n", GET_AH(), GET_DL());
60704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    goto int13_fail;
60714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
60724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (GET_AH()) {
60744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // all those functions return SUCCESS
60764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x00: /* disk controller reset */
60774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x09: /* initialize drive parameters */
60784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0c: /* seek to specified cylinder */
60794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0d: /* alternate disk reset */  // FIXME ElTorito Various. should really reset ?
60804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x10: /* check drive ready */     // FIXME ElTorito Various. should check if ready ?
60814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x11: /* recalibrate */
60824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x14: /* controller internal diagnostic */
60834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x16: /* detect disk change */
60844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
60854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
60864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // all those functions return disk write-protected
60884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x03: /* write disk sectors */
60894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x05: /* format disk track */
60904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x03);
60914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail_noah;
60924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
60934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: /* read disk status */
60954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status=read_byte(0x0040, 0x0074);
60964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(status);
60974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
60984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
60994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* set CF if error status read */
61004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status) goto int13_fail_nostatus;
61014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else        goto int13_success_noah;
61024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
61034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02: // read disk sectors
61054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x04: // verify disk sectors
61064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vspt       = read_word(ebda_seg,&EbdaData->cdemu.vdevice.spt);
61074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vcylinders = read_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders);
61084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vheads     = read_word(ebda_seg,&EbdaData->cdemu.vdevice.heads);
61094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ilba       = read_dword(ebda_seg,&EbdaData->cdemu.ilba);
61114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector    = GET_CL() & 0x003f;
61134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinder  = (GET_CL() & 0x00c0) << 2 | GET_CH();
61144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      head      = GET_DH();
61154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nbsectors = GET_AL();
61164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      segment   = ES;
61174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      offset    = BX;
61184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // no sector to read ?
61204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if(nbsectors==0) goto int13_success;
61214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // sanity checks sco openserver needs this!
61234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((sector   >  vspt)
61244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       || (cylinder >= vcylinders)
61254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima       || (head     >= vheads)) {
61264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail;
61274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
61284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // After controls, verify do nothing
61304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (GET_AH() == 0x04) goto int13_success;
61314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      segment = ES+(BX / 16);
61334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      offset  = BX % 16;
61344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // calculate the virtual lba inside the image
61364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vlba=((((Bit32u)cylinder*(Bit32u)vheads)+(Bit32u)head)*(Bit32u)vspt)+((Bit32u)(sector-1));
61374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // In advance so we don't loose the count
61394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(nbsectors);
61404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // start lba on cd
61424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      slba  = (Bit32u)vlba/4;
61434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      before= (Bit16u)vlba%4;
61444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // end lba on cd
61464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      elba = (Bit32u)(vlba+nbsectors-1)/4;
61474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      memsetb(get_SS(),atacmd,0,12);
61494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[0]=0x28;                      // READ command
61504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[7]=((Bit16u)(elba-slba+1) & 0xff00) >> 8; // Sectors
61514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[8]=((Bit16u)(elba-slba+1) & 0x00ff);      // Sectors
61524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[2]=(ilba+slba & 0xff000000) >> 24;  // LBA
61534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[3]=(ilba+slba & 0x00ff0000) >> 16;
61544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[4]=(ilba+slba & 0x0000ff00) >> 8;
61554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      atacmd[5]=(ilba+slba & 0x000000ff);
61564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if((status = ata_cmd_packet(device, 12, get_SS(), atacmd, before*512, nbsectors*512L, ATA_DATA_IN, segment,offset)) != 0) {
61574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_cdemu: function %02x, error %02x !\n",GET_AH(),status);
61584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x02);
61594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AL(0);
61604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        goto int13_fail_noah;
61614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
61624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
61644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
61654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x08: /* read disk drive parameters */
61674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vspt=read_word(ebda_seg,&EbdaData->cdemu.vdevice.spt);
61684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vcylinders=read_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders) - 1;
61694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      vheads=read_word(ebda_seg,&EbdaData->cdemu.vdevice.heads) - 1;
61704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL( 0x00 );
61724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_BL( 0x00 );
61734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CH( vcylinders & 0xff );
61744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CL((( vcylinders >> 2) & 0xc0) | ( vspt  & 0x3f ));
61754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DH( vheads );
61764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DL( 0x02 );   // FIXME ElTorito Various. should send the real count of drives 1 or 2
61774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                        // FIXME ElTorito Harddisk. should send the HD count
61784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
61804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x01: SET_BL( 0x02 ); break;
61814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x02: SET_BL( 0x04 ); break;
61824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0x03: SET_BL( 0x06 ); break;
61834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
61844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61854d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
61864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push bp
61874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bp, sp
61884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ax, #diskette_param_table2
61894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov _int13_cdemu.DI+2[bp], ax
61904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov _int13_cdemu.ES+2[bp], cs
61914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  bp
61924d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
61934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success;
61944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
61954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
61964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x15: /* read disk drive size */
61974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME ElTorito Harddisk. What geometry to send ?
61984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x03);
61994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_success_noah;
62004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
62014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // all those functions return unimplemented
62034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0a: /* read disk sectors with ECC */
62044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0b: /* write disk sectors with ECC */
62054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x18: /* set media type for format */
62064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x41: // IBM/MS installation check
62074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // FIXME ElTorito Harddisk. Darwin would like to use EDD
62084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x42: // IBM/MS extended read
62094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x43: // IBM/MS extended write
62104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x44: // IBM/MS verify sectors
62114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x45: // IBM/MS lock/unlock drive
62124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x46: // IBM/MS eject media
62134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x47: // IBM/MS extended seek
62144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x48: // IBM/MS get drive parameters
62154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x49: // IBM/MS extended media change
62164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x4e: // ? - set hardware configuration
62174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x50: // ? - send packet command
62184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
62194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13_cdemu function AH=%02x unsupported, returns fail\n", GET_AH());
62204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      goto int13_fail;
62214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
62224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
62234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail:
62254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
62264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail_noah:
62274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(GET_AH());
62284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_fail_nostatus:
62294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_CF();     // error occurred
62304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
62314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success:
62334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x00); // no error
62344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_success_noah:
62354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(0x00);
62364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    CLEAR_CF();   // no error
62374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
62384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
62394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
62414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// End of int13 when emulating a device from the cd
62424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// ---------------------------------------------------------------------------
62434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
62454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else //BX_USE_ATADRV
62474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
62494d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaoutLBA(cylinder,hd_heads,head,hd_sectors,sector,dl)
62504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u cylinder;
62514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u hd_heads;
62524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u head;
62534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u hd_sectors;
62544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u sector;
62554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u dl;
62564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
62574d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
62584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push   bp
62594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    bp, sp
62604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push   eax
62614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push   ebx
62624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push   edx
62634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        xor    eax,eax
62644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    ax,4[bp]  // cylinder
62654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        xor    ebx,ebx
62664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    bl,6[bp]  // hd_heads
62674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        imul   ebx
62684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    bl,8[bp]  // head
62704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        add    eax,ebx
62714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    bl,10[bp] // hd_sectors
62724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        imul   ebx
62734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    bl,12[bp] // sector
62744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        add    eax,ebx
62754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
62764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        dec    eax
62774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    dx,#0x1f3
62784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        out    dx,al
62794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    dx,#0x1f4
62804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    al,ah
62814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        out    dx,al
62824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        shr    eax,#16
62834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    dx,#0x1f5
62844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        out    dx,al
62854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        and    ah,#0xf
62864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    bl,14[bp] // dl
62874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        and    bl,#1
62884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        shl    bl,#4
62894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        or     ah,bl
62904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        or     ah,#0xe0
62914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    al,ah
62924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov    dx,#0x01f6
62934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        out    dx,al
62944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop    edx
62954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop    ebx
62964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop    eax
62974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop    bp
62984d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
62994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
63004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
63024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_harddisk(EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
63034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
63044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
63054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u    drive, num_sectors, sector, head, status, mod;
63064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u    drive_map;
63074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u    n_drives;
63084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   cyl_mod, ax;
63094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   max_cylinder, cylinder, total_sectors;
63104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   hd_cylinders;
63114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u    hd_heads, hd_sectors;
63124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   val16;
63134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u    sector_count;
63144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  unsigned int i;
63154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   tempbx;
63164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   dpsize;
63174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   count, segment, offset;
63194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit32u   lba;
63204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u   error;
63214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_HD("int13 harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
63234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x008e, 0);  // clear completion flag
63254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* at this point, DL is >= 0x80 to be passed from the floppy int13h
63274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     handler code */
63284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* check how many disks first (cmos reg 0x12), return an error if
63294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     drive not present */
63304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  drive_map = inb_cmos(0x12);
63314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  drive_map = (((drive_map & 0xf0)==0) ? 0 : 1) |
63324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima              (((drive_map & 0x0f)==0) ? 0 : 2);
63334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  n_drives = (drive_map==0) ? 0 :
63344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ((drive_map==3) ? 2 : 1);
63354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (!(drive_map & (1<<(GET_ELDL()&0x7f)))) { /* allow 0, 1, or 2 disks */
63374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_AH(0x01);
63384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_DISK_RET_STATUS(0x01);
63394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SET_CF(); /* error occurred */
63404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
63414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
63424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (GET_AH()) {
63444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x00: /* disk controller reset */
63464d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f00\n");
63474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
63494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
63504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_ret_status(0);
63514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_current_cyl(0, 0); /* current cylinder, diskette 1 */
63524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_current_cyl(1, 0); /* current cylinder, diskette 2 */
63534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
63544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
63554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
63564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: /* read disk status */
63584d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f01\n");
63594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = read_byte(0x0040, 0x0074);
63604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(status);
63614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
63624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* set CF if error status read */
63634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status) SET_CF();
63644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else        CLEAR_CF();
63654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
63664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
63674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x04: // verify disk sectors
63694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02: // read disk sectors
63704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL();
63714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors);
63724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      num_sectors = GET_AL();
63744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinder    = (GET_CL() & 0x00c0) << 2 | GET_CH();
63754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector      = (GET_CL() & 0x3f);
63764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      head        = GET_DH();
63774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (hd_cylinders > 1024) {
63804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (hd_cylinders <= 2048) {
63814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 1;
63824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
63834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (hd_cylinders <= 4096) {
63844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 2;
63854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
63864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (hd_cylinders <= 8192) {
63874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 3;
63884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
63894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else { // hd_cylinders <= 16384
63904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 4;
63914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
63924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ax = head / hd_heads;
63944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cyl_mod = ax & 0xff;
63954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        head    = ax >> 8;
63964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cylinder |= cyl_mod;
63974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
63984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
63994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (cylinder >= hd_cylinders) ||
64004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           (sector > hd_sectors) ||
64014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           (head >= hd_heads) ) {
64024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(1);
64034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_DISK_RET_STATUS(1);
64044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); /* error occurred */
64054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
64064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
64074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (num_sectors > 128) || (num_sectors == 0) )
64094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("int13_harddisk: num_sectors out of range!\n");
64104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (head > 15)
64124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(read/verify) head > 15\n");
64134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( GET_AH() == 0x04 ) {
64154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0);
64164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_DISK_RET_STATUS(0);
64174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CLEAR_CF();
64184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
64194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
64204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = inb(0x1f7);
64224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status & 0x80) {
64234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(read/verify) BUSY bit set\n");
64244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
64254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x01f2, num_sectors);
64264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* activate LBA? (tomv) */
64274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (hd_heads > 16) {
64284d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("CHS: %x %x %x\n", cylinder, head, sector);
64294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outLBA(cylinder,hd_heads,head,hd_sectors,sector,drive);
64304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
64314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
64324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f3, sector);
64334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f4, cylinder & 0x00ff);
64344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f5, cylinder >> 8);
64354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f6, 0xa0 | ((drive & 0x01)<<4) | (head & 0x0f));
64364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
64374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x01f7, 0x20);
64384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (1) {
64404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status = inb(0x1f7);
64414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( !(status & 0x80) ) break;
64424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
64434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status & 0x01) {
64454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(read/verify) read error\n");
64464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if ( !(status & 0x08) ) {
64474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
64484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(read/verify) expected DRQ=1\n");
64494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
64504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector_count = 0;
64524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      tempbx = BX;
64534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64544d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
64554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti  ;; enable higher priority interrupts
64564d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
64574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (1) {
64594d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
64604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; store temp bx in real DI register
64614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
64624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
64634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  di, _int13_harddisk.tempbx + 2 [bp]
64644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
64654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; adjust if there will be an overrun
64674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp   di, #0xfe00
64684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jbe   i13_f02_no_adjust
64694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimai13_f02_adjust:
64704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sub   di, #0x0200 ; sub 512 bytes from offset
64714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   ax, es
64724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        add   ax, #0x0020 ; add 512 to segment
64734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   es, ax
64744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimai13_f02_no_adjust:
64764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, #0x0100   ;; counter (256 words = 512b)
64774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  dx, #0x01f0  ;; AT data read port
64784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
64804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          insw ;; CX words transfered from port(DX) to ES:[DI]
64814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimai13_f02_done:
64834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; store real DI register back to temp bx
64844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
64854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
64864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  _int13_harddisk.tempbx + 2 [bp], di
64874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
64884d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
64894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
64904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sector_count++;
64914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        num_sectors--;
64924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (num_sectors == 0) {
64934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          status = inb(0x1f7);
64944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if ( (status & 0xc9) != 0x40 )
64954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            BX_PANIC("no sectors left to read/verify, status is %02x\n", (unsigned) status);
64964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
64974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
64984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else {
64994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          status = inb(0x1f7);
65004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if ( (status & 0xc9) != 0x48 )
65014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            BX_PANIC("more sectors left to read/verify, status is %02x\n", (unsigned) status);
65024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          continue;
65034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
65044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
65074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
65084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(sector_count);
65094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
65104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
65114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
65124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x03: /* write disk sectors */
65154d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f03\n");
65164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL ();
65174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors);
65184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      num_sectors = GET_AL();
65204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinder    = GET_CH();
65214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cylinder    |= ( ((Bit16u) GET_CL()) << 2) & 0x300;
65224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector      = (GET_CL() & 0x3f);
65234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      head        = GET_DH();
65244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (hd_cylinders > 1024) {
65264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (hd_cylinders <= 2048) {
65274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 1;
65284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
65294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (hd_cylinders <= 4096) {
65304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 2;
65314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
65324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else if (hd_cylinders <= 8192) {
65334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 3;
65344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
65354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else { // hd_cylinders <= 16384
65364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          cylinder <<= 4;
65374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
65384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ax = head / hd_heads;
65404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cyl_mod = ax & 0xff;
65414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        head    = ax >> 8;
65424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cylinder |= cyl_mod;
65434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (cylinder >= hd_cylinders) ||
65464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           (sector > hd_sectors) ||
65474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima           (head >= hd_heads) ) {
65484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH( 1);
65494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_DISK_RET_STATUS(1);
65504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); /* error occurred */
65514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
65524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (num_sectors > 128) || (num_sectors == 0) )
65554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("int13_harddisk: num_sectors out of range!\n");
65564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (head > 15)
65584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(read) head > 15\n");
65594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = inb(0x1f7);
65614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (status & 0x80) {
65624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(read) BUSY bit set\n");
65634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// should check for Drive Ready Bit also in status reg
65654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x01f2, num_sectors);
65664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* activate LBA? (tomv) */
65684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (hd_heads > 16) {
65694d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("CHS (write): %x %x %x\n", cylinder, head, sector);
65704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outLBA(cylinder,hd_heads,head,hd_sectors,sector,GET_ELDL());
65714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
65734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f3, sector);
65744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f4, cylinder & 0x00ff);
65754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f5, cylinder >> 8);
65764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x01f6, 0xa0 | ((GET_ELDL() & 0x01)<<4) | (head & 0x0f));
65774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x01f7, 0x30);
65794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // wait for busy bit to turn off after seeking
65814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (1) {
65824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        status = inb(0x1f7);
65834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( !(status & 0x80) ) break;
65844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( !(status & 0x08) ) {
65874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
65884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("hard drive BIOS:(write) data-request bit not set\n");
65894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
65904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector_count = 0;
65924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      tempbx = BX;
65934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65944d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
65954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti  ;; enable higher priority interrupts
65964d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
65974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
65984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (1) {
65994d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
66004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; store temp bx in real SI register
66014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
66024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
66034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  si, _int13_harddisk.tempbx + 2 [bp]
66044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
66054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; adjust if there will be an overrun
66074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cmp   si, #0xfe00
66084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        jbe   i13_f03_no_adjust
66094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimai13_f03_adjust:
66104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sub   si, #0x0200 ; sub 512 bytes from offset
66114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   ax, es
66124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        add   ax, #0x0020 ; add 512 to segment
66134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov   es, ax
66144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimai13_f03_no_adjust:
66164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  cx, #0x0100   ;; counter (256 words = 512b)
66174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  dx, #0x01f0  ;; AT data read port
66184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        seg ES
66204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        rep
66214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outsw ;; CX words tranfered from ES:[SI] to port(DX)
66224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ;; store real SI register back to temp bx
66244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        push bp
66254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  bp, sp
66264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mov  _int13_harddisk.tempbx + 2 [bp], si
66274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        pop  bp
66284d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
66294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sector_count++;
66314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        num_sectors--;
66324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (num_sectors == 0) {
66334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          status = inb(0x1f7);
66344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if ( (status & 0xe9) != 0x40 )
66354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            BX_PANIC("no sectors left to write, status is %02x\n", (unsigned) status);
66364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
66374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
66384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        else {
66394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          status = inb(0x1f7);
66404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if ( (status & 0xc9) != 0x48 )
66414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            BX_PANIC("more sectors left to write, status is %02x\n", (unsigned) status);
66424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          continue;
66434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
66444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
66454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
66474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
66484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(sector_count);
66494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
66504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
66514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
66524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x05: /* format disk track */
66544d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f05\n");
66554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_PANIC("format disk track called\n");
66564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* nop */
66574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
66584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
66594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
66604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
66614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
66624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x08: /* read disk drive parameters */
66644d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f08\n");
66654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL ();
66674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors);
66684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // translate CHS
66704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
66714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (hd_cylinders <= 1024) {
66724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // hd_cylinders >>= 0;
66734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // hd_heads <<= 0;
66744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
66754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else if (hd_cylinders <= 2048) {
66764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_cylinders >>= 1;
66774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_heads <<= 1;
66784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
66794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else if (hd_cylinders <= 4096) {
66804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_cylinders >>= 2;
66814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_heads <<= 2;
66824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
66834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else if (hd_cylinders <= 8192) {
66844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_cylinders >>= 3;
66854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_heads <<= 3;
66864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
66874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else { // hd_cylinders <= 16384
66884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_cylinders >>= 4;
66894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        hd_heads <<= 4;
66904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
66914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
66924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      max_cylinder = hd_cylinders - 2; /* 0 based */
66934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(0);
66944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CH(max_cylinder & 0xff);
66954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CL(((max_cylinder >> 2) & 0xc0) | (hd_sectors & 0x3f));
66964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DH(hd_heads - 1);
66974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DL(n_drives); /* returns 0, 1, or 2 hard drives */
66984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
66994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
67004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
67014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x09: /* initialize drive parameters */
67064d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f09\n");
67074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
67084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
67094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
67104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0a: /* read disk sectors with ECC */
67144d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f0a\n");
67154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0b: /* write disk sectors with ECC */
67164d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f0b\n");
67174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_PANIC("int13h Functions 0Ah & 0Bh not implemented!\n");
67184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0c: /* seek to specified cylinder */
67224d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f0c\n");
67234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13h function 0ch (seek) not implemented!\n");
67244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
67254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
67264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
67274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x0d: /* alternate disk reset */
67314d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f0d\n");
67324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
67334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
67344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
67354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x10: /* check drive ready */
67394d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f10\n");
67404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //SET_AH(0);
67414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //SET_DISK_RET_STATUS(0);
67424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //CLEAR_CF(); /* successful */
67434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //return;
67444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //break;
67454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // should look at 40:8E also???
67474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      status = inb(0x01f7);
67484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (status & 0xc0) == 0x40 ) {
67494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0);
67504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_DISK_RET_STATUS(0);
67514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CLEAR_CF(); // drive ready
67524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
67534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
67544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
67554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0xAA);
67564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_DISK_RET_STATUS(0xAA);
67574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); // not ready
67584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
67594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
67604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x11: /* recalibrate */
67634d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f11\n");
67644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
67654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
67664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
67674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x14: /* controller internal diagnostic */
67714d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_HD("int13_f14\n");
67724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
67734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0);
67744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); /* successful */
67754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(0);
67764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
67774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
67784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
67794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x15: /* read disk drive size */
67804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL();
67814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors);
67824d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
67834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push bp
67844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bp, sp
67854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  al, _int13_harddisk.hd_heads + 2 [bp]
67864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  ah, _int13_harddisk.hd_sectors + 2 [bp]
67874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mul  al, ah ;; ax = heads * sectors
67884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bx, _int13_harddisk.hd_cylinders + 2 [bp]
67894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      dec  bx     ;; use (cylinders - 1) ???
67904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mul  ax, bx ;; dx:ax = (cylinders -1) * (heads * sectors)
67914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; now we need to move the 32bit result dx:ax to what the
67924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; BIOS wants which is cx:dx.
67934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ;; and then into CX:DX on the stack
67944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  _int13_harddisk.CX + 2 [bp], dx
67954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  _int13_harddisk.DX + 2 [bp], ax
67964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  bp
67974d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
67984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(3);  // hard disk accessible
67994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(0); // ??? should this be 0
68004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); // successful
68014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
68024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
68034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x18: // set media type for format
68054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x41: // IBM/MS
68064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x42: // IBM/MS
68074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x43: // IBM/MS
68084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x44: // IBM/MS
68094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x45: // IBM/MS lock/unlock drive
68104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x46: // IBM/MS eject media
68114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x47: // IBM/MS extended seek
68124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x49: // IBM/MS extended media change
68134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x50: // IBM/MS send packet command
68144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
68154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO("int13_harddisk: unsupported AH=%02x\n", GET_AH());
68164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(1);  // code=invalid function in AH or invalid parameter
68184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DISK_RET_STATUS(1);
68194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF(); /* unsuccessful */
68204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
68214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
68224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
68234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
68244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char panic_msg_reg12h[] = "HD%d cmos reg 12h not type F\n";
68264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic char panic_msg_reg19h[] = "HD%d cmos reg %02xh not user definable type 47\n";
68274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
68294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaget_hd_geometry(drive, hd_cylinders, hd_heads, hd_sectors)
68304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u drive;
68314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u *hd_cylinders;
68324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  *hd_heads;
68334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  *hd_sectors;
68344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
68354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u hd_type;
68364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ss;
68374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u cylinders;
68384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u iobase;
68394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ss = get_SS();
68414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive == 0x80) {
68424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hd_type = inb_cmos(0x12) & 0xf0;
68434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (hd_type != 0xf0)
68444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO(panic_msg_reg12h,0);
68454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hd_type = inb_cmos(0x19); // HD0: extended type
68464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (hd_type != 47)
68474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO(panic_msg_reg19h,0,0x19);
68484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    iobase = 0x1b;
68494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } else {
68504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hd_type = inb_cmos(0x12) & 0x0f;
68514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (hd_type != 0x0f)
68524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO(panic_msg_reg12h,1);
68534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hd_type = inb_cmos(0x1a); // HD1: extended type
68544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (hd_type != 47)
68554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BX_INFO(panic_msg_reg19h,0,0x1a);
68564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    iobase = 0x24;
68574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
68584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // cylinders
68604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cylinders = inb_cmos(iobase) | (inb_cmos(iobase+1) << 8);
68614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_word(ss, hd_cylinders, cylinders);
68624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // heads
68644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ss, hd_heads, inb_cmos(iobase+2));
68654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // sectors per track
68674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(ss, hd_sectors, inb_cmos(iobase+8));
68684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
68694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif //else BX_USE_ATADRV
68714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_SUPPORT_FLOPPY
68734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//////////////////////
68754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// FLOPPY functions //
68764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima//////////////////////
68774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid floppy_reset_controller()
68794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
68804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u val8;
68814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Reset controller
68834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = inb(0x03f2);
68844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x03f2, val8 & ~0x04);
68854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x03f2, val8 | 0x04);
68864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Wait for controller to come out of reset
68884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  do {
68894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 = inb(0x3f4);
68904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } while ( (val8 & 0xc0) != 0x80 );
68914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
68924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid floppy_prepare_controller(drive)
68944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u drive;
68954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
68964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  val8, dor, prev_reset;
68974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
68984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // set 40:3e bit 7 to 0
68994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = read_byte(0x0040, 0x003e);
69004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 &= 0x7f;
69014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x003e, val8);
69024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // turn on motor of selected drive, DMA & int enabled, normal operation
69044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  prev_reset = inb(0x03f2) & 0x04;
69054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive)
69064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    dor = 0x20;
69074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
69084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    dor = 0x10;
69094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dor |= 0x0c;
69104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dor |= drive;
69114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x03f2, dor);
69124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // reset the disk motor timeout value of INT 08
69144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x40,0x40, BX_FLOPPY_ON_CNT);
69154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // wait for drive readiness
69174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  do {
69184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 = inb(0x3f4);
69194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } while ( (val8 & 0xc0) != 0x80 );
69204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (prev_reset == 0) {
69224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // turn on interrupts
69234d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
69244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sti
69254d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
69264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // wait on 40:3e bit 7 to become 1
69274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    do {
69284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = read_byte(0x0040, 0x003e);
69294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } while ( (val8 & 0x80) == 0 );
69304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 &= 0x7f;
69314d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
69324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cli
69334d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
69344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_byte(0x0040, 0x003e, val8);
69354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
69364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
69374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool
69394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloppy_media_known(drive)
69404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u drive;
69414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
69424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  val8;
69434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u media_state_offset;
69444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = read_byte(0x0040, 0x003e); // diskette recal status
69464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive)
69474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 >>= 1;
69484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 &= 0x01;
69494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (val8 == 0)
69504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(0);
69514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  media_state_offset = 0x0090;
69534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive)
69544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state_offset += 1;
69554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = read_byte(0x0040, media_state_offset);
69574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = (val8 >> 4) & 0x01;
69584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (val8 == 0)
69594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(0);
69604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // check pass, return KNOWN
69624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(1);
69634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
69644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool
69664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloppy_media_sense(drive)
69674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u drive;
69684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
69694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool retval;
69704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u  media_state_offset;
69714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u   drive_type, config_data, media_state;
69724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (floppy_drive_recal(drive) == 0) {
69744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(0);
69754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
69764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // for now cheat and get drive type from CMOS,
69784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // assume media is same as drive type
69794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // ** config_data **
69814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Bitfields for diskette media control:
69824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Bit(s)  Description (Table M0028)
69834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  7-6  last data rate set by controller
69844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //        00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps
69854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  5-4  last diskette drive step rate selected
69864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //        00=0Ch, 01=0Dh, 10=0Eh, 11=0Ah
69874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  3-2  {data rate at start of operation}
69884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  1-0  reserved
69894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
69904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // ** media_state **
69914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Bitfields for diskette drive media state:
69924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Bit(s)  Description (Table M0030)
69934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  7-6  data rate
69944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps
69954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  5  double stepping required (e.g. 360kB in 1.2MB)
69964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  4  media type established
69974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  3  drive capable of supporting 4MB media
69984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //  2-0  on exit from BIOS, contains
69994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    000 trying 360kB in 360kB
70004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    001 trying 360kB in 1.2MB
70014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    010 trying 1.2MB in 1.2MB
70024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    011 360kB in 360kB established
70034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    100 360kB in 1.2MB established
70044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    101 1.2MB in 1.2MB established
70054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    110 reserved
70064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //    111 all other formats/drives
70074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  drive_type = inb_cmos(0x10);
70094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive == 0)
70104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    drive_type >>= 4;
70114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
70124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    drive_type &= 0x0f;
70134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( drive_type == 1 ) {
70144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 360K 5.25" drive
70154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x25; // 0010 0101
70174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 2 ) {
70204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 1.2 MB 5.25" drive
70214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x25; // 0010 0101   // need double stepping??? (bit 5)
70234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 3 ) {
70264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 720K 3.5" drive
70274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000 ???
70284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x17; // 0001 0111
70294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 4 ) {
70324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 1.44 MB 3.5" drive
70334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x17; // 0001 0111
70354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 5 ) {
70384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 2.88 MB 3.5" drive
70394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0xCC; // 1100 1100
70404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0xD7; // 1101 0111
70414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //
70444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Extended floppy size uses special cmos setting
70454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 6 ) {
70464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 160k 5.25" drive
70474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x27; // 0010 0111
70494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 7 ) {
70524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 180k 5.25" drive
70534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x27; // 0010 0111
70554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else if ( drive_type == 8 ) {
70584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // 320k 5.25" drive
70594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x27; // 0010 0111
70614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 1;
70624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
70654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // not recognized
70664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    config_data = 0x00; // 0000 0000
70674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state = 0x00; // 0000 0000
70684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    retval = 0;
70694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
70704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive == 0)
70724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state_offset = 0x90;
70734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
70744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    media_state_offset = 0x91;
70754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x008B, config_data);
70764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, media_state_offset, media_state);
70774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(retval);
70794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
70804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool
70824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloppy_drive_recal(drive)
70834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u drive;
70844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
70854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  val8;
70864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u curr_cyl_offset;
70874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  floppy_prepare_controller(drive);
70894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // send Recalibrate command (2 bytes) to controller
70914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x03f5, 0x07);  // 07: Recalibrate
70924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x03f5, drive); // 0=drive0, 1=drive1
70934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // turn on interrupts
70954d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
70964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
70974d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
70984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
70994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // wait on 40:3e bit 7 to become 1
71004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  do {
71014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 = (read_byte(0x0040, 0x003e) & 0x80);
71024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } while ( val8 == 0 );
71034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = 0; // separate asm from while() loop
71054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // turn off interrupts
71064d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
71074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
71084d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
71094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // set 40:3e bit 7 to 0, and calibrated bit
71114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = read_byte(0x0040, 0x003e);
71124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 &= 0x7f;
71134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive) {
71144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 |= 0x02; // Drive 1 calibrated
71154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    curr_cyl_offset = 0x0095;
71164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } else {
71174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 |= 0x01; // Drive 0 calibrated
71184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    curr_cyl_offset = 0x0094;
71194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
71204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x003e, val8);
71214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, curr_cyl_offset, 0); // current cylinder is 0
71224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(1);
71244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
71254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bx_bool
71294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloppy_drive_exists(drive)
71304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u drive;
71314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
71324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  drive_type;
71334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // check CMOS to see if drive exists
71354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  drive_type = inb_cmos(0x10);
71364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive == 0)
71374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    drive_type >>= 4;
71384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
71394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    drive_type &= 0x0f;
71404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( drive_type == 0 )
71414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(0);
71424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
71434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return(1);
71444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
71454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
71474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
71484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
71494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
71504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  drive, num_sectors, track, sector, head, status;
71514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u base_address, base_count, base_es;
71524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  page, mode_register, val8, dor;
71534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  return_status[7];
71544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  drive_type, num_floppies, ah;
71554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u es, last_addr;
71564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_FL("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
71584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ah = GET_AH();
71604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch ( ah ) {
71624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x00: // diskette controller reset
71634d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f00\n");
71644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL();
71654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive > 1) {
71664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(1); // invalid param
71674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(1);
71684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
71694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
71704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
71714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive_type = inb_cmos(0x10);
71724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive == 0)
71744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        drive_type >>= 4;
71754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else
71764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        drive_type &= 0x0f;
71774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive_type == 0) {
71784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x80); // drive not responding
71794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(0x80);
71804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
71814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
71824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
71834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
71844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_ret_status(0);
71854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); // successful
71864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_current_cyl(drive, 0); // current cylinder
71874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
71884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: // Read Diskette Status
71904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
71914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = read_byte(0x0000, 0x0441);
71924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(val8);
71934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (val8) {
71944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
71954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
71964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
71974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
71984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x02: // Read Diskette Sectors
71994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x03: // Write Diskette Sectors
72004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x04: // Verify Diskette Sectors
72014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      num_sectors = GET_AL();
72024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      track       = GET_CH();
72034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sector      = GET_CL();
72044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      head        = GET_DH();
72054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive       = GET_ELDL();
72064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((drive > 1) || (head > 1) || (sector == 0) ||
72084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          (num_sectors == 0) || (num_sectors > 72)) {
72094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
72104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(1);
72114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(1);
72124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AL(0); // no sectors read
72134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); // error occurred
72144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
72154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
72164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // see if drive exists
72184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (floppy_drive_exists(drive) == 0) {
72194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x80); // not responding
72204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(0x80);
72214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AL(0); // no sectors read
72224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); // error occurred
72234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
72244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
72254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // see if media in drive, and type is known
72274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (floppy_media_known(drive) == 0) {
72284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (floppy_media_sense(drive) == 0) {
72294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AH(0x0C); // Media type not found
72304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_diskette_ret_status(0x0C);
72314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(0); // no sectors read
72324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF(); // error occurred
72334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
72344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
72354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
72364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (ah == 0x02) {
72384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Read Diskette Sectors
72394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //-----------------------------------
72414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set up DMA controller for transfer
72424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //-----------------------------------
72434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // es:bx = pointer to where to place information from diskette
72454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 04: DMA-1 base and current address, channel 2
72464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 05: DMA-1 base and current count, channel 2
72474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        page = (ES >> 12);   // upper 4 bits
72484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base_es = (ES << 4); // lower 16bits contributed by ES
72494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base_address = base_es + BX; // lower 16 bits of address
72504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                     // contributed by ES:BX
72514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( base_address < base_es ) {
72524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // in case of carry, adjust page by 1
72534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          page++;
72544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
72554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base_count = (num_sectors * 512) - 1;
72564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // check for 64K boundary overrun
72584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        last_addr = base_address + base_count;
72594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (last_addr < base_address) {
72604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AH(0x09);
72614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_diskette_ret_status(0x09);
72624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(0); // no sectors read
72634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF(); // error occurred
72644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
72654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
72664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT13_FL("masking DMA-1 c2\n");
72684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000a, 0x06);
72694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_FL("clear flip-flop\n");
72714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000c, 0x00); // clear flip-flop
72724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0004, base_address);
72734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0004, base_address>>8);
72744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_FL("clear flip-flop\n");
72754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000c, 0x00); // clear flip-flop
72764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0005, base_count);
72774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0005, base_count>>8);
72784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 0b: DMA-1 Mode Register
72804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mode_register = 0x46; // single mode, increment, autoinit disable,
72814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                              // transfer type=write, channel 2
72824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_FL("setting mode register\n");
72834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000b, mode_register);
72844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_FL("setting page register\n");
72864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 81: DMA-1 Page Register, channel 2
72874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0081, page);
72884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT13_FL("unmask chan 2\n");
72904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000a, 0x02); // unmask channel 2
72914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT13_FL("unmasking DMA-1 c2\n");
72934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000a, 0x02);
72944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
72954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //--------------------------------------
72964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set up floppy controller for transfer
72974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //--------------------------------------
72984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        floppy_prepare_controller(drive);
72994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // send read-normal-data command (9 bytes) to controller
73014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 0xe6); // e6: read normal data
73024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, (head << 2) | drive); // HD DR1 DR2
73034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, track);
73044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, head);
73054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, sector);
73064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 2); // 512 byte sector size
73074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, sector + num_sectors - 1); // last sector to read on track
73084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 0); // Gap length
73094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 0xff); // Gap length
73104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // turn on interrupts
73124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
73134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sti
73144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
73154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // wait on 40:3e bit 7 to become 1
73174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        do {
73184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val8 = read_byte(0x0040, 0x0040);
73194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (val8 == 0) {
73204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            floppy_reset_controller();
73214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AH(0x80); // drive not ready (timeout)
73224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            set_diskette_ret_status(0x80);
73234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AL(0); // no sectors read
73244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_CF(); // error occurred
73254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            return;
73264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
73274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val8 = (read_byte(0x0040, 0x003e) & 0x80);
73284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } while ( val8 == 0 );
73294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = 0; // separate asm from while() loop
73314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // turn off interrupts
73324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
73334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cli
73344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
73354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set 40:3e bit 7 to 0
73374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = read_byte(0x0040, 0x003e);
73384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 &= 0x7f;
73394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x003e, val8);
73404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // check port 3f4 for accessibility to status bytes
73424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = inb(0x3f4);
73434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( (val8 & 0xc0) != 0xc0 )
73444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_PANIC("int13_diskette: ctrl not ready\n");
73454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // read 7 return status bytes from controller
73474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // using loop index broken, have to unroll...
73484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[0] = inb(0x3f5);
73494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[1] = inb(0x3f5);
73504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[2] = inb(0x3f5);
73514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[3] = inb(0x3f5);
73524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[4] = inb(0x3f5);
73534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[5] = inb(0x3f5);
73544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[6] = inb(0x3f5);
73554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // record in BIOS Data Area
73564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0042, return_status[0]);
73574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0043, return_status[1]);
73584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0044, return_status[2]);
73594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0045, return_status[3]);
73604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0046, return_status[4]);
73614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0047, return_status[5]);
73624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0048, return_status[6]);
73634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( (return_status[0] & 0xc0) != 0 ) {
73654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AH(0x20);
73664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_diskette_ret_status(0x20);
73674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(0); // no sectors read
73684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF(); // error occurred
73694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
73704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
73714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // ??? should track be new val from return_status[3] ?
73734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_current_cyl(drive, track);
73744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // AL = number of sectors read (same value as passed)
73754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x00); // success
73764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CLEAR_CF();   // success
73774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
73784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (ah == 0x03) {
73794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Write Diskette Sectors
73804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //-----------------------------------
73824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set up DMA controller for transfer
73834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //-----------------------------------
73844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // es:bx = pointer to where to place information from diskette
73864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 04: DMA-1 base and current address, channel 2
73874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 05: DMA-1 base and current count, channel 2
73884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        page = (ES >> 12);   // upper 4 bits
73894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base_es = (ES << 4); // lower 16bits contributed by ES
73904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base_address = base_es + BX; // lower 16 bits of address
73914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                     // contributed by ES:BX
73924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( base_address < base_es ) {
73934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // in case of carry, adjust page by 1
73944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          page++;
73954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
73964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        base_count = (num_sectors * 512) - 1;
73974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
73984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // check for 64K boundary overrun
73994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        last_addr = base_address + base_count;
74004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (last_addr < base_address) {
74014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AH(0x09);
74024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_diskette_ret_status(0x09);
74034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(0); // no sectors read
74044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF(); // error occurred
74054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
74064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
74074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT13_FL("masking DMA-1 c2\n");
74094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000a, 0x06);
74104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000c, 0x00); // clear flip-flop
74124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0004, base_address);
74134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0004, base_address>>8);
74144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000c, 0x00); // clear flip-flop
74154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0005, base_count);
74164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0005, base_count>>8);
74174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 0b: DMA-1 Mode Register
74194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        mode_register = 0x4a; // single mode, increment, autoinit disable,
74204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                              // transfer type=read, channel 2
74214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000b, mode_register);
74224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // port 81: DMA-1 Page Register, channel 2
74244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x0081, page);
74254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_DEBUG_INT13_FL("unmasking DMA-1 c2\n");
74274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x000a, 0x02);
74284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //--------------------------------------
74304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set up floppy controller for transfer
74314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        //--------------------------------------
74324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        floppy_prepare_controller(drive);
74334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // send write-normal-data command (9 bytes) to controller
74354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 0xc5); // c5: write normal data
74364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, (head << 2) | drive); // HD DR1 DR2
74374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, track);
74384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, head);
74394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, sector);
74404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 2); // 512 byte sector size
74414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, sector + num_sectors - 1); // last sector to write on track
74424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 0); // Gap length
74434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        outb(0x03f5, 0xff); // Gap length
74444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // turn on interrupts
74464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
74474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        sti
74484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
74494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // wait on 40:3e bit 7 to become 1
74514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        do {
74524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val8 = read_byte(0x0040, 0x0040);
74534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if (val8 == 0) {
74544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            floppy_reset_controller();
74554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AH(0x80); // drive not ready (timeout)
74564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            set_diskette_ret_status(0x80);
74574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_AL(0); // no sectors written
74584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_CF(); // error occurred
74594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            return;
74604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
74614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          val8 = (read_byte(0x0040, 0x003e) & 0x80);
74624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } while ( val8 == 0 );
74634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = 0; // separate asm from while() loop
74654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // turn off interrupts
74664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
74674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cli
74684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
74694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set 40:3e bit 7 to 0
74714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = read_byte(0x0040, 0x003e);
74724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 &= 0x7f;
74734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x003e, val8);
74744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // check port 3f4 for accessibility to status bytes
74764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = inb(0x3f4);
74774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( (val8 & 0xc0) != 0xc0 )
74784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_PANIC("int13_diskette: ctrl not ready\n");
74794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // read 7 return status bytes from controller
74814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // using loop index broken, have to unroll...
74824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[0] = inb(0x3f5);
74834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[1] = inb(0x3f5);
74844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[2] = inb(0x3f5);
74854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[3] = inb(0x3f5);
74864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[4] = inb(0x3f5);
74874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[5] = inb(0x3f5);
74884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return_status[6] = inb(0x3f5);
74894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // record in BIOS Data Area
74904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0042, return_status[0]);
74914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0043, return_status[1]);
74924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0044, return_status[2]);
74934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0045, return_status[3]);
74944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0046, return_status[4]);
74954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0047, return_status[5]);
74964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        write_byte(0x0040, 0x0048, return_status[6]);
74974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
74984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( (return_status[0] & 0xc0) != 0 ) {
74994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          if ( (return_status[1] & 0x02) != 0 ) {
75004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // diskette not writable.
75014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // AH=status code=0x03 (tried to write on write-protected disk)
75024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            // AL=number of sectors written=0
75034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            AX = 0x0300;
75044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            SET_CF();
75054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            return;
75064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          } else {
75074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima            BX_PANIC("int13_diskette_function: read error\n");
75084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          }
75094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
75104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // ??? should track be new val from return_status[3] ?
75124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_current_cyl(drive, track);
75134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // AL = number of sectors read (same value as passed)
75144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x00); // success
75154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CLEAR_CF();   // success
75164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
75174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else {  // if (ah == 0x04)
75184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Verify Diskette Sectors
75194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // ??? should track be new val from return_status[3] ?
75214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_current_cyl(drive, track);
75224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // AL = number of sectors verified (same value as passed)
75234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CLEAR_CF();   // success
75244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x00); // success
75254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
75264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
75274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
75284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x05: // format diskette track
75304d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f05\n");
75314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      num_sectors = GET_AL();
75334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      track       = GET_CH();
75344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      head        = GET_DH();
75354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive       = GET_ELDL();
75364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ((drive > 1) || (head > 1) || (track > 79) ||
75384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          (num_sectors == 0) || (num_sectors > 18)) {
75394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(1);
75404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(1);
75414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); // error occurred
75424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
75434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // see if drive exists
75454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (floppy_drive_exists(drive) == 0) {
75464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x80); // drive not responding
75474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(0x80);
75484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); // error occurred
75494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
75504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
75514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // see if media in drive, and type is known
75534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (floppy_media_known(drive) == 0) {
75544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (floppy_media_sense(drive) == 0) {
75554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AH(0x0C); // Media type not found
75564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_diskette_ret_status(0x0C);
75574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AL(0); // no sectors read
75584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF(); // error occurred
75594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
75604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
75614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
75624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // set up DMA controller for transfer
75644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      page = (ES >> 12);   // upper 4 bits
75654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base_es = (ES << 4); // lower 16bits contributed by ES
75664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base_address = base_es + BX; // lower 16 bits of address
75674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                                   // contributed by ES:BX
75684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( base_address < base_es ) {
75694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // in case of carry, adjust page by 1
75704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        page++;
75714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
75724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      base_count = (num_sectors * 4) - 1;
75734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // check for 64K boundary overrun
75754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      last_addr = base_address + base_count;
75764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (last_addr < base_address) {
75774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x09);
75784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(0x09);
75794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AL(0); // no sectors read
75804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF(); // error occurred
75814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
75824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
75834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x000a, 0x06);
75854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x000c, 0x00); // clear flip-flop
75864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x0004, base_address);
75874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x0004, base_address>>8);
75884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x000c, 0x00); // clear flip-flop
75894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x0005, base_count);
75904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x0005, base_count>>8);
75914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mode_register = 0x4a; // single mode, increment, autoinit disable,
75924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                            // transfer type=read, channel 2
75934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x000b, mode_register);
75944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // port 81: DMA-1 Page Register, channel 2
75954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x0081, page);
75964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x000a, 0x02);
75974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
75984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // set up floppy controller for transfer
75994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      floppy_prepare_controller(drive);
76004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // send format-track command (6 bytes) to controller
76024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x03f5, 0x4d); // 4d: format track
76034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x03f5, (head << 2) | drive); // HD DR1 DR2
76044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x03f5, 2); // 512 byte sector size
76054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x03f5, num_sectors); // number of sectors per track
76064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x03f5, 0); // Gap length
76074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0x03f5, 0xf6); // Fill byte
76084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // turn on interrupts
76094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
76104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sti
76114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
76124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // wait on 40:3e bit 7 to become 1
76144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      do {
76154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = read_byte(0x0040, 0x0040);
76164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (val8 == 0) {
76174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          floppy_reset_controller();
76184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_AH(0x80); // drive not ready (timeout)
76194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          set_diskette_ret_status(0x80);
76204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF(); // error occurred
76214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
76224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
76234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        val8 = (read_byte(0x0040, 0x003e) & 0x80);
76244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } while ( val8 == 0 );
76254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = 0; // separate asm from while() loop
76274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // turn off interrupts
76284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
76294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cli
76304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
76314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // set 40:3e bit 7 to 0
76324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = read_byte(0x0040, 0x003e);
76334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 &= 0x7f;
76344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x003e, val8);
76354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // check port 3f4 for accessibility to status bytes
76364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = inb(0x3f4);
76374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (val8 & 0xc0) != 0xc0 )
76384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_PANIC("int13_diskette: ctrl not ready\n");
76394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // read 7 return status bytes from controller
76414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // using loop index broken, have to unroll...
76424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[0] = inb(0x3f5);
76434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[1] = inb(0x3f5);
76444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[2] = inb(0x3f5);
76454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[3] = inb(0x3f5);
76464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[4] = inb(0x3f5);
76474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[5] = inb(0x3f5);
76484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return_status[6] = inb(0x3f5);
76494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // record in BIOS Data Area
76504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0042, return_status[0]);
76514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0043, return_status[1]);
76524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0044, return_status[2]);
76534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0045, return_status[3]);
76544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0046, return_status[4]);
76554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0047, return_status[5]);
76564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0040, 0x0048, return_status[6]);
76574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if ( (return_status[0] & 0xc0) != 0 ) {
76594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if ( (return_status[1] & 0x02) != 0 ) {
76604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // diskette not writable.
76614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // AH=status code=0x03 (tried to write on write-protected disk)
76624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // AL=number of sectors written=0
76634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          AX = 0x0300;
76644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_CF();
76654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          return;
76664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
76674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_PANIC("int13_diskette_function: write error\n");
76684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
76694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
76704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
76724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_ret_status(0);
76734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_current_cyl(drive, 0);
76744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); // successful
76754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
76764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x08: // read diskette drive parameters
76794d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f08\n");
76804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL();
76814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive > 1) {
76834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        AX = 0;
76844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX = 0;
76854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        CX = 0;
76864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        DX = 0;
76874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        ES = 0;
76884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        DI = 0;
76894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_DL(num_floppies);
76904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
76914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
76924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
76934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
76944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive_type = inb_cmos(0x10);
76954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      num_floppies = 0;
76964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive_type & 0xf0)
76974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        num_floppies++;
76984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive_type & 0x0f)
76994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        num_floppies++;
77004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive == 0)
77024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        drive_type >>= 4;
77034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else
77044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        drive_type &= 0x0f;
77054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_BH(0);
77074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_BL(drive_type);
77084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0);
77094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AL(0);
77104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_DL(num_floppies);
77114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      switch (drive_type) {
77134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 0: // none
77144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0;
77154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(0); // max head #
77164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 1: // 360KB, 5.25"
77194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x2709; // 40 tracks, 9 sectors
77204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(1); // max head #
77214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 2: // 1.2MB, 5.25"
77244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x4f0f; // 80 tracks, 15 sectors
77254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(1); // max head #
77264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 3: // 720KB, 3.5"
77294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x4f09; // 80 tracks, 9 sectors
77304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(1); // max head #
77314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 4: // 1.44MB, 3.5"
77344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x4f12; // 80 tracks, 18 sectors
77354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(1); // max head #
77364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 5: // 2.88MB, 3.5"
77394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x4f24; // 80 tracks, 36 sectors
77404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(1); // max head #
77414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 6: // 160k, 5.25"
77444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x2708; // 40 tracks, 8 sectors
77454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(0); // max head #
77464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 7: // 180k, 5.25"
77494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x2709; // 40 tracks, 9 sectors
77504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(0); // max head #
77514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        case 8: // 320k, 5.25"
77544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          CX = 0x2708; // 40 tracks, 8 sectors
77554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          SET_DH(1); // max head #
77564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          break;
77574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        default: // ?
77594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_PANIC("floppy: int13: bad floppy type\n");
77604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
77614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* set es & di to point to 11 byte diskette param table in ROM */
77634d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
77644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      push bp
77654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov  bp, sp
77664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov ax, #diskette_param_table2
77674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov _int13_diskette_function.DI+2[bp], ax
77684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      mov _int13_diskette_function.ES+2[bp], cs
77694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      pop  bp
77704d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
77714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); // success
77724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* disk status not changed upon success */
77734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
77744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x15: // read diskette drive type
77774d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f15\n");
77784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL();
77794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive > 1) {
77804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0); // only 2 drives supported
77814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // set_diskette_ret_status here ???
77824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
77834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
77844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
77854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive_type = inb_cmos(0x10);
77864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive == 0)
77884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        drive_type >>= 4;
77894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else
77904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        drive_type &= 0x0f;
77914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF(); // successful, not present
77924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive_type==0) {
77934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0); // drive not present
77944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
77954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      else {
77964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(1); // drive present, does not support change line
77974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
77984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
77994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
78004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x16: // get diskette change line status
78024d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f16\n");
78034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      drive = GET_ELDL();
78044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (drive > 1) {
78054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x01); // invalid drive
78064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(0x01);
78074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
78084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
78094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
78104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x06); // change line not supported
78124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_ret_status(0x06);
78134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
78144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
78154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x17: // set diskette type for format(old)
78174d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f17\n");
78184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* not used for 1.44M floppies */
78194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x01); // not supported
78204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_ret_status(1); /* not supported */
78214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
78224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
78234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x18: // set diskette type for format(new)
78254d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBX_DEBUG_INT13_FL("floppy f18\n");
78264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x01); // do later
78274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      set_diskette_ret_status(1);
78284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
78294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
78304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
78324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("int13_diskette: unsupported AH=%02x\n", GET_AH());
78334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // if ( (ah==0x20) || ((ah>=0x41) && (ah<=0x49)) || (ah==0x4e) ) {
78354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_AH(0x01); // ???
78364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        set_diskette_ret_status(1);
78374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
78384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
78394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //   }
78404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
78414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
78424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else  // #if BX_SUPPORT_FLOPPY
78434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
78444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
78454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
78464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
78474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  val8;
78484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch ( GET_AH() ) {
78504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0x01: // Read Diskette Status
78524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      CLEAR_CF();
78534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = read_byte(0x0000, 0x0441);
78544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(val8);
78554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (val8) {
78564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SET_CF();
78574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
78584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
78594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
78614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_CF();
78624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      write_byte(0x0000, 0x0441, 0x01);
78634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SET_AH(0x01);
78644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
78654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
78664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif  // #if BX_SUPPORT_FLOPPY
78674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima void
78694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaset_diskette_ret_status(value)
78704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u value;
78714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
78724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x0041, value);
78734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
78744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
78764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaset_diskette_current_cyl(drive, cyl)
78774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u drive;
78784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u cyl;
78794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
78804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive > 1)
78814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC("set_diskette_current_cyl(): drive > 1\n");
78824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  write_byte(0x0040, 0x0094+drive, cyl);
78834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
78844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
78864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadetermine_floppy_media(drive)
78874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u drive;
78884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
78894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
78904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  val8, DOR, ctrl_info;
78914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ctrl_info = read_byte(0x0040, 0x008F);
78934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive==1)
78944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ctrl_info >>= 4;
78954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
78964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ctrl_info &= 0x0f;
78974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
78984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
78994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (drive == 0) {
79004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    DOR = 0x1c; // DOR: drive0 motor on, DMA&int enabled, normal op, drive select 0
79014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
79024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else {
79034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    DOR = 0x2d; // DOR: drive1 motor on, DMA&int enabled, normal op, drive select 1
79044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
79054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
79064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ( (ctrl_info & 0x04) != 0x04 ) {
79084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // Drive not determined means no drive exists, done.
79094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
79104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
79114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
79134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // check Main Status Register for readiness
79144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  val8 = inb(0x03f4) & 0x80; // Main Status Register
79154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (val8 != 0x80)
79164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_PANIC("d_f_m: MRQ bit not set\n");
79174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // change line
79194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // existing BDA values
79214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // turn on drive motor
79234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  outb(0x03f2, DOR); // Digital Output Register
79244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //
79254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
79264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_PANIC("d_f_m: OK so far\n");
79274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
79284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
79294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
79314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint17_function(regs, ds, iret_addr)
79324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha_regs_t regs; // regs pushed from PUSHA instruction
79334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
79344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret_addr_t  iret_addr; // CS,IP,Flags pushed from original INT call
79354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
79364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u addr,timeout;
79374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u val8;
79384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
79404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
79414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
79424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  addr = read_word(0x0040, (regs.u.r16.dx << 1) + 8);
79444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((regs.u.r8.ah < 3) && (regs.u.r16.dx < 3) && (addr > 0)) {
79454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    timeout = read_byte(0x0040, 0x0078 + regs.u.r16.dx) << 8;
79464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (regs.u.r8.ah == 0) {
79474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(addr, regs.u.r8.al);
79484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = inb(addr+2);
79494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(addr+2, val8 | 0x01); // send strobe
79504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
79514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nop
79524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
79534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(addr+2, val8 & ~0x01);
79544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      while (((inb(addr+1) & 0x40) == 0x40) && (timeout)) {
79554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        timeout--;
79564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
79574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
79584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (regs.u.r8.ah == 1) {
79594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = inb(addr+2);
79604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(addr+2, val8 & ~0x04); // send init
79614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
79624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      nop
79634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
79644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(addr+2, val8 | 0x04);
79654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
79664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    val8 = inb(addr+1);
79674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    regs.u.r8.ah = (val8 ^ 0x48);
79684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (!timeout) regs.u.r8.ah |= 0x01;
79694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ClearCF(iret_addr.flags);
79704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } else {
79714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    SetCF(iret_addr.flags); // Unsupported
79724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
79734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
79744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid
79764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint19_function(seq_nr)
79774d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBit16u seq_nr;
79784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
79794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ebda_seg=read_word(0x0040,0x000E);
79804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u bootdev;
79814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  bootdrv;
79824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u  bootchk;
79834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u bootseg;
79844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u bootip;
79854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u status;
79864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u bootfirst;
79874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ipl_entry_t e;
79894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
79904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // if BX_ELTORITO_BOOT is not defined, old behavior
79914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //   check bit 5 in CMOS reg 0x2d.  load either 0x00 or 0x80 into DL
79924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //   in preparation for the intial INT 13h (0=floppy A:, 0x80=C:)
79934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     0: system boot sequence, first drive C: then A:
79944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     1: system boot sequence, first drive A: then C:
79954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // else BX_ELTORITO_BOOT is defined
79964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //   CMOS regs 0x3D and 0x38 contain the boot sequence:
79974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     CMOS reg 0x3D & 0x0f : 1st boot device
79984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     CMOS reg 0x3D & 0xf0 : 2nd boot device
79994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     CMOS reg 0x38 & 0xf0 : 3rd boot device
80004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //   boot device codes:
80014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     0x00 : not defined
80024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     0x01 : first floppy
80034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     0x02 : first harddrive
80044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     0x03 : first cdrom
80054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     0x04 - 0x0f : PnP expansion ROMs (e.g. Etherboot)
80064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //     else : boot failure
80074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Get the boot sequence
80094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
80104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bootdev = inb_cmos(0x3d);
80114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bootdev |= ((inb_cmos(0x38) & 0xf0) << 4);
80124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bootdev >>= 4 * seq_nr;
80134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bootdev &= 0xf;
80144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Read user selected device */
80164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bootfirst = read_word(IPL_SEG, IPL_BOOTFIRST_OFFSET);
80174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (bootfirst != 0xFFFF) {
80184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootdev = bootfirst;
80194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* User selected device not set */
80204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF);
80214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Reset boot sequence */
80224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xFFFF);
80234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } else if (bootdev == 0) BX_PANIC("No bootable device.\n");
80244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
80264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bootdev -= 1;
80274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
80284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (seq_nr ==2) BX_PANIC("No more boot devices.");
80294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (!!(inb_cmos(0x2d) & 0x20) ^ (seq_nr == 1))
80304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      /* Boot from floppy if the bit is set or it's the second boot */
80314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootdev = 0x00;
80324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  else
80334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootdev = 0x01;
80344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
80354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Read the boot device from the IPL table */
80374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (get_boot_vector(bootdev, &e) == 0) {
80384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    BX_INFO("Invalid boot device (0x%x)\n", bootdev);
80394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    return;
80404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
80414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Do the loading, and set up vector as a far pointer to the boot
80434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   * address, and bootdrv as the boot drive */
80444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  print_boot_device(&e);
80454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch(e.type) {
80474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  case IPL_TYPE_FLOPPY: /* FDD */
80484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  case IPL_TYPE_HARDDISK: /* HDD */
80494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
80514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootseg = 0x07c0;
80524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = 0;
80534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80544d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
80554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bp
80564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
80574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
80584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push bx
80594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push cx
80604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push dx
80614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dl, _int19_function.bootdrv + 2[bp]
80634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, _int19_function.bootseg + 2[bp]
80644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  es, ax         ;; segment
80654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    xor  bx, bx         ;; offset
80664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ah, #0x02      ;; function 2, read diskette sector
80674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  al, #0x01      ;; read 1 sector
80684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ch, #0x00      ;; track 0
80694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  cl, #0x01      ;; sector 1
80704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dh, #0x00      ;; head 0
80714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    int  #0x13          ;; read sector
80724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    jnc  int19_load_done
80734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, #0x0001
80744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  _int19_function.status + 2[bp], ax
80754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint19_load_done:
80774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  dx
80784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  cx
80794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bx
80804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  ax
80814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pop  bp
80824d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
80834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (status != 0) {
80854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      print_boot_failure(e.type, 1);
80864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
80874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
80884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Always check the signature on a HDD boot sector; on FDD, only do
80904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima     * the check if the CMOS doesn't tell us to skip it */
80914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((e.type != IPL_TYPE_FLOPPY) || !((inb_cmos(0x38) & 0x01))) {
80924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (read_word(bootseg,0x1fe) != 0xaa55) {
80934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        print_boot_failure(e.type, 0);
80944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        return;
80954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
80964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
80974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
80984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    /* Canonicalize bootseg:bootip */
80994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootip = (bootseg & 0x0fff) << 4;
81004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootseg &= 0xf000;
81014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  break;
81024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
81044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  case IPL_TYPE_CDROM: /* CD-ROM */
81054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    status = cdrom_boot();
81064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    // If failure
81084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ( (status & 0x00ff) !=0 ) {
81094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      print_cdromboot_failure(status);
81104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      print_boot_failure(e.type, 1);
81114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      return;
81124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
81134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootdrv = (Bit8u)(status>>8);
81154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
81164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootip = 0;
81174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    break;
81184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
81194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  case IPL_TYPE_BEV: /* Expansion ROM with a Bootstrap Entry Vector (a far pointer) */
81214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootseg = e.vector >> 16;
81224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bootip = e.vector & 0xffff;
81234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    break;
81244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  default: return;
81264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
81274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Debugging info */
81294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_INFO("Booting from %x:%x\n", bootseg, bootip);
81304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* Jump to the boot vector */
81324d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
81334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, sp
81344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push cs
81354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push #int18_handler
81364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; Build an iret stack frame that will take us to the boot vector.
81374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; iret pops ip, then cs, then flags, so push them in the opposite order.
81384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    pushf
81394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, _int19_function.bootseg + 0[bp]
81404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
81414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, _int19_function.bootip + 0[bp]
81424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    push ax
81434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; Set the magic number in ax and the boot drive in dl.
81444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ax, #0xaa55
81454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  dl, _int19_function.bootdrv + 0[bp]
81464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; Zero some of the other registers.
81474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    xor  bx, bx
81484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  ds, bx
81494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  es, bx
81504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    mov  bp, bx
81514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    ;; Go!
81524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    iret
81534d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
81544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
81554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
81574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1a_function(regs, ds, iret_addr)
81584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha_regs_t regs; // regs pushed from PUSHA instruction
81594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
81604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret_addr_t  iret_addr; // CS,IP,Flags pushed from original INT call
81614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
81624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u val8;
81634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  BX_DEBUG_INT1A("int1a: AX=%04x BX=%04x CX=%04x DX=%04x DS=%04x\n", regs.u.r16.ax, regs.u.r16.bx, regs.u.r16.cx, regs.u.r16.dx, ds);
81654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_START
81674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
81684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ASM_END
81694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  switch (regs.u.r8.ah) {
81714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0: // get current clock count
81724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
81734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cli
81744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
81754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r16.cx = BiosData->ticks_high;
81764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r16.dx = BiosData->ticks_low;
81774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al  = BiosData->midnight_flag;
81784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BiosData->midnight_flag = 0; // reset flag
81794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
81804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sti
81814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
81824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // AH already 0
81834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
81844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
81854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
81864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 1: // Set Current Clock Count
81874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
81884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cli
81894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
81904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BiosData->ticks_high = regs.u.r16.cx;
81914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BiosData->ticks_low  = regs.u.r16.dx;
81924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      BiosData->midnight_flag = 0; // reset flag
81934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_START
81944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sti
81954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ASM_END
81964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
81974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
81984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
81994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 2: // Read CMOS Time
82024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (rtc_updating()) {
82034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SetCF(iret_addr.flags);
82044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
82054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
82064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.dh = inb_cmos(0x00); // Seconds
82084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.cl = inb_cmos(0x02); // Minutes
82094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ch = inb_cmos(0x04); // Hours
82104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.dl = inb_cmos(0x0b) & 0x01; // Stat Reg B
82114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
82124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al = regs.u.r8.ch;
82134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
82144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
82154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 3: // Set CMOS Time
82174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Using a debugger, I notice the following masking/setting
82184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // of bits in Status Register B, by setting Reg B to
82194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // a few values and getting its value after INT 1A was called.
82204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
82214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //        try#1       try#2       try#3
82224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // before 1111 1101   0111 1101   0000 0000
82234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // after  0110 0010   0110 0010   0000 0010
82244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
82254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
82264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // My assumption: RegB = ((RegB & 01100000b) | 00000010b)
82274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (rtc_updating()) {
82284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        init_rtc();
82294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // fall through as if an update were not in progress
82304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
82314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x00, regs.u.r8.dh); // Seconds
82324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x02, regs.u.r8.cl); // Minutes
82334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x04, regs.u.r8.ch); // Hours
82344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Set Daylight Savings time enabled bit to requested value
82354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = (inb_cmos(0x0b) & 0x60) | 0x02 | (regs.u.r8.dl & 0x01);
82364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // (reg B already selected)
82374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x0b, val8);
82384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
82394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al = val8; // val last written to Reg B
82404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
82414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
82424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 4: // Read CMOS Date
82444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
82454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (rtc_updating()) {
82464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SetCF(iret_addr.flags);
82474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
82484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
82494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.cl = inb_cmos(0x09); // Year
82504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.dh = inb_cmos(0x08); // Month
82514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.dl = inb_cmos(0x07); // Day of Month
82524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ch = inb_cmos(0x32); // Century
82534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al = regs.u.r8.ch;
82544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
82554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
82564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 5: // Set CMOS Date
82584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Using a debugger, I notice the following masking/setting
82594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // of bits in Status Register B, by setting Reg B to
82604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // a few values and getting its value after INT 1A was called.
82614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
82624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //        try#1       try#2       try#3       try#4
82634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // before 1111 1101   0111 1101   0000 0010   0000 0000
82644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // after  0110 1101   0111 1101   0000 0010   0000 0000
82654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
82664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
82674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // My assumption: RegB = (RegB & 01111111b)
82684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (rtc_updating()) {
82694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        init_rtc();
82704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SetCF(iret_addr.flags);
82714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
82724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
82734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x09, regs.u.r8.cl); // Year
82744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x08, regs.u.r8.dh); // Month
82754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x07, regs.u.r8.dl); // Day of Month
82764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x32, regs.u.r8.ch); // Century
82774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = inb_cmos(0x0b) & 0x7f; // clear halt-clock bit
82784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x0b, val8);
82794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
82804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al = val8; // AL = val last written to Reg B
82814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
82824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
82834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
82844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 6: // Set Alarm Time in CMOS
82854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Using a debugger, I notice the following masking/setting
82864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // of bits in Status Register B, by setting Reg B to
82874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // a few values and getting its value after INT 1A was called.
82884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
82894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //        try#1       try#2       try#3
82904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // before 1101 1111   0101 1111   0000 0000
82914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // after  0110 1111   0111 1111   0010 0000
82924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
82934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
82944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // My assumption: RegB = ((RegB & 01111111b) | 00100000b)
82954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = inb_cmos(0x0b); // Get Status Reg B
82964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r16.ax = 0;
82974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (val8 & 0x20) {
82984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Alarm interrupt enabled already
82994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        SetCF(iret_addr.flags); // Error: alarm in use
83004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        break;
83014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
83024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (rtc_updating()) {
83034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        init_rtc();
83044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // fall through as if an update were not in progress
83054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
83064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x01, regs.u.r8.dh); // Seconds alarm
83074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x03, regs.u.r8.cl); // Minutes alarm
83084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x05, regs.u.r8.ch); // Hours alarm
83094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb(0xa1, inb(0xa1) & 0xfe); // enable IRQ 8
83104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // enable Status Reg B alarm bit, clear halt clock bit
83114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x0b, (val8 & 0x7f) | 0x20);
83124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
83134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
83144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 7: // Turn off Alarm
83164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Using a debugger, I notice the following masking/setting
83174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // of bits in Status Register B, by setting Reg B to
83184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // a few values and getting its value after INT 1A was called.
83194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
83204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //        try#1       try#2       try#3       try#4
83214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // before 1111 1101   0111 1101   0010 0000   0010 0010
83224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // after  0100 0101   0101 0101   0000 0000   0000 0010
83234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      //
83244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1
83254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // My assumption: RegB = (RegB & 01010111b)
83264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      val8 = inb_cmos(0x0b); // Get Status Reg B
83274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // clear clock-halt bit, disable alarm bit
83284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      outb_cmos(0x0b, val8 & 0x57); // disable alarm bit
83294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = 0;
83304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.al = val8; // val last written to Reg B
83314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      ClearCF(iret_addr.flags); // OK
83324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
83334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_PCIBIOS
83344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    case 0xb1:
83354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // real mode PCI BIOS functions now handled in assembler code
83364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // this C code handles the error code for information only
83374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (regs.u.r8.bl == 0xff) {
83384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("PCI BIOS: PCI not present\n");
83394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (regs.u.r8.bl == 0x81) {
83404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("unsupported PCI BIOS function 0x%02x\n", regs.u.r8.al);
83414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (regs.u.r8.bl == 0x83) {
83424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        BX_INFO("bad PCI vendor ID %04x\n", regs.u.r16.dx);
83434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      } else if (regs.u.r8.bl == 0x86) {
83444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if (regs.u.r8.al == 0x02) {
83454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("PCI device %04x:%04x not found at index %d\n", regs.u.r16.dx, regs.u.r16.cx, regs.u.r16.si);
83464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
83474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          BX_INFO("no PCI device with class code 0x%02x%04x found at index %d\n", regs.u.r8.cl, regs.u.r16.dx, regs.u.r16.si);
83484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
83494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
83504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      regs.u.r8.ah = regs.u.r8.bl;
83514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SetCF(iret_addr.flags);
83524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
83534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
83544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    default:
83564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      SetCF(iret_addr.flags); // Unsupported
83574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
83584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
83594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  void
83614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint70_function(regs, ds, iret_addr)
83624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha_regs_t regs; // regs pushed from PUSHA instruction
83634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
83644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret_addr_t  iret_addr; // CS,IP,Flags pushed from original INT call
83654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
83664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // INT 70h: IRQ 8 - CMOS RTC interrupt from periodic or alarm modes
83674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  Bit8u registerB = 0, registerC = 0;
83684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // Check which modes are enabled and have occurred.
83704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  registerB = inb_cmos( 0xB );
83714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  registerC = inb_cmos( 0xC );
83724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if( ( registerB & 0x60 ) != 0 ) {
83744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if( ( registerC & 0x20 ) != 0 ) {
83754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Handle Alarm Interrupt.
83764d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
83774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sti
83784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      int #0x4a
83794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      cli
83804d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
83814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
83824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if( ( registerC & 0x40 ) != 0 ) {
83834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      // Handle Periodic Interrupt.
83844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if( read_byte( 0x40, 0xA0 ) != 0 ) {
83864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        // Wait Interval (Int 15, AH=83) active.
83874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        Bit32u time, toggle;
83884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        time = read_dword( 0x40, 0x9C );  // Time left in microseconds.
83904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        if( time < 0x3D1 ) {
83914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Done waiting.
83924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          Bit16u segment, offset;
83934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
83944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          segment = read_word( 0x40, 0x98 );
83954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          offset = read_word( 0x40, 0x9A );
83964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte( 0x40, 0xA0, 0 );  // Turn of status byte.
83974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          outb_cmos( 0xB, registerB & 0x37 ); // Clear the Periodic Interrupt.
83984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_byte(segment, offset, read_byte(segment, offset) | 0x80 );  // Write to specified flag byte.
83994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        } else {
84004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          // Continue waiting.
84014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          time -= 0x3D1;
84024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima          write_dword( 0x40, 0x9C, time );
84034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        }
84044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
84054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
84064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
84074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84084d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
84094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eoi_both_pics
84104d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
84114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
84124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84144d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
84154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;------------------------------------------
84164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT74h : PS/2 mouse hardware interrupt -
84174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;------------------------------------------
84184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint74_handler:
84194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
84204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
84214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds         ;; save DS
84224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x00 ;; placeholder for status
84234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x00 ;; placeholder for X
84244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x00 ;; placeholder for Y
84254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x00 ;; placeholder for Z
84264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x00 ;; placeholder for make_far_call boolean
84274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int74_function
84284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  cx      ;; remove make_far_call from stack
84294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jcxz int74_done
84304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; make far call to EBDA:0022
84324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x00
84334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
84344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push 0x040E     ;; push 0000:040E (opcodes 0xff, 0x36, 0x0E, 0x04)
84354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
84364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //CALL_EP(0x0022) ;; call far routine (call_Ep DS:0022 :opcodes 0xff, 0x1e, 0x22, 0x00)
84374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call far ptr[0x22]
84384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint74_done:
84394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
84404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eoi_both_pics
84414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add sp, #8     ;; pop status, x, y, z
84424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds          ;; restore DS
84444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
84454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
84464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; This will perform an IRET, but will retain value of current CF
84494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; by altering flags on stack.  Better than RETF #02.
84504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimairet_modify_cf:
84514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jc   carry_set
84524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
84534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
84544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  BYTE [bp + 0x06], #0xfe
84554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
84564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
84574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacarry_set:
84584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
84594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
84604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   BYTE [bp + 0x06], #0x01
84614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
84624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
84634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------
84664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT13h (relocated) -
84674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------
84684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;
84694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; int13_relocated is a little bit messed up since I played with it
84704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; I have to rewrite it:
84714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;   - call a function that detect which function to call
84724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;   - make all called C function get the same parameters list
84734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;
84744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_relocated:
84754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
84774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; check for an eltorito function
84784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   ah,#0x4a
84794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jb    int13_not_eltorito
84804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   ah,#0x4d
84814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ja    int13_not_eltorito
84824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
84844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  es
84854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
84864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ss
84874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ds
84884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  #int13_out
84904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp   _int13_eltorito      ;; ELDX not used
84914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_not_eltorito:
84934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ax
84944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  bx
84954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  cx
84964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  dx
84974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
84984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; check if emulation active
84994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call  _cdemu_isactive
85004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   al,#0x00
85014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je    int13_cdemu_inactive
85024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; check if access to the emulated drive
85044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call  _cdemu_emulated_drive
85054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   dx
85064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  dx
85074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   al,dl                ;; int13 on emulated drive
85084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne   int13_nocdemu
85094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   dx
85114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   cx
85124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   bx
85134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ax
85144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
85164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  es
85174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
85184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ss
85194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ds
85204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  #int13_out
85224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp   _int13_cdemu         ;; ELDX not used
85234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_nocdemu:
85254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and   dl,#0xE0             ;; mask to get device class, including cdroms
85264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   al,dl                ;; al is 0x00 or 0x80
85274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne   int13_cdemu_inactive ;; inactive for device class
85284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   dx
85304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   cx
85314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   bx
85324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ax
85334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ax
85354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  cx
85364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  dx
85374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  bx
85384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec   dl                   ;; real drive is dl - 1
85404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp   int13_legacy
85414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_cdemu_inactive:
85434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   dx
85444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   cx
85454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   bx
85464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ax
85474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
85494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_noeltorito:
85514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ax
85534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  cx
85544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  dx
85554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  bx
85564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_legacy:
85584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  dx                   ;; push eltorito value of dx instead of sp
85604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  bp
85624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  si
85634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  di
85644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  es
85664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
85674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ss
85684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ds
85694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; now the 16-bit registers can be restored with:
85714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; pop ds; pop es; popa; iret
85724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; arguments passed to functions should be
85734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS
85744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  test  dl, #0x80
85764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz   int13_notfloppy
85774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #int13_out
85794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp _int13_diskette_function
85804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_notfloppy:
85824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
85844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   dl, #0xE0
85864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jb    int13_notcdrom
85874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // ebx is modified: BSD 5.2.1 boot loader problem
85894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // someone should figure out which 32 bit register that actually are used
85904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr   ebx, #16
85924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  bx
85934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call  _int13_cdrom
85954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   bx
85974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl   ebx, #16
85984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
85994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int13_out
86004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_notcdrom:
86024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
86044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_disk:
86064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; int13_harddisk modifies high word of EAX
86074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr   eax, #16
86084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ax
86094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call  _int13_harddisk
86104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ax
86114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl   eax, #16
86124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_out:
86144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
86154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop es
86164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
86174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
86184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
86204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT18h -
86214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
86224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint18_handler: ;; Boot Failure recovery: try the next device.
86234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Reset SP and SS
86254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xfffe
86264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  sp, ax
86274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
86284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ss, ax
86294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Get the boot sequence number out of the IPL memory
86314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #IPL_SEG
86324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx                     ;; Set segment
86334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, IPL_SEQUENCE_OFFSET    ;; BX is now the sequence number
86344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx                         ;; ++
86354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  IPL_SEQUENCE_OFFSET, bx    ;; Write it back
86364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax                     ;; and reset the segment to zero.
86374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Carry on in the INT 19h handler, using the new sequence number
86394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx
86404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  int19_next_boot
86424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
86444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT19h -
86454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
86464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint19_relocated: ;; Boot function, relocated
86474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; int19 was beginning to be really complex, so now it
86494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; just calls a C function that does the work
86504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
86524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
86534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Reset SS and SP
86554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xfffe
86564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  sp, ax
86574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
86584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ss, ax
86594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Start from the first boot device (0, in AX)
86614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #IPL_SEG
86624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx                     ;; Set segment to write to the IPL memory
86634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  IPL_SEQUENCE_OFFSET, ax    ;; Save the sequence number
86644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax                     ;; and reset the segment.
86654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
86674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint19_next_boot:
86694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Call the C code for the next boot device
86714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int19_function
86724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Boot failed: invoke the boot recovery function
86744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  #0x18
86754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
86774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT1Ch -
86784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
86794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1c_handler: ;; User Timer Tick
86804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
86814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------
86844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- POST: Floppy Drive -
86854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------
86864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloppy_drive_post:
86874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
86884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
86894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x00
86914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x043e, al ;; drive 0 & 1 uncalibrated, no interrupt has occurred
86924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x043f, al  ;; diskette motor status: read op, drive0, motors off
86944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0440, al  ;; diskette motor timeout counter: not active
86964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0441, al  ;; diskette controller status return code
86974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
86984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0442, al  ;; disk & diskette controller status register 0
86994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0443, al  ;; diskette controller status register 1
87004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0444, al  ;; diskette controller status register 2
87014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0445, al  ;; diskette controller cylinder number
87024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0446, al  ;; diskette controller head number
87034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0447, al  ;; diskette controller sector number
87044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0448, al  ;; diskette controller bytes written
87054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x048b, al  ;; diskette configuration data
87074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; -----------------------------------------------------------------
87094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; (048F) diskette controller information
87104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
87114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x10   ;; get CMOS diskette drive type
87124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  0x70, AL
87134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   AL, 0x71
87144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al      ;; save byte to AH
87154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalook_drive0:
87174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr  al, #4      ;; look at top 4 bits for drive 0
87184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   f0_missing  ;; jump if no drive0
87194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, #0x07   ;; drive0 determined, multi-rate, has changed line
87204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  look_drive1
87214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaf0_missing:
87224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, #0x00   ;; no drive0
87234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalook_drive1:
87254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, ah      ;; restore from AH
87264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0x0f   ;; look at bottom 4 bits for drive 1
87274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   f1_missing  ;; jump if no drive1
87284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   bl, #0x70   ;; drive1 determined, multi-rate, has changed line
87294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaf1_missing:
87304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                   ;; leave high bits in BL zerod
87314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x048f, bl  ;; put new val in BDA (diskette controller information)
87324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; -----------------------------------------------------------------
87334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x00
87354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0490, al  ;; diskette 0 media state
87364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0491, al  ;; diskette 1 media state
87374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                   ;; diskette 0,1 operational starting state
87394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                   ;; drive type has not been determined,
87404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                   ;; has no changed detection line
87414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0492, al
87424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0493, al
87434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0494, al  ;; diskette 0 current cylinder
87454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0495, al  ;; diskette 1 current cylinder
87464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x02
87484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x0a, al   ;; clear DMA-1 channel 2 mask bit
87494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x1E, #0xF000, #diskette_param_table2)
87514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x40, #0xF000, #int13_diskette)
87524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x0E, #0xF000, #int0e_handler) ;; IRQ 6
87534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
87554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
87584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- POST: HARD DRIVE -
87594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
87604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; relocated here because the primary POST area isnt big enough.
87614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahard_drive_post:
87624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // IRQ 14 = INT 76h
87634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  // INT 76h calls INT 15h function ax=9100
87644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x0a   ; 0000 1010 = reserved, disable IRQ 14
87664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x03f6
87674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
87684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
87704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
87714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0474, al /* hard disk status of last operation */
87724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0477, al /* hard disk port offset (XT only ???) */
87734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x048c, al /* hard disk status register */
87744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x048d, al /* hard disk error register */
87754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x048e, al /* hard disk task complete flag */
87764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x01
87774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0475, al /* hard disk number attached */
87784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0xc0
87794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0476, al /* hard disk control byte */
87804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x13, #0xF000, #int13_handler)
87814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x76, #0xF000, #int76_handler)
87824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; INT 41h: hard disk 0 configuration pointer
87834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; INT 46h: hard disk 1 configuration pointer
87844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x41, #EBDA_SEG, #0x003D)
87854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x46, #EBDA_SEG, #0x004D)
87864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
87874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; move disk geometry data from CMOS to EBDA disk parameter table(s)
87884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x12
87894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
87904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
87914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xf0
87924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xf0
87934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   post_d0_extended
87944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp check_for_hd1
87954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_d0_extended:
87964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x19
87974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
87984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
87994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #47  ;; decimal 47 - user definable
88004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   post_d0_type47
88014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  HALT(__LINE__)
88024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_d0_type47:
88034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; CMOS  purpose                  param table offset
88044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1b    cylinders low            0
88054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1c    cylinders high           1
88064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1d    heads                    2
88074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1e    write pre-comp low       5
88084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1f    write pre-comp high      6
88094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 20    retries/bad map/heads>8  8
88104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 21    landing zone low         C
88114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 22    landing zone high        D
88124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 23    sectors/track            E
88134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #EBDA_SEG
88154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
88164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;; Filling EBDA table for hard disk 0.
88184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x1f
88194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al
88224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x1e
88234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x05), ax ;; write precomp word
88264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x20
88284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x08), al ;; drive control byte
88314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x22
88334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al
88364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x21
88374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x0C), ax ;; landing zone word
88404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x1c   ;; get cylinders word in AX
88424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71   ;; high byte
88444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al
88454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x1b
88464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71   ;; low byte
88484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, ax      ;; BX = cylinders
88494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x1d
88514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cl, al      ;; CL = heads
88544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x23
88564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
88574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
88584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, al      ;; DL = sectors
88594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  bx, #1024
88614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd0_post_logical_chs ;; if cylinders > 1024, use translated style CHS
88624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_physical_chs:
88644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; no logical CHS mapping used, just physical CHS
88654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; use Standard Fixed Disk Parameter Table (FDPT)
88664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x00), bx ;; number of physical cylinders
88674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x02), cl ;; number of physical heads
88684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x0E), dl ;; number of physical sectors
88694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp check_for_hd1
88704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_logical_chs:
88724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; complies with Phoenix style Translated Fixed Disk Parameter Table (FDPT)
88734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x09), bx ;; number of physical cylinders
88744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x0b), cl ;; number of physical heads
88754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x04), dl ;; number of physical sectors
88764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x0e), dl ;; number of logical sectors (same)
88774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0xa0
88784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x03), al ;; A0h signature, indicates translated table
88794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #2048
88814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd0_post_above_2048
88824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1024 < c <= 2048 cylinders
88834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x01
88844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x01
88854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp hd0_post_store_logical
88864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_above_2048:
88884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #4096
88894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd0_post_above_4096
88904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 2048 < c <= 4096 cylinders
88914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x02
88924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x02
88934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp hd0_post_store_logical
88944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
88954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_above_4096:
88964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #8192
88974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd0_post_above_8192
88984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 4096 < c <= 8192 cylinders
88994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x03
89004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x03
89014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp hd0_post_store_logical
89024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_above_8192:
89044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 8192 < c <= 16384 cylinders
89054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x04
89064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x04
89074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_store_logical:
89094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x00), bx ;; number of physical cylinders
89104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x003d + 0x02), cl ;; number of physical heads
89114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; checksum
89124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   cl, #0x0f     ;; repeat count
89134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   si, #0x003d   ;; offset to disk0 FDPT
89144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   al, #0x00     ;; sum
89154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd0_post_checksum_loop:
89164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add   al, [si]
89174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc   si
89184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec   cl
89194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz hd0_post_checksum_loop
89204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  not   al  ;; now take 2s complement
89214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc   al
89224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   [si], al
89234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;; Done filling EBDA table for hard disk 0.
89244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimacheck_for_hd1:
89274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; is there really a second hard disk?  if not, return now
89284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x12
89294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0x0f
89324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz   post_d1_exists
89334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
89344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_d1_exists:
89354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; check that the hd type is really 0x0f.
89364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0f
89374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz post_d1_extended
89384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  HALT(__LINE__)
89394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_d1_extended:
89404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; check that the extended type is 47 - user definable
89414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x1a
89424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #47  ;; decimal 47 - user definable
89454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   post_d1_type47
89464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  HALT(__LINE__)
89474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_d1_type47:
89484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Table for disk1.
89494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; CMOS  purpose                  param table offset
89504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x24    cylinders low            0
89514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x25    cylinders high           1
89524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x26    heads                    2
89534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x27    write pre-comp low       5
89544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x28    write pre-comp high      6
89554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x29    heads>8                  8
89564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x2a    landing zone low         C
89574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x2b    landing zone high        D
89584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x2c    sectors/track            E
89594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;; Fill EBDA table for hard disk 1.
89604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #EBDA_SEG
89614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
89624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x28
89634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al
89664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x27
89674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x05), ax ;; write precomp word
89704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x29
89724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x08), al ;; drive control byte
89754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x2b
89774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al
89804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x2a
89814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x0C), ax ;; landing zone word
89844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x25   ;; get cylinders word in AX
89864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71   ;; high byte
89884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, al
89894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x24
89904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71   ;; low byte
89924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, ax      ;; BX = cylinders
89934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x26
89954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
89964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
89974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cl, al      ;; CL = heads
89984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
89994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x2c
90004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
90014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71
90024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, al      ;; DL = sectors
90034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  bx, #1024
90054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd1_post_logical_chs ;; if cylinders > 1024, use translated style CHS
90064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_physical_chs:
90084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; no logical CHS mapping used, just physical CHS
90094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; use Standard Fixed Disk Parameter Table (FDPT)
90104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x00), bx ;; number of physical cylinders
90114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x02), cl ;; number of physical heads
90124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x0E), dl ;; number of physical sectors
90134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
90144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_logical_chs:
90164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; complies with Phoenix style Translated Fixed Disk Parameter Table (FDPT)
90174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x09), bx ;; number of physical cylinders
90184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x0b), cl ;; number of physical heads
90194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x04), dl ;; number of physical sectors
90204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x0e), dl ;; number of logical sectors (same)
90214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0xa0
90224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x03), al ;; A0h signature, indicates translated table
90234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #2048
90254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd1_post_above_2048
90264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1024 < c <= 2048 cylinders
90274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x01
90284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x01
90294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp hd1_post_store_logical
90304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_above_2048:
90324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #4096
90334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd1_post_above_4096
90344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 2048 < c <= 4096 cylinders
90354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x02
90364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x02
90374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp hd1_post_store_logical
90384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_above_4096:
90404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #8192
90414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnbe hd1_post_above_8192
90424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 4096 < c <= 8192 cylinders
90434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x03
90444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x03
90454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp hd1_post_store_logical
90464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_above_8192:
90484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 8192 < c <= 16384 cylinders
90494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr bx, #0x04
90504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl cl, #0x04
90514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_store_logical:
90534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x00), bx ;; number of physical cylinders
90544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   (0x004d + 0x02), cl ;; number of physical heads
90554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; checksum
90564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   cl, #0x0f     ;; repeat count
90574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   si, #0x004d   ;; offset to disk0 FDPT
90584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   al, #0x00     ;; sum
90594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimahd1_post_checksum_loop:
90604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add   al, [si]
90614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc   si
90624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec   cl
90634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz hd1_post_checksum_loop
90644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  not   al  ;; now take 2s complement
90654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc   al
90664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   [si], al
90674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;; Done filling EBDA table for hard disk 1.
90684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
90704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
90724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- POST: EBDA segment
90734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
90744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; relocated here because the primary POST area isnt big enough.
90754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaebda_post:
90764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_EBDA
90774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, #EBDA_SEG
90784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
90794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov byte ptr [0x0], #EBDA_SIZE
90804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
90814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax            ; mov EBDA seg into 40E
90824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
90834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov word ptr [0x40E], #EBDA_SEG
90844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret;;
90854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
90874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- POST: EOI + jmp via [0x40:67)
90884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
90894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; relocated here because the primary POST area isnt big enough.
90904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaeoi_jmp_post:
90914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   al, #0x20
90924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out   #0xA0, al ;; slave  PIC EOI
90934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   al, #0x20
90944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out   #0x20, al ;; master PIC EOI
90954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
90964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimajmp_post_0x467:
90974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
90984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
90994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp far ptr [0x467]
91014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimairet_post_0x467:
91034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
91044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
91054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov sp, [0x467]
91074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ss, [0x469]
91084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
91094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaretf_post_0x467:
91114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
91124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
91134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov sp, [0x467]
91154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ss, [0x469]
91164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  retf
91174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimas3_post:
91194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov sp, #0xffe
91204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ROMBIOS32
91214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call rombios32_init
91224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
91234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _s3_resume
91244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov bl, #0x00
91254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and ax, ax
91264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz normal_post
91274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _s3_resume_panic
91284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
91304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaeoi_both_pics:
91314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   al, #0x20
91324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out   #0xA0, al ;; slave  PIC EOI
91334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaeoi_master_pic:
91344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   al, #0x20
91354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out   #0x20, al ;; master PIC EOI
91364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
91374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
91394d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaBcdToBin:
91404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; in:  AL in BCD format
91414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; out: AL in binary format, AH will always be 0
91424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; trashes BX
91434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, al
91444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  bl, #0x0f ;; bl has low digit
91454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr  al, #4    ;; al has high digit
91464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bh, #10
91474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mul  al, bh    ;; multiply high digit by 10 (result in AX)
91484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  al, bl    ;;   then add low digit
91494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
91504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
91524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatimer_tick_post:
91534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Setup the Timer Ticks Count (0x46C:dword) and
91544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   Timer Ticks Roller Flag (0x470:byte)
91554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; The Timer Ticks Count needs to be set according to
91564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; the current CMOS time, as if ticks have been occurring
91574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; at 18.2hz since midnight up to this point.  Calculating
91584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; this is a little complicated.  Here are the factors I gather
91594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; regarding this.  14,318,180 hz was the original clock speed,
91604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; chosen so it could be divided by either 3 to drive the 5Mhz CPU
91614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; at the time, or 4 to drive the CGA video adapter.  The div3
91624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; source was divided again by 4 to feed a 1.193Mhz signal to
91634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; the timer.  With a maximum 16bit timer count, this is again
91644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; divided down by 65536 to 18.2hz.
91654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
91664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 14,318,180 Hz clock
91674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   /3 = 4,772,726 Hz fed to orginal 5Mhz CPU
91684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   /4 = 1,193,181 Hz fed to timer
91694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   /65536 (maximum timer count) = 18.20650736 ticks/second
91704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1 second = 18.20650736 ticks
91714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1 minute = 1092.390442 ticks
91724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 1 hour   = 65543.42651 ticks
91734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
91744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Given the values in the CMOS clock, one could calculate
91754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; the number of ticks by the following:
91764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   ticks = (BcdToBin(seconds) * 18.206507) +
91774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;           (BcdToBin(minutes) * 1092.3904)
91784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;           (BcdToBin(hours)   * 65543.427)
91794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; To get a little more accuracy, since Im using integer
91804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; arithmatic, I use:
91814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   ticks = (BcdToBin(seconds) * 18206507) / 1000000 +
91824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;           (BcdToBin(minutes) * 10923904) / 10000 +
91834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;           (BcdToBin(hours)   * 65543427) / 1000
91844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; assuming DS=0000
91864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
91874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; get CMOS seconds
91884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  eax, eax ;; clear EAX
91894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x00
91904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
91914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71 ;; AL has CMOS seconds in BCD
91924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call BcdToBin  ;; EAX now has seconds in binary
91934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  edx, #18206507
91944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mul  eax, edx
91954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ebx, #1000000
91964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  edx, edx
91974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  div  eax, ebx
91984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ecx, eax  ;; ECX will accumulate total ticks
91994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; get CMOS minutes
92014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  eax, eax ;; clear EAX
92024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x02
92034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
92044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71 ;; AL has CMOS minutes in BCD
92054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call BcdToBin  ;; EAX now has minutes in binary
92064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  edx, #10923904
92074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mul  eax, edx
92084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ebx, #10000
92094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  edx, edx
92104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  div  eax, ebx
92114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  ecx, eax  ;; add to total ticks
92124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; get CMOS hours
92144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  eax, eax ;; clear EAX
92154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x04
92164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  #0x70, al
92174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, #0x71 ;; AL has CMOS hours in BCD
92184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call BcdToBin  ;; EAX now has hours in binary
92194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  edx, #65543427
92204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mul  eax, edx
92214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ebx, #1000
92224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  edx, edx
92234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  div  eax, ebx
92244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  ecx, eax  ;; add to total ticks
92254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x46C, ecx ;; Timer Ticks Count
92274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  al, al
92284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x470, al  ;; Timer Ticks Rollover Flag
92294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
92304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
92324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint76_handler:
92334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; record completion in BIOS task complete flag
92344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ax
92354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
92364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   ax, #0x0040
92374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   ds, ax
92384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   0x008E, #0xff
92394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call  eoi_both_pics
92404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ds
92414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ax
92424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
92434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
92464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_APM
92474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause32 386
92494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define APM_PROT32
92504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include "apmbios.S"
92514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause16 386
92534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define APM_PROT16
92544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include "apmbios.S"
92554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define APM_REAL
92574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include "apmbios.S"
92584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
92604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------------------
92624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_PCIBIOS
92634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause32 386
92644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.align 16
92654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabios32_structure:
92664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x5f, 0x33, 0x32, 0x5f  ;; "_32_" signature
92674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw bios32_entry_point, 0xf ;; 32 bit physical address
92684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0             ;; revision level
92694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; length in paragraphs and checksum stored in a word to prevent errors
92704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw (~(((bios32_entry_point >> 8) + (bios32_entry_point & 0xff) + 0x32) \
92714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        & 0xff) << 8) + 0x01
92724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0,0,0,0,0     ;; reserved
92734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
92744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.align 16
92754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabios32_entry_point:
92764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushfd
92774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, #0x49435024 ;; "$PCI"
92784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne unknown_service
92794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x80000000
92804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cf8
92814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, eax
92824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
92834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
92844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifdef PCI_FIXED_HOST_BRIDGE
92854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, #PCI_FIXED_HOST_BRIDGE
92864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne unknown_service
92874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
92884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; say ok if a device is present
92894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, #0xffffffff
92904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je unknown_service
92914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
92924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ebx, #0x000f0000
92934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ecx, #0
92944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov edx, #pcibios_protected
92954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor al, al
92964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp bios32_end
92974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaunknown_service:
92984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x80
92994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabios32_end:
93004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifdef BX_QEMU
93014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu
93024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
93034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popfd
93044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  retf
93054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
93064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.align 16
93074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_protected:
93084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushfd
93094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
93104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push esi
93114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edi
93124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x01 ;; installation check
93134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f02
93144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov bx, #0x0210
93154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, #0
93164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov edx, #0x20494350 ;; "PCI "
93174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x01
93184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
93194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f02: ;; find pci device
93204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x02
93214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f03
93224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl ecx, #16
93234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, dx
93244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor bx, bx
93254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov di, #0x00
93264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_devloop:
93274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
93284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
93294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
93304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, ecx
93314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_nextdev
93324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp si, #0
93334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  pci_pro_ok
93344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec si
93354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_nextdev:
93364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc bx
93374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #0x0100
93384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_devloop
93394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ah, #0x86
93404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_fail
93414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f03: ;; find class code
93424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x03
93434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f08
93444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor bx, bx
93454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov di, #0x08
93464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_devloop2:
93474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
93484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
93494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
93504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr eax, #8
93514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, ecx
93524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_nextdev2
93534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp si, #0
93544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  pci_pro_ok
93554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec si
93564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_nextdev2:
93574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc bx
93584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #0x0100
93594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_devloop2
93604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ah, #0x86
93614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_fail
93624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f08: ;; read configuration byte
93634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x08
93644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f09
93654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
93664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
93674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
93684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x03
93694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
93704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  al, dx
93714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
93724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cl, al
93734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
93744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f09: ;; read configuration word
93754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x09
93764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f0a
93774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
93784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
93794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
93804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x02
93814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
93824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  ax, dx
93834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
93844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, ax
93854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
93864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f0a: ;; read configuration dword
93874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0a
93884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f0b
93894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
93904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
93914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
93924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
93934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
93944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ecx, eax
93954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
93964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f0b: ;; write configuration byte
93974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0b
93984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f0c
93994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
94004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
94014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
94024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x03
94034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
94044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, cl
94054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, al
94064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
94074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
94084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f0c: ;; write configuration word
94094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0c
94104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_f0d
94114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
94124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
94134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
94144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x02
94154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
94164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, cx
94174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, ax
94184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
94194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
94204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_f0d: ;; write configuration dword
94214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0d
94224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_pro_unknown
94234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_pro_select_reg
94244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
94254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
94264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, ecx
94274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, eax
94284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
94294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_pro_ok
94304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_unknown:
94314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ah, #0x81
94324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_fail:
94334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edi
94344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop esi
94354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifdef BX_QEMU
94364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu
94374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
94384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popfd
94394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  stc
94404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  retf
94414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_ok:
94424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ah, ah
94434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edi
94444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop esi
94454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifdef BX_QEMU
94464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu
94474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
94484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popfd
94494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  clc
94504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  retf
94514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
94524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_pro_select_reg:
94534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edx
94544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x800000
94554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax,  bx
94564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl eax, #8
94574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and di,  #0xff
94584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or  ax,  di
94594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and al,  #0xfc
94604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cf8
94614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx,  eax
94624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edx
94634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
94644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
94654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause16 386
94664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
94674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_real:
94684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push eax
94694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
94704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x80000000
94714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cf8
94724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, eax
94734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
94744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
94754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifdef PCI_FIXED_HOST_BRIDGE
94764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, #PCI_FIXED_HOST_BRIDGE
94774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  pci_present
94784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
94794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; say ok if a device is present
94804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, #0xffffffff
94814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  pci_present
94824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
94834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
94844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop eax
94854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ah, #0xff
94864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  stc
94874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
94884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_present:
94894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
94904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop eax
94914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x01 ;; installation check
94924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f02
94934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, #0x0001
94944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov bx, #0x0210
94954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, #0
94964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov edx, #0x20494350 ;; "PCI "
94974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov edi, #0xf0000
94984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov di, #pcibios_protected
94994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  clc
95004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
95014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f02: ;; find pci device
95024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push esi
95034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push edi
95044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x02
95054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f03
95064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl ecx, #16
95074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, dx
95084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor bx, bx
95094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov di, #0x00
95104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_devloop:
95114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
95124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
95134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
95144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, ecx
95154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_nextdev
95164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp si, #0
95174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  pci_real_ok
95184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec si
95194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_nextdev:
95204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc bx
95214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #0x0100
95224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_devloop
95234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, cx
95244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr ecx, #16
95254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, #0x8602
95264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_fail
95274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f03: ;; find class code
95284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x03
95294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f08
95304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor bx, bx
95314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov di, #0x08
95324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_devloop2:
95334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
95344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
95354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
95364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr eax, #8
95374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, ecx
95384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_nextdev2
95394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp si, #0
95404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  pci_real_ok
95414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec si
95424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_nextdev2:
95434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc bx
95444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bx, #0x0100
95454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_devloop2
95464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, cx
95474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr ecx, #16
95484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, #0x8603
95494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_fail
95504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f08: ;; read configuration byte
95514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x08
95524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f09
95534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
95544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
95554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
95564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x03
95574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
95584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  al, dx
95594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
95604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cl, al
95614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
95624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f09: ;; read configuration word
95634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x09
95644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f0a
95654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
95664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
95674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
95684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x02
95694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
95704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  ax, dx
95714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
95724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, ax
95734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
95744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f0a: ;; read configuration dword
95754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0a
95764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f0b
95774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
95784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
95794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
95804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  eax, dx
95814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
95824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ecx, eax
95834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
95844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f0b: ;; write configuration byte
95854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0b
95864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f0c
95874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
95884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
95894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
95904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x03
95914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
95924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, cl
95934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, al
95944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
95954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
95964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f0c: ;; write configuration word
95974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0c
95984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f0d
95994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
96004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
96014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, di
96024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dx, #0x02
96034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add dx, #0x0cfc
96044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, cx
96054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, ax
96064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
96074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
96084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f0d: ;; write configuration dword
96094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0d
96104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_f0e
96114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pci_real_select_reg
96124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
96134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x0cfc
96144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, ecx
96154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx, eax
96164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
96174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
96184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_f0e: ;; get irq routing options
96194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0e
96204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne pci_real_unknown
96214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG ES
96224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
96234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jb pci_real_too_small
96244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG ES
96254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
96264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushf
96274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
96284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push es
96294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push cx
96304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push si
96314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push di
96324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cld
96334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov si, #pci_routing_table_structure_start
96344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push cs
96354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
96364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG ES
96374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, [di+2]
96384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG ES
96394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov es, [di+4]
96404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov di, cx
96414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cx, #pci_routing_table_structure_end - pci_routing_table_structure_start
96424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  rep
96434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      movsb
96444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop di
96454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop si
96464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop cx
96474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop es
96484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
96494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popf
96504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov bx, #(1 << 9) | (1 << 11)   ;; irq 9 and 11 are used
96514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_ok
96524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_too_small:
96534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG ES
96544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
96554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ah, #0x89
96564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp pci_real_fail
96574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
96584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_unknown:
96594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ah, #0x81
96604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_fail:
96614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edi
96624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop esi
96634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  stc
96644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
96654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_ok:
96664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ah, ah
96674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop edi
96684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop esi
96694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  clc
96704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
96714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
96724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_real_select_reg:
96734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
96744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x800000
96754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax,  bx
96764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl eax, #8
96774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and di,  #0xff
96784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or  ax,  di
96794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and al,  #0xfc
96804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx,  #0x0cf8
96814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx,  eax
96824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop dx
96834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
96844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
96854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.align 16
96864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_routing_table_structure:
96874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x24, 0x50, 0x49, 0x52  ;; "$PIR" signature
96884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0, 1 ;; version
96894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 32 + (6 * 16) ;; table size
96904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; PCI interrupt router bus
96914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x08 ;; PCI interrupt router DevFunc
96924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x0000 ;; PCI exclusive IRQs
96934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x8086 ;; compatible PCI interrupt router vendor ID
96944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x122e ;; compatible PCI interrupt router device ID
96954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0,0 ;; Miniport data
96964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0,0,0,0,0,0,0,0,0,0,0 ;; reserved
96974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x37 ;; checksum
96984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_routing_table_structure_start:
96994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; first slot entry PCI-to-ISA (embedded)
97004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; pci bus number
97014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x08 ;; pci device number (bit 7-3)
97024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x60 ;; link value INTA#: pointer into PCI2ISA config space
97034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTA#
97044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x61 ;; link value INTB#
97054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTB#
97064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x62 ;; link value INTC#
97074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTC#
97084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x63 ;; link value INTD#
97094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTD#
97104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; physical slot (0 = embedded)
97114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; reserved
97124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; second slot entry: 1st PCI slot
97134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; pci bus number
97144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x10 ;; pci device number (bit 7-3)
97154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x61 ;; link value INTA#
97164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTA#
97174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x62 ;; link value INTB#
97184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTB#
97194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x63 ;; link value INTC#
97204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTC#
97214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x60 ;; link value INTD#
97224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTD#
97234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 1 ;; physical slot (0 = embedded)
97244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; reserved
97254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; third slot entry: 2nd PCI slot
97264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; pci bus number
97274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x18 ;; pci device number (bit 7-3)
97284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x62 ;; link value INTA#
97294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTA#
97304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x63 ;; link value INTB#
97314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTB#
97324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x60 ;; link value INTC#
97334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTC#
97344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x61 ;; link value INTD#
97354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTD#
97364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 2 ;; physical slot (0 = embedded)
97374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; reserved
97384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 4th slot entry: 3rd PCI slot
97394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; pci bus number
97404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x20 ;; pci device number (bit 7-3)
97414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x63 ;; link value INTA#
97424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTA#
97434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x60 ;; link value INTB#
97444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTB#
97454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x61 ;; link value INTC#
97464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTC#
97474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x62 ;; link value INTD#
97484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTD#
97494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 3 ;; physical slot (0 = embedded)
97504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; reserved
97514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 5th slot entry: 4rd PCI slot
97524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; pci bus number
97534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x28 ;; pci device number (bit 7-3)
97544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x60 ;; link value INTA#
97554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTA#
97564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x61 ;; link value INTB#
97574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTB#
97584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x62 ;; link value INTC#
97594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTC#
97604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x63 ;; link value INTD#
97614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTD#
97624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 4 ;; physical slot (0 = embedded)
97634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; reserved
97644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 6th slot entry: 5rd PCI slot
97654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; pci bus number
97664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x30 ;; pci device number (bit 7-3)
97674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x61 ;; link value INTA#
97684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTA#
97694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x62 ;; link value INTB#
97704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTB#
97714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x63 ;; link value INTC#
97724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTC#
97734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x60 ;; link value INTD#
97744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xdef8 ;; IRQ bitmap INTD#
97754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 5 ;; physical slot (0 = embedded)
97764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0 ;; reserved
97774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_routing_table_structure_end:
97784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
97794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if !BX_ROMBIOS32
97804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_irq_list:
97814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 11, 10, 9, 5;
97824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
97834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_init_sel_reg:
97844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push eax
97854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x800000
97864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax,  bx
97874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl eax, #8
97884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and dl,  #0xfc
97894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or  al,  dl
97904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx,  #0x0cf8
97914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out dx,  eax
97924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop eax
97934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
97944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
97954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_init_iomem_bases:
97964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
97974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
97984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  eax, #0xe0000000 ;; base for memory init
97994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push eax
98004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xc000 ;; base for i/o init
98014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
98024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x0010 ;; start at base address #0
98034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
98044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0x0008
98054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_init_io_loop1:
98064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x00
98074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
98084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
98094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   ax, dx
98104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, #0xffff
98114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   next_pci_dev
98124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x04 ;; disable i/o and memory space access
98134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
98144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
98154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
98164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xfc
98174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
98184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_init_io_loop2:
98194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, [bp-8]
98204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
98214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
98224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   eax, dx
98234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  test al, #0x01
98244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz  init_io_base
98254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ecx, eax
98264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  eax, #0xffffffff
98274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, eax
98284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   eax, dx
98294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  eax, ecx
98304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   next_pci_base
98314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  eax, #0xffffffff
98324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ecx, eax
98334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  eax, [bp-4]
98344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, eax
98354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  eax, ecx ;; calculate next free mem base
98364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  eax, #0x01000000
98374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  eax, #0xff000000
98384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bp-4], eax
98394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  next_pci_base
98404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimainit_io_base:
98414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, ax
98424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xffff
98434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, ax
98444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   ax, dx
98454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, cx
98464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   next_pci_base
98474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, #0xfffe
98484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, ax
98494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, [bp-6]
98504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, ax
98514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  ax, cx ;; calculate next free i/o base
98524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  ax, #0x0100
98534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  ax, #0xff00
98544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bp-6], ax
98554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanext_pci_base:
98564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, [bp-8]
98574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  al, #0x04
98584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0x28
98594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   enable_iomem_space
98604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  byte ptr[bp-8], al
98614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  pci_init_io_loop2
98624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaenable_iomem_space:
98634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x04 ;; enable i/o and memory space access if available
98644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
98654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
98664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
98674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al, #0x07
98684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
98694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanext_pci_dev:
98704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  byte ptr[bp-8], #0x10
98714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx
98724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  bx, #0x0100
98734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  pci_init_io_loop1
98744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  sp, bp
98754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
98764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
98774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
98784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_init_set_elcr:
98794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
98804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push cx
98814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x04d0
98824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  test al, #0x08
98834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   is_master_pic
98844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  dx
98854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0x07
98864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimais_master_pic:
98874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cl, al
98884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, #0x01
98894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl  bl, cl
98904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
98914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al, bl
98924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
98934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  cx
98944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ax
98954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
98964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
98974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_init_irqs:
98984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
98994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
99004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xf000
99014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
99024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x04d0 ;; reset ELCR1 + ELCR2
99034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x00
99044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
99054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  dx
99064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
99074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  si, #pci_routing_table_structure
99084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bh, [si+8]
99094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, [si+9]
99104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x00
99114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
99124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
99134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   ax, dx
99144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, [si+12] ;; check irq router
99154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  pci_init_end
99164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, [si+34]
99174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
99184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx ;; save irq router bus + devfunc
99194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
99204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x8080
99214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, ax ;; reset PIRQ route control
99224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  dx, #2
99234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, ax
99244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, [si+6]
99254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sub  ax, #0x20
99264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr  ax, #4
99274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, ax
99284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  si, #0x20 ;; set pointer to 1st entry
99294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
99304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #pci_irq_list
99314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
99324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
99334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
99344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_init_irq_loop1:
99354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bh, [si]
99364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, [si+1]
99374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_init_irq_loop2:
99384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x00
99394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
99404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
99414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   ax, dx
99424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, #0xffff
99434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz  pci_test_int_pin
99444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  test bl, #0x07
99454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   next_pir_entry
99464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  next_pci_func
99474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_test_int_pin:
99484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x3c
99494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
99504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfd
99514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
99524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0x07
99534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   next_pci_func
99544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec  al ;; determine pirq reg
99554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x03
99564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mul  al, dl
99574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  al, #0x02
99584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ah, ah
99594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, ax
99604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, [si+bx]
99614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, al
99624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, [bp]
99634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
99644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
99654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0x03
99664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  dl, al
99674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
99684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0x80
99694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jb   pirq_found
99704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, [bp-2] ;; pci irq list pointer
99714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, [bx]
99724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
99734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx
99744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bp-2], bx
99754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_set_elcr
99764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapirq_found:
99774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bh, [si]
99784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, [si+1]
99794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  bl, [bp-3] ;; pci function number
99804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dl, #0x3c
99814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_sel_reg
99824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x0cfc
99834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
99844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanext_pci_func:
99854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  byte ptr[bp-3]
99864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bl
99874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  test bl, #0x07
99884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz  pci_init_irq_loop2
99894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanext_pir_entry:
99904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  si, #0x10
99914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  byte ptr[bp-3], #0x00
99924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  loop pci_init_irq_loop1
99934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  sp, bp
99944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bx
99954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapci_init_end:
99964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
99974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
99984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
99994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // !BX_ROMBIOS32
100004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_PCIBIOS
100014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ROMBIOS32
100034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarombios32_init:
100044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; save a20 and enable it
100054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in al, 0x92
100064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
100074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or al, #0x02
100084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x92, al
100094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; save SS:SP to the BDA
100114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
100124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
100134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov 0x0469, ss
100144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov 0x0467, sp
100154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG CS
100174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    lidt [pmode_IDT_info]
100184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG CS
100194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    lgdt [rombios32_gdt_48]
100204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; set PE bit in CR0
100214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  eax, cr0
100224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al, #0x01
100234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cr0, eax
100244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; start protected mode code: ljmpl 0x10:rombios32_init1
100254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0x66, 0xea
100264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw rombios32_05
100274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x000f       ;; high 16 bit address
100284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x0010
100294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause32 386
100314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarombios32_05:
100324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; init data segments
100334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x18
100344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
100354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov es, ax
100364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ss, ax
100374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor eax, eax
100384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov fs, ax
100394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov gs, ax
100404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cld
100414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; init the stack pointer to point below EBDA
100434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, [0x040e]
100444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl eax, #4
100454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov esp, #-0x10
100464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add esp, eax
100474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; pass pointer to s3_resume_flag and s3_resume_vector to rombios32
100494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x04b0
100504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x04b2
100514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; call rombios32 code
100534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, #0x000e0000
100544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eax
100554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; return to 16 bit protected mode first
100574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0xea
100584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dd rombios32_10
100594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x20
100604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimause16 386
100624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarombios32_10:
100634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; restore data segment limits to 0xffff
100644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, #0x28
100654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
100664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov es, ax
100674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ss, ax
100684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov fs, ax
100694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov gs, ax
100704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; reset PE bit in CR0
100724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  eax, cr0
100734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xFE
100744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cr0, eax
100754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; far jump to flush CPU queue after transition to real mode
100774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  JMP_AP(0xf000, rombios32_real_mode)
100784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarombios32_real_mode:
100804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; restore IDT to normal real-mode defaults
100814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SEG CS
100824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    lidt [rmode_IDT_info]
100834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
100854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
100864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov es, ax
100874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov fs, ax
100884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov gs, ax
100894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; restore SS:SP from the BDA
100914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ss, 0x0469
100924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor esp, esp
100934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov sp, 0x0467
100944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; restore a20
100954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ax
100964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x92, al
100974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
100984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
100994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarombios32_gdt_48:
101004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x30
101014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw rombios32_gdt
101024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0x000f
101034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarombios32_gdt:
101054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0, 0, 0, 0
101064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0, 0, 0, 0
101074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xffff, 0, 0x9b00, 0x00cf ; 32 bit flat code segment (0x10)
101084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xffff, 0, 0x9300, 0x00cf ; 32 bit flat data segment (0x18)
101094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xffff, 0, 0x9b0f, 0x0000 ; 16 bit code segment base=0xf0000 limit=0xffff
101104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dw 0xffff, 0, 0x9300, 0x0000 ; 16 bit data segment base=0x0 limit=0xffff
101114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ROMBIOS32
101124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; parallel port detection: base address in DX, index in BX, timeout in CL
101154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadetect_parport:
101164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
101174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  dx, #2
101184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
101194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xdf ; clear input mode
101204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
101214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  dx
101224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0xaa
101234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
101244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
101254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xaa
101264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  no_parport
101274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx
101284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl  bx, #1
101294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bx+0x408], dx ; Parallel I/O address
101304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bx
101314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bx+0x478], cl ; Parallel printer timeout
101324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx
101334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimano_parport:
101344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
101354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; serial port detection: base address in DX, index in BX, timeout in CL
101374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadetect_serial:
101384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
101394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  dx
101404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x02
101414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
101424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
101434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0x02
101444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  no_serial
101454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  dx
101464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
101474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0x02
101484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  no_serial
101494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec  dx
101504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  al, al
101514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
101524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  dx
101534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx
101544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl  bx, #1
101554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bx+0x400], dx ; Serial I/O address
101564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bx
101574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bx+0x47c], cl ; Serial timeout
101584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx
101594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
101604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimano_serial:
101614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  dx
101624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
101634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarom_checksum:
101654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
101664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx
101674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push cx
101684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
101694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  bx, bx
101704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  cx, cx
101714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ch, [2]
101724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl  cx, #1
101734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimachecksum_loop:
101744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  al, [bx]
101754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx
101764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  loop checksum_loop
101774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xff
101784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  cx
101794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bx
101804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ax
101814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
101824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; We need a copy of this string, but we are not actually a PnP BIOS,
101854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; so make sure it is *not* aligned, so OSes will not see it if they scan.
101864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.align 16
101874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db 0
101884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapnp_string:
101894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  .ascii "$PnP"
101904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
101924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarom_scan:
101934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Scan for existence of valid expansion ROMS.
101944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   Video ROM:   from 0xC0000..0xC7FFF in 2k increments
101954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   General ROM: from 0xC8000..0xDFFFF in 2k increments
101964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   System  ROM: only 0xE0000
101974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
101984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Header:
101994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   Offset    Value
102004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   0         0x55
102014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   1         0xAA
102024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   2         ROM length in 512-byte blocks
102034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   3         ROM initialization entry point (FAR CALL)
102044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarom_scan_loop:
102064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax       ;; Save AX
102074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, cx
102084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x0004 ;; start with increment of 4 (512-byte) blocks = 2k
102094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp [0], #0xAA55 ;; look for signature
102104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  rom_scan_increment
102114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call rom_checksum
102124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz  rom_scan_increment
102134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, [2]  ;; change increment to ROM length in 512-byte blocks
102144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; We want our increment in 512-byte quantities, rounded to
102164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; the nearest 2k quantity, since we only scan at 2k intervals.
102174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  test al, #0x03
102184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   block_count_rounded
102194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xfc ;; needs rounding up
102204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  al, #0x04
102214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimablock_count_rounded:
102224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  bx, bx   ;; Restore DS back to 0000:
102244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx
102254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax       ;; Save AX
102264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push di       ;; Save DI
102274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Push addr of ROM entry point
102284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push cx       ;; Push seg
102294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push #0x0003  ;; Push offset
102304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
102324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; That should stop it grabbing INT 19h; we will use its BEV instead.
102334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xf000
102344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  es, ax
102354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lea  di, pnp_string
102364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp   ;; Call ROM init routine using seg:off on stack
102384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db   0xff     ;; call_far ss:[bp+0]
102394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db   0x5e
102404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db   0
102414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli           ;; In case expansion ROM BIOS turns IF on
102424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  sp, #2   ;; Pop offset value
102434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  cx       ;; Pop seg value (restore CX)
102444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Look at the ROM's PnP Expansion header.  Properly, we're supposed
102464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; to init all the ROMs and then go back and build an IPL table of
102474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; all the bootable devices, but we can get away with one pass.
102484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, cx       ;; ROM base
102494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, 0x001a   ;; 0x1A is the offset into ROM header that contains...
102504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, [bx]     ;; the offset of PnP expansion header, where...
102514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, #0x5024  ;; we look for signature "$PnP"
102524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  no_bev
102534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, 2[bx]
102544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, #0x506e
102554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  no_bev
102564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, 0x16[bx] ;; 0x16 is the offset of Boot Connection Vector
102584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, #0x0000
102594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   no_bcv
102604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Option ROM has BCV. Run it now.
102624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push cx       ;; Push seg
102634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax       ;; Push offset
102644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
102664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0xf000
102674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  es, bx
102684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  lea  di, pnp_string
102694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* jump to BCV function entry pointer */
102704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp   ;; Call ROM BCV routine using seg:off on stack
102714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db   0xff     ;; call_far ss:[bp+0]
102724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db   0x5e
102734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  db   0
102744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli           ;; In case expansion ROM BIOS turns IF on
102754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  sp, #2   ;; Pop offset value
102764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  cx       ;; Pop seg value (restore CX)
102774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp   no_bev
102784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimano_bcv:
102804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
102814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ax, #0x0000  ;; the Bootstrap Entry Vector, or zero if there is none.
102824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   no_bev
102834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
102844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Found a device that thinks it can boot the system.  Record its BEV and product name string.
102854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  di, 0x10[bx]            ;; Pointer to the product name string or zero if none
102864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #IPL_SEG            ;; Go to the segment where the IPL table lives
102874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx
102884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, IPL_COUNT_OFFSET    ;; Read the number of entries so far
102894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  bx, #IPL_TABLE_ENTRIES
102904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   no_bev                  ;; Get out if the table is full
102914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl  bx, #0x4                ;; Turn count into offset (entries are 16 bytes)
102924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0[bx], #IPL_TYPE_BEV    ;; This entry is a BEV device
102934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  6[bx], cx               ;; Build a far pointer from the segment...
102944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  4[bx], ax               ;; and the offset
102954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  di, #0x0000
102964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   no_prod_str
102974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0xA[bx], cx             ;; Build a far pointer from the segment...
102984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  8[bx], di               ;; and the offset
102994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimano_prod_str:
103004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shr  bx, #0x4                ;; Turn the offset back into a count
103014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc  bx                      ;; We have one more entry now
103024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  IPL_COUNT_OFFSET, bx    ;; Remember that.
103034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimano_bev:
103054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  di       ;; Restore DI
103064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ax       ;; Restore AX
103074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarom_scan_increment:
103084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl  ax, #5   ;; convert 512-bytes blocks to 16-byte increments
103094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                ;; because the segment selector is shifted left 4 bits.
103104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  cx, ax
103114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ax       ;; Restore AX
103124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  cx, ax
103134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jbe  rom_scan_loop
103144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax   ;; Restore DS back to 0000:
103164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
103174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
103184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_init_pic:
103204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x11 ; send initialisation commands
103214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x20, al
103224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xa0, al
103234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x08
103244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x21, al
103254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x70
103264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xa1, al
103274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x04
103284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x21, al
103294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x02
103304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xa1, al
103314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x01
103324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x21, al
103334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xa1, al
103344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0xb8
103354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  0x21, AL ;master pic: unmask IRQ 0, 1, 2, 6
103364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_PS2_MOUSE
103374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x8f
103384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
103394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x9f
103404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
103414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  0xa1, AL ;slave  pic: unmask IRQ 12, 13, 14
103424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ret
103434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; the following area can be used to write dynamically generated tables
103454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  .align 16
103464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabios_table_area_start:
103474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dd 0xaafb4442
103484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dd bios_table_area_end - bios_table_area_start - 8;
103494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------
103514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- POST -
103524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;--------
103534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe05b ; POST Entry Point
103544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost:
103554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
103574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; first reset the DMA controllers
103594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x0d,al
103604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xda,al
103614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; then initialize the DMA controllers
103634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0xC0
103644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xD6, al ; cascade mode of channel 4 enabled
103654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x00
103664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0xD4, al ; unmask channel 4
103674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Examine CMOS shutdown status.
103694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov AL, #0x0f
103704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x70, AL
103714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  AL, 0x71
103724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; backup status
103744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov bl, al
103754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Reset CMOS shutdown status.
103774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov AL, #0x0f
103784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x70, AL          ; select CMOS register Fh
103794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov AL, #0x00
103804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x71, AL          ; set shutdown action to normal
103814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Examine CMOS shutdown status.
103834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, bl
103844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x00, 0x09, 0x0D+ = normal startup
103864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp AL, #0x00
103874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz normal_post
103884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp AL, #0x0d
103894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jae normal_post
103904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp AL, #0x09
103914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je normal_post
103924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x05 = eoi + jmp via [0x40:0x67] jump
103944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x05
103954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  eoi_jmp_post
103964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
103974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x0A = jmp via [0x40:0x67] jump
103984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0a
103994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  jmp_post_0x467
104004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x0B = iret via [0x40:0x67]
104024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0b
104034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  iret_post_0x467
104044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; 0x0C = retf via [0x40:0x67]
104064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp al, #0x0c
104074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je  retf_post_0x467
104084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Examine CMOS shutdown status.
104104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;  0x01,0x02,0x03,0x04,0x06,0x07,0x08 = Unimplemented shutdown status.
104114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bx
104124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _shutdown_status_panic
104134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
104154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  HALT(__LINE__)
104164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;
104174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;#if 0
104184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;  0xb0, 0x20,       /* mov al, #0x20 */
104194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;  0xe6, 0x20,       /* out 0x20, al    ;send EOI to PIC */
104204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;#endif
104214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;
104224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop es
104234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
104244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
104254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
104264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
104274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanormal_post:
104294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ; case 0: normal startup
104304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
104324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xfffe
104334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  sp, ax
104344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
104354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
104364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ss, ax
104374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Save shutdown status
104394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov 0x04b0, bl
104404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp bl, #0xfe
104424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz s3_post
104434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; zero out BIOS data area (40:00..40:ff)
104454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  es, ax
104464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, #0x0080 ;; 128 words
104474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  di, #0x0400
104484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cld
104494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  rep
104504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    stosw
104514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _log_bios_start
104534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; set all interrupts to default handler
104554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  bx, bx         ;; offset index
104564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, #0x0100    ;; counter (256 interrupts)
104574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #dummy_iret_handler
104584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0xF000
104594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapost_default_ints:
104614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bx], ax
104624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  bx, #2
104634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  [bx], dx
104644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  add  bx, #2
104654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  loop post_default_ints
104664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; set vector 0x79 to zero
104684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; this is used by 'gardian angel' protection system
104694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x79, #0, #0)
104704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; base memory in K 40:13 (word)
104724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #BASE_MEM_IN_K
104734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0413, ax
104744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Manufacturing Test 40:12
104774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   zerod out above
104784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Warm Boot Flag 0040:0072
104804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   value of 1234h = skip memory checks
104814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;   zerod out above
104824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Printer Services vector
104854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x17, #0xF000, #int17_handler)
104864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Bootstrap failure vector
104884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x18, #0xF000, #int18_handler)
104894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Bootstrap Loader vector
104914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x19, #0xF000, #int19_handler)
104924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; User Timer Tick vector
104944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x1c, #0xF000, #int1c_handler)
104954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Memory Size Check vector
104974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x12, #0xF000, #int12_handler)
104984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
104994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Equipment Configuration Check vector
105004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x11, #0xF000, #int11_handler)
105014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; System Services
105034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x15, #0xF000, #int15_handler)
105044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; EBDA setup
105064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call ebda_post
105074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; PIT setup
105094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x08, #0xF000, #int08_handler)
105104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; int 1C already points at dummy_iret_handler (above)
105114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x34 ; timer0: binary count, 16bit count, mode 2
105124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x43, al
105134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x00 ; maximum count of 0000H = 18.2Hz
105144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x40, al
105154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out 0x40, al
105164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Keyboard
105184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x09, #0xF000, #int09_handler)
105194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x16, #0xF000, #int16_handler)
105204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
105224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
105234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0417, al /* keyboard shift flags, set 1 */
105244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0418, al /* keyboard shift flags, set 2 */
105254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0419, al /* keyboard alt-numpad work area */
105264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0471, al /* keyboard ctrl-break flag */
105274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0497, al /* keyboard status flags 4 */
105284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x10
105294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0496, al /* keyboard status flags 3 */
105304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* keyboard head of buffer pointer */
105334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0x001E
105344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x041A, bx
105354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* keyboard end of buffer pointer */
105374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x041C, bx
105384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* keyboard pointer to start of buffer */
105404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0x001E
105414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0480, bx
105424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* keyboard pointer to end of buffer */
105444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0x003E
105454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0482, bx
105464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  /* init the keyboard */
105484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _keyboard_init
105494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; mov CMOS Equipment Byte to BDA Equipment Word
105514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, 0x0410
105524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x14
105534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  0x70, al
105544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, 0x71
105554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0410, ax
105564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Parallel setup
105594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x0F, #0xF000, #dummy_iret_handler)
105604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
105614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
105624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor bx, bx
105634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cl, #0x14 ; timeout value
105644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x378 ; Parallel I/O address, port 1
105654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call detect_parport
105664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x278 ; Parallel I/O address, port 2
105674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call detect_parport
105684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl bx, #0x0e
105694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, 0x410   ; Equipment word bits 14..15 determing # parallel ports
105704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and ax, #0x3fff
105714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or  ax, bx ; set number of parallel ports
105724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov 0x410, ax
105734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Serial setup
105754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x0C, #0xF000, #dummy_iret_handler)
105764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x14, #0xF000, #int14_handler)
105774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor bx, bx
105784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov cl, #0x0a ; timeout value
105794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x03f8 ; Serial I/O address, port 1
105804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call detect_serial
105814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x02f8 ; Serial I/O address, port 2
105824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call detect_serial
105834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x03e8 ; Serial I/O address, port 3
105844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call detect_serial
105854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov dx, #0x02e8 ; Serial I/O address, port 4
105864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call detect_serial
105874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  shl bx, #0x09
105884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, 0x410   ; Equipment word bits 9..11 determing # serial ports
105894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and ax, #0xf1ff
105904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or  ax, bx ; set number of serial port
105914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov 0x410, ax
105924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
105934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; CMOS RTC
105944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x1A, #0xF000, #int1a_handler)
105954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x4A, #0xF000, #dummy_iret_handler)
105964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x70, #0xF000, #int70_handler)
105974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; BIOS DATA AREA 0x4CE ???
105984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call timer_tick_post
105994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; PS/2 mouse setup
106014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x74, #0xF000, #int74_handler)
106024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; IRQ13 (FPU exception) setup
106044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x75, #0xF000, #int75_handler)
106054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Video setup
106074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  SET_INT_VECTOR(0x10, #0xF000, #int10_handler)
106084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; PIC
106104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call post_init_pic
106114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, #0xc000  ;; init vga bios
106134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xc780
106144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call rom_scan
106154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _print_bios_banner
106174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ROMBIOS32
106194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call rombios32_init
106204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#else
106214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_PCIBIOS
106224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_iomem_bases
106234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_init_irqs
106244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif //BX_PCIBIOS
106254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
106264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Floppy setup
106294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call floppy_drive_post
106314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; Hard Drive setup
106344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call hard_drive_post
106364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_ATADRV
106384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; ATA/ATAPI driver setup
106414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _ata_init
106434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _ata_detect
106444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_USE_ATADRV
106474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
106494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; eltorito floppy/harddisk emulation from cd
106514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _cdemu_init
106534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;;
106544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
106554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _init_boot_vectors
106574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  cx, #0xc800  ;; init option roms
106594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0xe000
106604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call rom_scan
106614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_ELTORITO_BOOT
106634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _interactive_bootkey
106644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif // BX_ELTORITO_BOOT
106654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti        ;; enable interrupts
106674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  #0x19
106684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe2c3 ; NMI Handler Entry Point
106704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimanmi:
106714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; FIXME the NMI handler should not panic
106724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; but iret when called from int75 (fpu exception)
106734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _nmi_handler_msg
106744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
106754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint75_handler:
106774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  0xf0, al         // clear irq13
106784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eoi_both_pics    // clear interrupt
106794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  2                // legacy nmi call
106804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
106814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;-------------------------------------------
106834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT 13h Fixed Disk Services Entry Point -
106844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;-------------------------------------------
106854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe3fe ; INT 13h Fixed Disk Services Entry Point
106864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_handler:
106874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //JMPL(int13_relocated)
106884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int13_relocated
106894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe401 ; Fixed Disk Parameter Table
106914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
106934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT19h -
106944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
106954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe6f2 ; INT 19h Boot Load Service Entry Point
106964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint19_handler:
106974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
106984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int19_relocated
106994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;-------------------------------------------
107004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- System BIOS Configuration Data Table
107014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;-------------------------------------------
107024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org BIOS_CONFIG_TABLE
107034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x08                  ; Table size (bytes) -Lo
107044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x00                  ; Table size (bytes) -Hi
107054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb SYS_MODEL_ID
107064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb SYS_SUBMODEL_ID
107074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb BIOS_REVISION
107084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; Feature byte 1
107094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b7: 1=DMA channel 3 used by hard disk
107104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b6: 1=2 interrupt controllers present
107114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b5: 1=RTC present
107124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b4: 1=BIOS calls int 15h/4Fh every key
107134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b3: 1=wait for extern event supported (Int 15h/41h)
107144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b2: 1=extended BIOS data area used
107154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b1: 0=AT or ESDI bus, 1=MicroChannel
107164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b0: 1=Dual bus (MicroChannel + ISA)
107174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb (0 << 7) | \
107184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (1 << 6) | \
107194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (1 << 5) | \
107204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (BX_CALL_INT15_4F << 4) | \
107214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 3) | \
107224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (BX_USE_EBDA << 2) | \
107234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 1) | \
107244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 0)
107254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; Feature byte 2
107264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b7: 1=32-bit DMA supported
107274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b6: 1=int16h, function 9 supported
107284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b5: 1=int15h/C6h (get POS data) supported
107294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b4: 1=int15h/C7h (get mem map info) supported
107304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b3: 1=int15h/C8h (en/dis CPU) supported
107314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b2: 1=non-8042 kb controller
107324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b1: 1=data streaming supported
107334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b0: reserved
107344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb (0 << 7) | \
107354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (1 << 6) | \
107364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 5) | \
107374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 4) | \
107384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 3) | \
107394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 2) | \
107404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 1) | \
107414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima   (0 << 0)
107424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; Feature byte 3
107434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b7: not used
107444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b6: reserved
107454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b5: reserved
107464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b4: POST supports ROM-to-RAM enable/disable
107474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b3: SCSI on system board
107484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b2: info panel installed
107494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b1: Initial Machine Load (IML) system - BIOS on disk
107504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b0: SCSI supported in IML
107514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x00
107524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; Feature byte 4
107534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b7: IBM private
107544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b6: EEPROM present
107554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b5-3: ABIOS presence (011 = not supported)
107564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b2: private
107574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b1: memory split above 16Mb supported
107584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b0: POSTEXT directly supported by POST
107594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x00
107604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; Feature byte 5 (IBM)
107614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b1: enhanced mouse
107624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; b0: flash EPROM
107634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x00
107644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe729 ; Baud Rate Generator Table
107684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
107704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT14h -
107714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
107724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe739 ; INT 14h Serial Communications Service Entry Point
107734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint14_handler:
107744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
107754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
107764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
107774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
107784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int14_function
107794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
107804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
107814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
107824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------------------------
107854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT 16h Keyboard Service Entry Point -
107864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------------------------
107874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe82e
107884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_handler:
107894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
107914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
107924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushf
107934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
107944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
107954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   ah, #0x00
107964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je    int16_F00
107974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp   ah, #0x10
107984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je    int16_F00
107994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0xf000
108014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx
108024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int16_function
108034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
108044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popf
108054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
108064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   int16_zero_set
108074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_zero_clear:
108094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
108104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
108114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //SEG SS
108124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  BYTE [bp + 0x06], #0xbf
108134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
108144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
108154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_zero_set:
108174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push bp
108184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bp, sp
108194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //SEG SS
108204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   BYTE [bp + 0x06], #0x40
108214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  bp
108224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
108234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_F00:
108254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0x0040
108264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx
108274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_wait_for_key:
108294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
108304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, 0x001a
108314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  bx, 0x001c
108324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  int16_key_found
108334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
108344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  nop
108354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
108364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                           /* no key yet, call int 15h, function AX=9002 */
108374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0x50,                    /* push AX */
108384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0xb8, 0x02, 0x90,        /* mov AX, #0x9002 */
108394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0xcd, 0x15,              /* int 15h */
108404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0x58,                    /* pop  AX */
108414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0xeb, 0xea,              /* jmp   WAIT_FOR_KEY */
108424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
108434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp  int16_wait_for_key
108444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint16_key_found:
108464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bx, #0xf000
108474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, bx
108484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int16_function
108494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
108504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popf
108514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
108524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if 0
108534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima                           /* notify int16 complete w/ int 15h, function AX=9102 */
108544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0x50,                    /* push AX */
108554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0xb8, 0x02, 0x91,        /* mov AX, #0x9102 */
108564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0xcd, 0x15,              /* int 15h */
108574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  0x58,                    /* pop  AX */
108584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
108594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
108604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;-------------------------------------------------
108644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT09h : Keyboard Hardware Service Entry Point -
108654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;-------------------------------------------------
108664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xe987
108674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint09_handler:
108684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
108694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
108704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0xAD      ;;disable keyboard
108724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out #0x64, al
108734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0x0B
108754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out #0x20, al
108764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  al, #0x20
108774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and al, #0x02
108784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz  int09_finish
108794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in  al, #0x60             ;;read key from keyboard controller
108814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
108824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
108834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
108844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#ifdef BX_CALL_INT15_4F
108854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, #0x4f     ;; allow for keyboard intercept
108864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  stc
108874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int  #0x15
108884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnc  int09_done
108894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
108904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
108914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; check for extended key
108924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xe0
108934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne int09_check_pause
108944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
108954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
108964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, BYTE [0x496]     ;; mf2_state |= 0x02
108974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al, #0x02
108984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  BYTE [0x496], al
108994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int09_done
109004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint09_check_pause: ;; check for pause key
109024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xe1
109034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne int09_process_key
109044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
109054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
109064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, BYTE [0x496]     ;; mf2_state |= 0x01
109074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al, #0x01
109084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  BYTE [0x496], al
109094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int09_done
109104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint09_process_key:
109124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   bx, #0xf000
109134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov   ds, bx
109144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call  _int09_function
109154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint09_done:
109174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
109184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ds
109194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
109204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eoi_master_pic
109214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint09_finish:
109234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov al, #0xAE      ;;enable keyboard
109244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out #0x64, al
109254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ax
109264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
109274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------------------------
109304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT 13h Diskette Service Entry Point -
109314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------------------------
109324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xec59
109334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint13_diskette:
109344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int13_noeltorito
109354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;---------------------------------------------
109374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT 0Eh Diskette Hardware ISR Entry Point -
109384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;---------------------------------------------
109394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xef57 ; INT 0Eh Diskette Hardware ISR Entry Point
109404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint0e_handler:
109414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ax
109424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
109434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x03f4
109444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
109454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xc0
109464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xc0
109474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je   int0e_normal
109484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x03f5
109494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, #0x08 ; sense interrupt status
109504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx, al
109514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint0e_loop1:
109524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x03f4
109534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
109544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xc0
109554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xc0
109564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  int0e_loop1
109574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint0e_loop2:
109584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x03f5
109594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
109604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx, #0x03f4
109614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al, dx
109624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al, #0xc0
109634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  al, #0xc0
109644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je int0e_loop2
109654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint0e_normal:
109664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
109674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax ;; segment 0000
109684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
109694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eoi_master_pic
109704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al, 0x043e
109714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al, #0x80 ;; diskette interrupt has occurred
109724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x043e, al
109734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
109744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  dx
109754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ax
109764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
109774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xefc7 ; Diskette Controller Parameter Table
109804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadiskette_param_table:
109814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  Since no provisions are made for multiple drive types, most
109824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  values in this table are ignored.  I set parameters for 1.44M
109834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  floppy here
109844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0xAF
109854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x02 ;; head load time 0000001, DMA used
109864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x25
109874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x02
109884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb    18
109894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x1B
109904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0xFF
109914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x6C
109924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0xF6
109934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x0F
109944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x08
109954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
109974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------------------------
109984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT17h : Printer Service Entry Point -
109994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------------------------------------
110004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xefd2
110014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint17_handler:
110024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
110034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
110044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
110054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
110064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int17_function
110074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
110084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
110094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
110104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadiskette_param_table2:
110124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  New diskette parameter table adding 3 parameters from IBM
110134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  Since no provisions are made for multiple drive types, most
110144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  values in this table are ignored.  I set parameters for 1.44M
110154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;  floppy here
110164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0xAF
110174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x02 ;; head load time 0000001, DMA used
110184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x25
110194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x02
110204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb    18
110214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x1B
110224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0xFF
110234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x6C
110244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0xF6
110254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x0F
110264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb  0x08
110274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb    79 ;; maximum track
110284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb     0 ;; data transfer rate
110294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb     4 ;; drive type in cmos
110304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xf045 ; INT 10 Functions 0-Fh Entry Point
110324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  HALT(__LINE__)
110334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
110344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT10h -
110374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xf065 ; INT 10h Video Support Service Entry Point
110394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint10_handler:
110404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; dont do anything, since the VGA BIOS handles int10h requests
110414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
110424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xf0a4 ; MDA/CGA Video Parameter Table (INT 1Dh)
110444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT12h -
110474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xf841 ; INT 12h Memory Size Service Entry Point
110494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima; ??? different for Pentium (machine check)?
110504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint12_handler:
110514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
110524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x0040
110534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
110544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, 0x0013
110554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
110564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
110574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT11h -
110604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xf84d ; INT 11h Equipment List Service Entry Point
110624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint11_handler:
110634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
110644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, #0x0040
110654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
110664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ax, 0x0010
110674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
110684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
110694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
110704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT15h -
110724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
110734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xf859 ; INT 15h System Services Entry Point
110744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_handler:
110754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushf
110764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_APM
110774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp ah, #0x53
110784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je apm_call
110794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
110804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  ds
110814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push  es
110824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ah, #0x86
110834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je int15_handler32
110844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ah, #0xE8
110854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je int15_handler32
110864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
110874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_PS2_MOUSE
110884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ah, #0xC2
110894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  je int15_handler_mouse
110904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
110914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int15_function
110924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_handler_mouse_ret:
110934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
110944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_handler32_ret:
110954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   es
110964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop   ds
110974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popf
110984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp iret_modify_cf
110994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_APM
111004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaapm_call:
111014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp _apmreal_entry
111024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
111034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_USE_PS2_MOUSE
111054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_handler_mouse:
111064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int15_function_mouse
111074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int15_handler_mouse_ret
111084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
111094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint15_handler32:
111114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushad
111124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int15_function32
111134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popad
111144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int15_handler32_ret
111154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; Protected mode IDT descriptor
111174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;
111184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; I just make the limit 0, so the machine will shutdown
111194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; if an exception occurs during protected mode memory
111204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; transfers.
111214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;
111224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; Set base to f0000 to correspond to beginning of BIOS,
111234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; in case I actually define an IDT later
111244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; Set limit to 0
111254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapmode_IDT_info:
111274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadw 0x0000  ;; limit 15:00
111284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadw 0x0000  ;; base  15:00
111294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x0f    ;; base  23:16
111304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; Real mode IDT descriptor
111324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;
111334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; Set to typical real-mode values.
111344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; base  = 000000
111354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; limit =   03ff
111364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimarmode_IDT_info:
111384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadw 0x03ff  ;; limit 15:00
111394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadw 0x0000  ;; base  15:00
111404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x00    ;; base  23:16
111414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
111444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT1Ah -
111454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;----------
111464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfe6e ; INT 1Ah Time-of-day Service Entry Point
111474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1a_handler:
111484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#if BX_PCIBIOS
111494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp  ah, #0xb1
111504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jne  int1a_normal
111514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call pcibios_real
111524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jc   pcibios_error
111534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  retf 2
111544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimapcibios_error:
111554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  bl, ah
111564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ah, #0xb1
111574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
111584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
111594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ax, ss  ; set readable descriptor to ds, for calling pcibios
111604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax  ;  on 16bit protected mode.
111614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp int1a_callfunction
111624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1a_normal:
111634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#endif
111644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
111654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pusha
111664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
111674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
111684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint1a_callfunction:
111694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int1a_function
111704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popa
111714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
111724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
111734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;
111754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;; int70h: IRQ8 - CMOS RTC
111764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;;
111774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint70_handler:
111784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
111794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pushad
111804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor  ax, ax
111814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  ds, ax
111824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call _int70_function
111834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  popad
111844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  ds
111854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
111864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;---------
111884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- INT08 -
111894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;---------
111904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfea5 ; INT 08h System Timer ISR Entry Point
111914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint08_handler:
111924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sti
111934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push eax
111944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push ds
111954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor ax, ax
111964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov ds, ax
111974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
111984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; time to turn off drive(s)?
111994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  al,0x0440
112004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  or   al,al
112014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jz   int08_floppy_off
112024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  dec  al
112034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  0x0440,al
112044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jnz  int08_floppy_off
112054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; turn motor(s) off
112064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  push dx
112074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov  dx,#0x03f2
112084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  in   al,dx
112094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  and  al,#0xcf
112104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  out  dx,al
112114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop  dx
112124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint08_floppy_off:
112134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov eax, 0x046c ;; get ticks dword
112154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc eax
112164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; compare eax to one days worth of timer ticks at 18.2 hz
112184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cmp eax, #0x001800B0
112194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jb  int08_store_ticks
112204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; there has been a midnight rollover at this point
112214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  xor eax, eax    ;; zero out counter
112224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  inc BYTE 0x0470 ;; increment rollover flag
112234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint08_store_ticks:
112254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  mov 0x046c, eax ;; store new ticks dword
112264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  ;; chain to user timer tick INT #0x1c
112274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //pushf
112284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //;; call_ep [ds:loc]
112294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  //CALL_EP( 0x1c << 2 )
112304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int #0x1c
112314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  cli
112324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  call eoi_master_pic
112334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop ds
112344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pop eax
112354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
112364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfef3 ; Initial Interrupt Vector Offsets Loaded by POST
112384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xff00
112414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.ascii BIOS_COPYRIGHT_STRING
112424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;------------------------------------------------
112444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;- IRET Instruction for Dummy Interrupt Handler -
112454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima;------------------------------------------------
112464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xff53 ; IRET Instruction for Dummy Interrupt Handler
112474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadummy_iret_handler:
112484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
112494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xff54 ; INT 05h Print Screen Service Entry Point
112514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  HALT(__LINE__)
112524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  iret
112534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfff0 ; Power-up Entry Point
112554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  jmp 0xf000:post
112564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
112584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.ascii BIOS_BUILD_DATE
112594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfffe ; System Model ID
112614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb SYS_MODEL_ID
112624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimadb 0x00   ; filler
112634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
112644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xfa6e ;; Character Font for 320x200 & 640x200 Graphics (lower 128 characters)
112654d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
112664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/*
112674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * This font comes from the fntcol16.zip package (c) by  Joseph Gil
112684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * found at ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
112694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * This font is public domain
112704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima */
112714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic Bit8u vgafont8[128*8]=
112724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
112734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
112754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,
112764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
112774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00,
112784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
112794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c,
112804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
112814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,
112824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
112834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff,
112844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
112854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,
112864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
112874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0,
112884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
112894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00,
112904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
112914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18,
112924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
112934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00,
112944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
112954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00,
112964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
112974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00,
112984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
112994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00,
113004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
113014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00,
113024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
113034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00,
113044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
113054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
113074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
113084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
113094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,
113104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
113114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00,
113124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
113134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
113144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
113154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
113164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
113174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
113184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
113194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
113204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
113214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00,
113224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
113234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00,
113244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
113254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00,
113264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
113274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00,
113284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
113294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00,
113304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
113314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
113324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
113334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00,
113344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
113354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00,
113364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
113374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00,
113384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
113394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00,
113404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
113414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00,
113424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
113434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00,
113444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
113454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00,
113464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
113474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00,
113484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
113494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00,
113504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
113514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00,
113524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
113534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
113544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
113554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00,
113564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
113574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
113584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
113594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
113604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
113614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00,
113624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
113634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00,
113644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
113654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00,
113664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
113674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
113684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
113694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
113704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
113714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00,
113724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
113734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00,
113744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
113754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00,
113764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
113774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00,
113784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
113794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78,
113804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
113814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
113824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
113834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
113844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
113854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0,
113864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
113874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00,
113884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
113894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00,
113904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
113914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
113924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
113934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00,
113944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
113954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00,
113964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
113974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
113984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
113994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
114014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima};
114024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
114034d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_START
114044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima.org 0xcc00
114054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabios_table_area_end:
114064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// bcc-generated data will be placed here
114074d07f569799aaae0d7fccf8e76386d450664987fJun NakajimaASM_END
11408