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