-
Notifications
You must be signed in to change notification settings - Fork 1
/
rombios.c
11845 lines (10335 loc) · 313 KB
/
rombios.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
// ROM BIOS compatibility entry points:
// ===================================
// $e05b ; POST Entry Point
// $e2c3 ; NMI Handler Entry Point
// $e3fe ; INT 13h Fixed Disk Services Entry Point
// $e401 ; Fixed Disk Parameter Table
// $e6f2 ; INT 19h Boot Load Service Entry Point
// $e6f5 ; Configuration Data Table
// $e729 ; Baud Rate Generator Table
// $e739 ; INT 14h Serial Communications Service Entry Point
// $e82e ; INT 16h Keyboard Service Entry Point
// $e987 ; INT 09h Keyboard Service Entry Point
// $ec59 ; INT 13h Diskette Service Entry Point
// $ef57 ; INT 0Eh Diskette Hardware ISR Entry Point
// $efc7 ; Diskette Controller Parameter Table
// $efd2 ; INT 17h Printer Service Entry Point
// $f045 ; INT 10 Functions 0-Fh Entry Point
// $f065 ; INT 10h Video Support Service Entry Point
// $f0a4 ; MDA/CGA Video Parameter Table (INT 1Dh)
// $f841 ; INT 12h Memory Size Service Entry Point
// $f84d ; INT 11h Equipment List Service Entry Point
// $f859 ; INT 15h System Services Entry Point
// $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters)
// $fe6e ; INT 1Ah Time-of-day Service Entry Point
// $fea5 ; INT 08h System Timer ISR Entry Point
// $fef3 ; Initial Interrupt Vector Offsets Loaded by POST
// $ff53 ; IRET Instruction for Dummy Interrupt Handler
// $ff54 ; INT 05h Print Screen Service Entry Point
// $fff0 ; Power-up Entry Point
// $fff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
// $fffe ; System Model ID
// NOTES for ATA/ATAPI driver (cbbochs@free.fr)
// Features
// - supports up to 4 ATA interfaces
// - device/geometry detection
// - 16bits/32bits device access
// - pchs/lba access
// - datain/dataout/packet command support
//
// NOTES for El-Torito Boot (cbbochs@free.fr)
// - CD-ROM booting is only available if ATA/ATAPI Driver is available
// - Current code is only able to boot mono-session cds
// - Current code can not boot and emulate a hard-disk
// the bios will panic otherwise
// - Current code also use memory in EBDA segment.
// - I used cmos byte 0x3D to store extended information on boot-device
// - Code has to be modified modified to handle multiple cdrom drives
// - Here are the cdrom boot failure codes:
// 1 : no atapi device found
// 2 : no atapi cdrom found
// 3 : can not read cd - BRVD
// 4 : cd is not eltorito (BRVD)
// 5 : cd is not eltorito (ISO TAG)
// 6 : cd is not eltorito (ELTORITO TAG)
// 7 : can not read cd - boot catalog
// 8 : boot catalog : bad header
// 9 : boot catalog : bad platform
// 10 : boot catalog : bad signature
// 11 : boot catalog : bootable flag not set
// 12 : can not read cd - boot image
//
// ATA driver
// - EBDA segment.
// I used memory starting at 0x121 in the segment
// - the translation policy is defined in cmos regs 0x39 & 0x3a
//
// TODO :
//
// int74
// - needs to be reworked. Uses direct [bp] offsets. (?)
//
// int13:
// - f04 (verify sectors) isn't complete (?)
// - f02/03/04 should set current cyl,etc in BDA (?)
// - rewrite int13_relocated & clean up int13 entry code
//
// NOTES:
// - NMI access (bit7 of addr written to 70h)
//
// ATA driver
// - should handle the "don't detect" bit (cmos regs 0x3b & 0x3c)
// - could send the multiple-sector read/write commands
//
// El-Torito
// - Emulate a Hard-disk (currently only diskette can be emulated) see "FIXME ElTorito Harddisk"
// - Implement remaining int13_cdemu functions (as defined by El-Torito specs)
// - cdrom drive is hardcoded to ide 0 device 1 in several places. see "FIXME ElTorito Hardcoded"
// - int13 Fix DL when emulating a cd. In that case DL is decremented before calling real int13.
// This is ok. But DL should be reincremented afterwards.
// - Fix all "FIXME ElTorito Various"
// - should be able to boot any cdrom instead of the first one
//
// BCC Bug: find a generic way to handle the bug of #asm after an "if" (fixed in 0.16.7)
#include "rombios.h"
// Sanity Checks
#if BX_CPU<3
# error Only 386+ cpu supported
#endif
#if BX_USE_ATADRV && !BX_USE_EBDA
# error ATA/ATAPI Driver can only be used if EBDA is available
#endif
#if BX_ELTORITO_BOOT && !BX_USE_ATADRV
# error El-Torito Boot can only be use if ATA/ATAPI Driver is available
#endif
// define this if you want to make PCIBIOS working on a specific bridge only
// undef enables PCIBIOS when at least one PCI device is found
// i440FX is emulated by Bochs and QEMU
#define PCI_FIXED_HOST_BRIDGE 0x12378086 ;; i440FX PCI bridge
#define PCI_FIXED_HOST_BRIDGE2 0x01228086 ;; i430FX PCI bridge
// #20 is dec 20
// #$20 is hex 20 = 32
// #0x20 is hex 20 = 32
// LDA #$20
// JSR $E820
// LDD .i,S
// JSR $C682
// mov al, #$20
// all hex literals should be prefixed with '0x'
// grep "#[0-9a-fA-F][0-9a-fA-F]" rombios.c
// no mov SEG-REG, #value, must mov register into seg-reg
// grep -i "mov[ ]*.s" rombios.c
// This is for compiling with gcc2 and gcc3
#define ASM_START #asm
#define ASM_END #endasm
// Added this to use data_segment based data
#define read_byte_DS(offset) *((Bit8u *)(offset))
#define read_word_DS(offset) *((Bit16u *)(offset))
#define read_dword_DS(offset) *((Bit32u *)(offset))
#define write_byte_DS(offset,data) *((Bit8u *)(offset)) = (data)
#define write_word_DS(offset,data) *((Bit16u *)(offset)) = (data)
#define write_dword_DS(offset,data) *((Bit32u *)(offset)) = (data)
// Added this to refer byte, word
#define LOBYTE(val) *((Bit8u *)&val)
#define HIBYTE(val) *(((Bit8u *)&val)+1)
#define LOWORD(val) *((Bit16u *)&val)
#define HIWORD(val) *(((Bit16u *)&val)+1)
ASM_START
.rom
.org 0x0000
use16 386
MACRO HALT
;; the HALT macro is called with the line number of the HALT call.
;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex
;; to print a BX_PANIC message. This will normally halt the simulation
;; with a message such as "BIOS panic at rombios.c, line 4091".
;; However, users can choose to make panics non-fatal and continue.
#if BX_VIRTUAL_PORTS
mov dx,#PANIC_PORT
mov ax,#?1
out dx,ax
#else
mov dx,#0x80
mov ax,#?1
out dx,al
#endif
MEND
MACRO JMP_AP
db 0xea
dw ?2
dw ?1
MEND
MACRO SET_INT_VECTOR
mov ax, ?3
mov ?1*4, ax
mov ax, ?2
mov ?1*4+2, ax
MEND
ASM_END
typedef unsigned char Bit8u;
typedef unsigned short Bit16u;
typedef unsigned short bx_bool;
typedef unsigned long Bit32u;
void _memsetb(value,offset,seg,count);
void _memcpyb(doffset,dseg,soffset,sseg,count);
void _memcpyd(doffset,dseg,soffset,sseg,count);
#define memsetb(seg,offset,value,count) _memsetb(value,offset,seg,count)
// memset of count bytes
void
_memsetb(value,offset,seg,count)
Bit16u value;
Bit16u offset;
Bit16u seg;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
push ax
push cx
push es
push di
mov cx, 10[bp] ; count
jcxz memsetb_end
les di, 6[bp] ; segment & offset
mov al, 4[bp] ; value
cld
rep
stosb
memsetb_end:
pop di
pop es
pop cx
pop ax
pop bp
ASM_END
}
#define memcpyb(dseg,doffset,sseg,soffset,count) _memcpyb(doffset,dseg,soffset,sseg,count)
// memcpy of count bytes
void
_memcpyb(doffset,dseg,soffset,sseg,count)
Bit16u doffset;
Bit16u dseg;
Bit16u soffset;
Bit16u sseg;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
push cx
push es
push di
push ds
push si
mov cx, 12[bp] ; count
jcxz memcpyb_end
les di, 4[bp] ; dsegment & doffset
lds si, 8[bp] ; ssegment & soffset
cld
rep
movsb
memcpyb_end:
pop si
pop ds
pop di
pop es
pop cx
pop bp
ASM_END
}
#define memcpyd(dseg,doffset,sseg,soffset,count) _memcpyd(doffset,dseg,soffset,sseg,count)
// memcpy of count dword
void
_memcpyd(doffset,dseg,soffset,sseg,count)
Bit16u doffset;
Bit16u dseg;
Bit16u soffset;
Bit16u sseg;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
push cx
push es
push di
push ds
push si
mov cx, 12[bp] ; count
jcxz memcpyd_end
les di, 4[bp] ; dsegment & doffset
lds si, 8[bp] ; ssegment & soffset
cld
rep
movsd
memcpyd_end:
pop si
pop ds
pop di
pop es
pop cx
pop bp
ASM_END
}
// read_dword and write_dword functions
static Bit32u _read_dword();
static void _write_dword();
static Bit32u read_dword_SS();
//static void write_dword_SS();
#define read_dword(seg, offset) _read_dword(offset, seg)
Bit32u
_read_dword(offset, seg)
Bit16u seg;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
push bx
push ds
lds bx, 4[bp] ; segment & offset
mov ax, [bx]
mov dx, 2[bx]
;; ax = return value (word)
;; dx = return value (word)
pop ds
pop bx
pop bp
ASM_END
}
#define write_dword(seg, offset, data) _write_dword(data, offset, seg)
void
_write_dword(data, offset, seg)
Bit32u data;
Bit16u offset;
Bit16u seg;
{
ASM_START
push bp
mov bp, sp
push eax
push bx
push ds
lds bx, 8[bp] ; segment & offset
mov eax, 4[bp] ; data dword
mov [bx], eax ; write data dword
pop ds
pop bx
pop eax
pop bp
ASM_END
}
Bit32u
read_dword_SS(offset)
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
mov bp, 4[bp] ; offset
mov ax, [bp]
mov dx, 2[bp]
;; ax = return value (word)
;; dx = return value (word)
pop bp
ASM_END
}
// Not currently used
#if 0
void
write_dword_SS(data, offset)
Bit32u data;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
push eax
mov eax, 4[bp] ; data word
mov bp, 8[bp] ; offset
mov [bp], eax ; write data dword
pop eax
pop bp
ASM_END
}
#endif
// Bit32u (unsigned long) and long helper functions
ASM_START
;; and function
landl:
landul:
SEG SS
and ax,[di]
SEG SS
and bx,2[di]
ret
;; add function
laddl:
laddul:
SEG SS
add ax,[di]
SEG SS
adc bx,2[di]
ret
;; cmp function
lcmpl:
lcmpul:
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
shr ebx, #16
SEG SS
cmp eax, dword ptr [di]
ret
;; sub function
lsubl:
lsubul:
SEG SS
sub ax,[di]
SEG SS
sbb bx,2[di]
ret
;; mul function
lmull:
lmulul:
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
SEG SS
mul eax, dword ptr [di]
mov ebx, eax
shr ebx, #16
ret
;; dec function
ldecl:
ldecul:
SEG SS
dec dword ptr [bx]
ret
;; or function
lorl:
lorul:
SEG SS
or ax,[di]
SEG SS
or bx,2[di]
ret
;; inc function
lincl:
lincul:
SEG SS
inc dword ptr [bx]
ret
;; tst function
ltstl:
ltstul:
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
shr ebx, #16
test eax, eax
ret
;; sr function
lsrul:
mov cx,di
jcxz lsr_exit
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
lsr_loop:
shr eax, #1
loop lsr_loop
mov ebx, eax
shr ebx, #16
lsr_exit:
ret
;; sl function
lsll:
lslul:
mov cx,di
jcxz lsl_exit
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
lsl_loop:
shl eax, #1
loop lsl_loop
mov ebx, eax
shr ebx, #16
lsl_exit:
ret
idiv_:
cwd
idiv bx
ret
idiv_u:
xor dx,dx
div bx
ret
ldivul:
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
xor edx, edx
SEG SS
mov bx, 2[di]
shl ebx, #16
SEG SS
mov bx, [di]
div ebx
mov ebx, eax
shr ebx, #16
ret
ASM_END
// for access to RAM area which is used by interrupt vectors
// and BIOS Data Area
typedef struct {
unsigned char filler1[0x400];
unsigned char filler2[0x6c];
Bit16u ticks_low;
Bit16u ticks_high;
Bit8u midnight_flag;
} bios_data_t;
#define BiosData ((bios_data_t *) 0)
#if BX_USE_ATADRV
typedef struct {
Bit16u heads; // # heads
Bit16u cylinders; // # cylinders
Bit16u spt; // # sectors / track
} chs_t;
// DPTE definition
typedef struct {
Bit16u iobase1;
Bit16u iobase2;
Bit8u prefix;
Bit8u unused;
Bit8u irq;
Bit8u blkcount;
Bit8u dma;
Bit8u pio;
Bit16u options;
Bit16u reserved;
Bit8u revision;
Bit8u checksum;
} dpte_t;
typedef struct {
Bit8u iface; // ISA or PCI
Bit16u iobase1; // IO Base 1
Bit16u iobase2; // IO Base 2
Bit8u irq; // IRQ
} ata_channel_t;
typedef struct {
Bit8u type; // Detected type of ata (ata/atapi/none/unknown)
Bit8u device; // Detected type of attached devices (hd/cd/none)
Bit8u removable; // Removable device flag
Bit8u lock; // Locks for removable devices
Bit8u mode; // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
Bit16u blksize; // block size
Bit8u translation; // type of translation
chs_t lchs; // Logical CHS
chs_t pchs; // Physical CHS
Bit32u sectors_low; // Total sectors count
Bit32u sectors_high;
} ata_device_t;
typedef struct {
// ATA channels info
ata_channel_t channels[BX_MAX_ATA_INTERFACES];
// ATA devices info
ata_device_t devices[BX_MAX_ATA_DEVICES];
//
// map between (bios hd id - 0x80) and ata channels
Bit8u hdcount, hdidmap[BX_MAX_ATA_DEVICES];
// map between (bios cd id - 0xE0) and ata channels
Bit8u cdcount, cdidmap[BX_MAX_ATA_DEVICES];
// Buffer for DPTE table
dpte_t dpte;
// Count of transferred sectors and bytes
Bit16u trsfsectors;
Bit32u trsfbytes;
} ata_t;
#if BX_ELTORITO_BOOT
// ElTorito Device Emulation data
typedef struct {
Bit8u active;
Bit8u media;
Bit8u emulated_drive;
Bit8u controller_index;
Bit16u device_spec;
Bit32u ilba;
Bit16u buffer_segment;
Bit16u load_segment;
Bit16u sector_count;
// Virtual device
chs_t vdevice;
} cdemu_t;
#endif // BX_ELTORITO_BOOT
// for access to EBDA area
// The EBDA structure should conform to
// http://www.frontiernet.net/~fys/rombios.htm document
// I made the ata and cdemu structs begin at 0x121 in the EBDA seg
// EBDA must be at most 768 bytes; it lives at EBDA_SEG, and the boot
// device tables are at IPL_SEG
typedef struct {
Bit8u size;
unsigned char filler0[0x21];
Bit16u mouse_driver_offset;
Bit16u mouse_driver_seg;
Bit8u mouse_flag1;
Bit8u mouse_flag2;
Bit8u mouse_data[0x08];
unsigned char filler1[0x0D];
// FDPT - Can be split into data members if needed
unsigned char fdpt0[0x10];
unsigned char fdpt1[0x10];
unsigned char filler2[0xC4];
// ATA Driver data
ata_t ata;
#if BX_ELTORITO_BOOT
// El Torito Emulation data
cdemu_t cdemu;
#endif // BX_ELTORITO_BOOT
} ebda_data_t;
#define EbdaData ((ebda_data_t *) 0)
// for access to the int13ext structure
typedef struct {
Bit8u size;
Bit8u reserved;
Bit16u count;
Bit16u offset;
Bit16u segment;
Bit32u lba1;
Bit32u lba2;
} int13ext_t;
#define Int13Ext ((int13ext_t *) 0)
// Disk Physical Table definition
typedef struct {
Bit16u size;
Bit16u infos;
Bit32u cylinders;
Bit32u heads;
Bit32u spt;
Bit32u sector_count1;
Bit32u sector_count2;
Bit16u blksize;
Bit16u dpte_offset;
Bit16u dpte_segment;
union {
struct {
Bit16u key;
Bit8u dpi_length;
Bit8u reserved1;
Bit16u reserved2;
Bit8u host_bus[4];
Bit8u iface_type[8];
Bit8u iface_path[8];
Bit8u device_path[8];
Bit8u reserved3;
Bit8u checksum;
} phoenix;
struct {
Bit16u key;
Bit8u dpi_length;
Bit8u reserved1;
Bit16u reserved2;
Bit8u host_bus[4];
Bit8u iface_type[8];
Bit8u iface_path[8];
Bit8u device_path[16];
Bit8u reserved3;
Bit8u checksum;
} t13;
} dpi;
} dpt_t;
#define Int13DPT ((dpt_t *) 0)
#endif // BX_USE_ATADRV
typedef struct {
union {
struct {
Bit16u di, si, bp, sp;
Bit16u bx, dx, cx, ax;
} r16;
struct {
Bit16u filler[4];
Bit8u bl, bh, dl, dh, cl, ch, al, ah;
} r8;
} u;
} pusha_regs_t;
typedef struct {
union {
struct {
Bit32u edi, esi, ebp, esp;
Bit32u ebx, edx, ecx, eax;
} r32;
struct {
Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4;
Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8;
} r16;
struct {
Bit32u filler[4];
Bit8u bl, bh;
Bit16u filler1;
Bit8u dl, dh;
Bit16u filler2;
Bit8u cl, ch;
Bit16u filler3;
Bit8u al, ah;
Bit16u filler4;
} r8;
} u;
} pushad_regs_t;
typedef struct {
union {
struct {
Bit16u flags;
} r16;
struct {
Bit8u flagsl;
Bit8u flagsh;
} r8;
} u;
} flags_t;
#define SetCF(x) x.u.r8.flagsl |= 0x01
#define SetZF(x) x.u.r8.flagsl |= 0x40
#define ClearCF(x) x.u.r8.flagsl &= 0xfe
#define ClearZF(x) x.u.r8.flagsl &= 0xbf
#define GetCF(x) (x.u.r8.flagsl & 0x01)
typedef struct {
Bit16u ip;
Bit16u cs;
flags_t flags;
} iret_addr_t;
typedef struct {
Bit16u type;
Bit16u flags;
Bit32u vector;
Bit32u description;
Bit32u reserved;
} ipl_entry_t;
static Bit8u inb();
static Bit8u inb_cmos();
static void outb();
static void outb_cmos();
static Bit16u inw();
static void outw();
static void init_rtc();
static bx_bool rtc_updating();
static Bit8u _read_byte();
static Bit16u _read_word();
static void _write_byte();
static void _write_word();
static Bit8u read_byte_SS();
static Bit16u read_word_SS();
static void _write_byte_SS();
static void _write_word_SS();
static void bios_printf();
static Bit8u inhibit_mouse_int_and_events();
static void enable_mouse_int_and_events();
static Bit8u send_to_mouse_ctrl();
static Bit8u get_mouse_data();
static void set_kbd_command_byte();
static void int09_function();
static void int13_harddisk();
static void int13_cdrom();
static void int13_cdemu();
static void int13_eltorito();
static void int13_diskette_function();
static void int14_function();
static void int15_function();
static void int16_function();
static void int17_function();
static void int19_function();
static void int1a_function();
static void int70_function();
static void int74_function();
static Bit16u get_CS();
static Bit16u get_SS();
static Bit16u set_DS();
static unsigned int enqueue_key();
static unsigned int dequeue_key();
static void get_hd_geometry();
static void set_diskette_ret_status();
static void set_diskette_current_cyl();
static void determine_floppy_media();
static bx_bool floppy_drive_exists();
static bx_bool floppy_drive_recal();
static bx_bool floppy_media_known();
static bx_bool floppy_media_sense();
static bx_bool set_enable_a20();
static void debugger_on();
static void debugger_off();
static void keyboard_init();
static void keyboard_panic();
static void shutdown_status_panic();
static void nmi_handler_msg();
static void delay_ticks();
static void delay_ticks_and_check_for_keystroke();
static void interactive_bootkey();
static void print_bios_banner();
static void print_boot_device();
static void print_boot_failure();
static void print_cdromboot_failure();
# if BX_USE_ATADRV
// ATA / ATAPI driver
void ata_init();
void ata_detect();
void ata_reset();
Bit16u ata_cmd_non_data();
Bit16u ata_cmd_data_io();
Bit16u ata_cmd_packet();
Bit16u atapi_get_sense();
Bit16u atapi_is_ready();
Bit16u atapi_is_cdrom();
#endif // BX_USE_ATADRV
#if BX_ELTORITO_BOOT
void cdemu_init();
Bit8u cdemu_isactive();
Bit8u cdemu_emulated_drive();
Bit16u cdrom_boot();
#endif // BX_ELTORITO_BOOT
static char bios_cvs_version_string[] = "$Revision$ $Date$";
#define BIOS_COPYRIGHT_STRING "(c) 2001-2017 The Bochs Project"
#if DEBUG_ATA
# define BX_DEBUG_ATA(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_ATA(a...)
#endif
#if DEBUG_INT13_HD
# define BX_DEBUG_INT13_HD(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT13_HD(a...)
#endif
#if DEBUG_INT13_CD
# define BX_DEBUG_INT13_CD(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT13_CD(a...)
#endif
#if DEBUG_INT13_ET
# define BX_DEBUG_INT13_ET(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT13_ET(a...)
#endif
#if DEBUG_INT13_FL
# define BX_DEBUG_INT13_FL(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT13_FL(a...)
#endif
#if DEBUG_INT15
# define BX_DEBUG_INT15(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT15(a...)
#endif
#if DEBUG_INT16
# define BX_DEBUG_INT16(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT16(a...)
#endif
#if DEBUG_INT1A
# define BX_DEBUG_INT1A(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT1A(a...)
#endif
#if DEBUG_INT74
# define BX_DEBUG_INT74(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT74(a...)
#endif
#define SET_AL(val8) *((Bit8u *)&AX) = (val8)
#define SET_BL(val8) *((Bit8u *)&BX) = (val8)
#define SET_CL(val8) *((Bit8u *)&CX) = (val8)
#define SET_DL(val8) *((Bit8u *)&DX) = (val8)
#define SET_AH(val8) *(((Bit8u *)&AX)+1) = (val8)
#define SET_BH(val8) *(((Bit8u *)&BX)+1) = (val8)
#define SET_CH(val8) *(((Bit8u *)&CX)+1) = (val8)
#define SET_DH(val8) *(((Bit8u *)&DX)+1) = (val8)
#define GET_AL() ( AX & 0x00ff )
#define GET_BL() ( BX & 0x00ff )
#define GET_CL() ( CX & 0x00ff )
#define GET_DL() ( DX & 0x00ff )
#define GET_AH() *(((Bit8u *)&AX)+1)
#define GET_BH() *(((Bit8u *)&BX)+1)
#define GET_CH() *(((Bit8u *)&CX)+1)
#define GET_DH() *(((Bit8u *)&DX)+1)
#define GET_ELDL() ( ELDX & 0x00ff )
#define GET_ELDH() *(((Bit8u *)&ELDX)+1)