2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright 1993 NeXT Computer, Inc.
26 * All rights reserved.
32 unsigned char uses_ebios
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
42 int readKeyboardStatus(void)
54 int readKeyboardShiftFlags(void)
62 unsigned int time18(void)
75 time
.s
.low
= bb
.edx
.rr
;
76 time
.s
.high
= bb
.ecx
.rr
;
80 int memsize(int which
)
86 // Get the total system memory discovered by the
90 size
= (bb
.edx
.rr
<< 16) | bb
.eax
.rr
;
92 // Convert to extended memory size.
94 size
= ( size
> 1024 ) ? size
- 1024 : 0;
98 // Get amount of conventional memory available.
107 void video_mode(int mode
)
115 int biosread(int dev
, int cyl
, int head
, int sec
, int num
)
120 sec
+= 1; /* sector numbers start at 1 */
124 bb
.ecx
.r
.l
= ((cyl
& 0x300) >> 2) | (sec
& 0x3F);
128 bb
.ebx
.rr
= OFFSET(ptov(BIOS_ADDR
));
129 bb
.es
= SEGMENT(ptov(BIOS_ADDR
));
134 if ((bb
.eax
.r
.h
== 0x00) || (i
++ >= 5))
137 /* reset disk subsystem and try again */
144 int ebiosread(int dev
, long sec
, int count
)
149 unsigned char reserved
;
150 unsigned char numblocks
;
151 unsigned char reserved2
;
152 unsigned short bufferOffset
;
153 unsigned short bufferSegment
;
154 unsigned long long startblock
;
156 addrpacket
.size
= sizeof(addrpacket
);
162 bb
.esi
.rr
= OFFSET((unsigned)&addrpacket
);
163 bb
.ds
= SEGMENT((unsigned)&addrpacket
);
164 addrpacket
.reserved
= addrpacket
.reserved2
= 0;
165 addrpacket
.numblocks
= count
;
166 addrpacket
.bufferOffset
= OFFSET(ptov(BIOS_ADDR
));
167 addrpacket
.bufferSegment
= SEGMENT(ptov(BIOS_ADDR
));
168 addrpacket
.startblock
= sec
;
170 if ((bb
.eax
.r
.h
== 0x00) || (i
++ >= 5))
173 /* reset disk subsystem and try again */
183 bb
.ebx
.r
.h
= 0x00; /* background black */
184 bb
.ebx
.r
.l
= 0x0F; /* foreground white */
190 void putca(int ch
, int attr
, int repeat
)
193 bb
.ebx
.r
.h
= 0x00; /* page number */
194 bb
.ebx
.r
.l
= attr
; /* attribute */
197 bb
.ecx
.rx
= repeat
; /* repeat count */
201 unsigned int get_diskinfo(int drive
)
205 unsigned short flags
;
206 unsigned long cylinders
;
208 unsigned long sectors
;
209 unsigned long long total_sectors
;
211 unsigned long params_p
;
213 unsigned char useEbios
= 0;
216 compact_diskinfo_t di
;
219 static int maxhd
= 0;
227 if (bb
.flags
.cf
== 0)
228 maxhd
= 0x7f + bb
.edx
.r
.l
;
234 /* Check drive for EBIOS support. */
240 if(bb
.ebx
.rr
== 0xaa55 && bb
.flags
.cf
== 0) {
241 /* Get flags for supported operations. */
242 useEbios
= bb
.ecx
.r
.l
;
245 if (useEbios
& EBIOS_ENHANCED_DRIVE_INFO
) {
246 /* Get EBIOS drive info. */
251 bb
.esi
.rr
= OFFSET((unsigned)&ebios
);
252 bb
.ds
= SEGMENT((unsigned)&ebios
);
254 if(bb
.flags
.cf
!= 0) {
263 if (bb
.flags
.cf
== 0 && bb
.eax
.r
.h
== 0) {
269 sec
= bb
.ecx
.r
.l
& 0x3F;
270 if(useEbios
& EBIOS_ENHANCED_DRIVE_INFO
) {
271 cyl
= (ebios
.total_sectors
/ ((hds
+ 1) * sec
)) - 1;
274 cyl
= bb
.ecx
.r
.h
| ((bb
.ecx
.r
.l
& 0xC0) << 2);
277 ret
.di
.sectors
= sec
;
278 ret
.di
.cylinders
= cyl
;
280 if(drive
>= 0x80) uses_ebios
[drive
- 0x80] = useEbios
;
284 void setCursorPosition(int x
, int y
, int page
)
288 bb
.ebx
.r
.h
= page
; /* page 0 for graphics */
294 void setCursorType(int type
)
302 void getCursorPositionAndType(int * x
, int * y
, int * type
)
312 void scollPage(int x1
, int y1
, int x2
, int y2
, int attr
, int rows
, int dir
)
315 bb
.eax
.r
.h
= (dir
> 0) ? 0x06 : 0x07;
325 void clearScreenRows( int y1
, int y2
)
327 scollPage( 0, y1
, 80 - 1, y2
, 0x07, y2
- y1
+ 1, 1 );
330 void setActiveDisplayPage( int page
)
340 int terminateDiskEmulation()
342 static char cd_spec
[0x12];
346 bb
.eax
.r
.l
= 0; // subfunc: terminate emulation
347 bb
.esi
.rr
= OFFSET((unsigned)&cd_spec
);
348 bb
.ds
= SEGMENT((unsigned)&cd_spec
);
353 int readDriveParameters(int drive
, struct driveParameters
*dp
)
359 if (bb
.eax
.r
.h
== 0) {
360 dp
->heads
= bb
.edx
.r
.h
;
361 dp
->sectors
= bb
.ecx
.r
.l
& 0x3F;
362 dp
->cylinders
= bb
.ecx
.r
.h
| ((bb
.ecx
.r
.l
& 0xC0) << 2);
363 dp
->totalDrives
= bb
.edx
.r
.l
;
365 bzero(dp
, sizeof(*dp
));
372 #define APM_INTNO 0x15
373 #define APM_INTCODE 0x53
378 KERNBOOTSTRUCT
*kbp
= kernBootStruct
;
380 bb
.intno
= APM_INTNO
;
381 bb
.eax
.r
.h
= APM_INTCODE
;
385 if ((bb
.flags
.cf
== 0) &&
386 (bb
.ebx
.r
.h
== 'P') &&
387 (bb
.ebx
.r
.l
== 'M')) {
389 kbp
->apmConfig
.major_vers
= bb
.eax
.r
.h
;
390 kbp
->apmConfig
.minor_vers
= bb
.eax
.r
.l
;
391 kbp
->apmConfig
.flags
.data
= bb
.ecx
.rr
;
400 KERNBOOTSTRUCT
*kbp
= kernBootStruct
;
402 bb
.intno
= APM_INTNO
;
403 bb
.eax
.r
.h
= APM_INTCODE
;
407 if (bb
.flags
.cf
== 0) {
409 kbp
->apmConfig
.cs32_base
= (bb
.eax
.rr
) << 4;
410 kbp
->apmConfig
.entry_offset
= bb
.ebx
.rx
;
411 kbp
->apmConfig
.cs16_base
= (bb
.ecx
.rr
) << 4;
412 kbp
->apmConfig
.ds_base
= (bb
.edx
.rr
) << 4;
413 if (kbp
->apmConfig
.major_vers
>= 1 &&
414 kbp
->apmConfig
.minor_vers
>= 1) {
415 kbp
->apmConfig
.cs_length
= bb
.esi
.rr
;
416 kbp
->apmConfig
.ds_length
= bb
.edi
.rr
;
418 kbp
->apmConfig
.cs_length
=
419 kbp
->apmConfig
.ds_length
= 64 * 1024;
421 kbp
->apmConfig
.connected
= 1;
437 if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
447 ReadEISASlotInfo(EISA_slot_info_t
*ep
, int slot
)
451 unsigned char char2h
:2;
452 unsigned char char1
:5;
453 unsigned char char3
:5;
454 unsigned char char2l
:3;
460 unsigned char data
[4];
462 static char hex
[0x10] = "0123456789ABCDEF";
472 ep
->u_ID
.d
= bb
.eax
.r
.l
;
473 ep
->configMajor
= bb
.ebx
.r
.h
;
474 ep
->configMinor
= bb
.ebx
.r
.l
;
475 ep
->checksum
= bb
.ecx
.rr
;
476 ep
->numFunctions
= bb
.edx
.r
.h
;
477 ep
->u_resources
.d
= bb
.edx
.r
.l
;
478 u
.data
[0] = bb
.edi
.r
.l
;
479 u
.data
[1] = bb
.edi
.r
.h
;
480 u
.data
[2] = bb
.esi
.r
.l
;
481 u
.data
[3] = bb
.esi
.r
.h
;
482 ep
->id
[0] = u
.s
.char1
+ ('A' - 1);
483 ep
->id
[1] = (u
.s
.char2l
| (u
.s
.char2h
<< 3)) + ('A' - 1);
484 ep
->id
[2] = u
.s
.char3
+ ('A' - 1);
485 ep
->id
[3] = hex
[u
.s
.d1
];
486 ep
->id
[4] = hex
[u
.s
.d2
];
487 ep
->id
[5] = hex
[u
.s
.d3
];
488 ep
->id
[6] = hex
[u
.s
.d4
];
494 * Note: ep must point to an address below 64k.
498 ReadEISAFuncInfo(EISA_func_info_t
*ep
, int slot
, int function
)
504 bb
.ecx
.r
.h
= function
;
505 bb
.esi
.rr
= (unsigned int)ep
->data
;
507 if (bb
.eax
.r
.h
== 0) {
509 ep
->function
= function
;
513 #endif /* EISA_SUPPORT */
515 #define PCI_SIGNATURE 0x20494350 /* "PCI " */
518 ReadPCIBusInfo(PCI_bus_info_t
*pp
)
524 if ((bb
.eax
.r
.h
== 0) && (bb
.edx
.rx
== PCI_SIGNATURE
)) {
526 pp
->u_bus
.d
= bb
.eax
.r
.l
;
527 pp
->majorVersion
= bb
.ebx
.r
.h
;
528 pp
->minorVersion
= bb
.ebx
.r
.l
;
529 pp
->maxBusNum
= bb
.ecx
.r
.l
;