-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathinit.386
2937 lines (2311 loc) · 65.4 KB
/
init.386
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
;***************************************************************************
;
; Copyright (c) 1997, 1998 Timpanogas Research Group, Inc. All Rights
; Reserved.
;
; AUTHOR : Jeff V. Merkey
; FILE : INIT.386
; DESCRIP : Real Mode MS-DOS Initialization Code for MANOS v1.0
; DATE : October 24, 1997
;
;
;***************************************************************************
.486P ; select the processor
MODEL LARGE ; DOSSEG
DOSHEAP = 1 ; specify whether DOS heap is to be used, or
; internal heap; 1 indicates DOS heap; 0 internal
STACK 400h ; reserve stack space as needed for application
VERBOSE EQU 0
CR EQU 13
LF EQU 10
SYSTEM_PORTA EQU 60h
SYSTEM_STATUS_PORT EQU 64h
SYSTEM_CONTROL_PORTA EQU 92h
;
; bus types
;
ISA EQU 01h
MCA EQU 02h
PS2 EQU 04h
EISA EQU 08h
PCI EQU 10h
PCMCIA EQU 20h
OperSize macro
db 66h
endm
AddrSize macro
db 67h
endm
OPND32 macro op_code, op_erand
db 66h
IFNB <op_code>
db op_code
IFNB <op_erand>
dd op_erand
ENDIF
ENDIF
endm
CPUID macro
db 0Fh
db 0A2h
endm
CR4_TO_ECX macro
db 0Fh
db 20h
db 0E1h
endm
ECX_TO_CR4 macro
db 0Fh
db 22h
db 0E1h
endm
Synch macro
LOCAL L1, L2, L3
jmp short L1
L1:
jmp short L2
L2:
jmp short L3
L3:
endm
PSPSignature EQU 020CDh ; signature of PSP
ProgramSegmentPrefix struc
PSPExitInt dw ?
PSPMemTotal dw ?
PSPResv1 db ?
PSPDOSCall db 5 dup (?)
PSPTerminate dd ?
PSPControlC dd ?
PSPCritical dd ?
PSPParent dw ?
PSPHandleTable db 20 dup (?)
PSPEnvironment dw ?
PSPStack dd ?
PSPHandleSize dw ?
PSPHandlePtr dd ?
PSPResv2 db 24 dup (?)
PSPDOSInt db 3 dup (?)
PSPResv3 db 9 dup (?)
PSPFCB1 db 16 dup (?)
PSPFCB2 db 16 dup (?)
PSPResv4 db 4 dup (?)
PSPCommandLen db 1 dup (?)
PSPCommandBuf db 127 dup (?)
ProgramSegmentPrefix ends
IMAGE_BASE_RELOCATION struc
VirtualAddress dd ?
SizeOfBlock dd ?
IMAGE_BASE_RELOCATION ends
ASSUME cs:INITCODE, ds:INITCODE, es:nothing, fs:nothing, gs:nothing
INITCODE SEGMENT PUBLIC READWRITE USE16
public RealMode16Segment
RealMode16Segment label dword
;
; THIS IS THE BEGINNING OF EXECUTION
;
; execution of this loader begins at this point. The Borland assembler
; supports a STARTUPCODE directive that will automatically insert the
; proper PSP segment fixups relative to our EXE program.
;
align 16
public STARTUP_TAG1
STARTUP_TAG1 db 'INIT'
STARTUP_TAG2 db '_COD'
STARTUP_TAG3 db 'E_ST'
STARTUP_TAG4 db 'ART_'
;
; manos header. DO NOT MOVE THIS HEADER OR TAG. LLINK EXPECTS
; THE MANOS HEADER TO IMMEDIATELY FOLLOW THIS TAG.
;
public manos_header
manos_header label dword
blocks_in_file dw 0
manos_res dw 0
startup_pe_header dd 0
startup_32_code dd 0
startup_32_data dd 0
startup_16_code dd 0
startup_stack dd 0
startup_reloc dd 0
startup_reloc_32 dd 0
code_rva dd 0
data_rva dd 0
code_size dd 0
data_size dd 0
pe_base dd 0
startup_debug dd 0
code_virt_size dd 0
data_virt_size dd 0
reloc_size dd 0
debug_size dd 0
system_offset dd 0
psp_next_segment dw 0
total_paragraphs dw 0
InProt db 'MANOS_FATAL: System is already in Protected Mode', CR, LF, '$'
GoodDOSMsg db 'MS-DOS Compatible Version 3.00 or Higher Detected', CR, LF, '$'
BadDOSMsg db 'MANOS_FATAL: MS-DOS Version Must be 3.00 or Higher for this Loader', CR, LF, '$'
SMPDetect db 'Multi-Processing Support Detected', CR, LF, '$'
MPSVer db 'Intel MPS (Multi-Processor Specification) Support Present', CR, LF, '$'
XMSError db 'MANOS_FATAL: XMS Detected. Unload your XMS driver, then restart MANOS', CR, LF, '$'
NoMem db 'MANOS_FATAL: Insufficient memory (need at least 8MB)', CR, LF, '$'
NoLowMem db 'MANOS_FATAL: Insufficient memory below 1MB', CR, LF, '$'
MemFound db 'Memory Subsystem Check Complete', CR, LF, '$'
ISABus db 'Industry Standard Architecture (ISA) Bus Detected', CR, LF, '$'
MCABus db 'Micro Channel Architecture (MCA) Bus Detected', CR, LF, '$'
PS2Bus db 'IBM PS/2 System Detected', CR, LF, '$'
EISABus db 'Extended Industry Standard Architecture (EISA) Bus Detected', CR, LF, '$'
PCIBus db 'Peripheral Component Interconnect (PCI) Bus Detected', CR, LF, '$'
PCMCIABus db 'PCMCIA Bus Detected', CR, LF, '$'
Line20Msg db 'Address Line 20 has been enabled', CR, LF, '$'
Line20PS2 db 'Address Line 20 has been enabled (PS/2 mode)', CR, LF, '$'
SearchMsg db 'Performing Processor Verification', CR, LF, '$'
GDTMsg db 'Global Descriptor Tables Initialized', CR, LF, '$'
DOSDrive db 'Default MS-DOS Drive Information Found', CR, LF, '$'
MouseOff db 'Mouse Driver has been Reset and Disabled', CR, LF, '$'
MouseOn db 'Mouse Driver has been enabled', CR, LF, '$'
resize_error db 'MANOS_FATAL: Program Segment Prefix (PSP) Resize Failed', CR, LF, '$'
unsup_proc db 'MANOS_FATAL: Processor must be an 80386 equivalent or higher', CR, LF, '$'
ProtModeOn db 'Entered Protected Mode', CR, LF, '$'
ProtModeOff db 'Exited Protected Mode', CR, LF, '$'
id_msg db 'This system has a$'
fp_8087 db ' and an 8087 math coprocessor$'
fp_80287 db ' and an 80287 math coprocessor$'
fp_80387 db ' and an 80387 math coprocessor$'
c8086 db 'n 8086/8088 processor$'
c286 db 'n 80286 processor$'
c386 db 'n 80386 processor$'
c486 db 'n 80486 DX processor or 80487 SX math coprocessor$'
c486nfp db 'n 80486 SX processor$'
Intel486_msg db 'This System Contains a Genuine '
db 'Intel486(TM) processor', CR, LF, '$'
Pentium_msg db 'This System Contains a Genuine '
db 'Intel Pentium(R) processor', CR, LF, '$'
PentiumPro_msg db 'This System Contains a Genuine '
db 'Intel PentiumPro(R) processor', CR, LF, '$'
model_msg db 'Model: $'
stepping_msg db 'Stepping: $'
family_msg db CR, LF, 'Processor Family: $'
period db '.', CR, LF, '$'
dataCR db ?, CR, LF, '$'
dataCR1 db ?, CR, LF, '$'
intel_id db 'GenuineIntel'
fpu_msg db CR, LF, 'This processor contains a FPU', CR, LF, '$'
no_fpu_msg db CR, LF, 'This processor contains no FPU', CR, LF, '$'
mce_msg db 'This processor supports the '
db 'Machine Check Exception', CR, LF, '$'
cmp_msg db 'This processor supports the '
db 'CMPXCHG8B instruction', CR, LF, '$'
page_4MB_msg db 'This processor supports '
db '4MB paging', CR, LF, '$'
io_break_msg db 'This processor supports '
db 'IO Breakpoints', CR, LF, '$'
not_Intel db 't least an 80486 processor. '
db 'CPUID was not supported', CR, LF, '$'
FourMeg db 'Processor Supports 4MB Paging', CR, LF, '$'
BadProcessor db 'FATAL: A 386 Processor or Higher was not Detected', CR, LF, '$'
llinkmsg db 'FATAL: LLINK has not been run on this file', CR, LF, '$'
io_break_enable db 'IO Breakpoint Support Enabled', CR, LF, '$'
p4mb_enable db '4MB Paging Support Enabled', CR, LF, '$'
wc_enable db 'PCI Write Combining Enabled', CR, LF, '$'
DOSExitMsg db 'Exiting to MS-DOS', CR, LF, '$'
FixupOKMsg db '32-bit image fixup completed', CR, LF, '$'
FixupErrorMsg db '32-bit image fixup error', CR, LF, '$'
CurrentDir db 72 dup (0)
FAMILY_MASK EQU 0F00h
FAMILY_SHIFT EQU 8
MODEL_MASK EQU 0F0h
MODEL_SHIFT EQU 4
STEPPING_MASK EQU 0Fh
FPU_FLAG EQU 1h
MCE_FLAG EQU 80h
CMPXCHG8B_FLAG EQU 100h
GDTDescriptor struc
Limit dw 0FFFFh
Base1 dw 0
Base2 db 0
GDTType db 10010010b
OtherType db 11001111b
Base3 db 0
GDTDescriptor ends
PICA_8259 EQU 20h
PICA_CONTROL EQU 21h
PICB_8259 EQU 0A0h
PICB_CONTROL EQU 0A1h
align 16
DOS_TABLE dd 0
GDT_TABLE dd 0
GDT_POINTER dd 0
DOS_IDT_TABLE dd 0
DOS_CE_SEGMENT dd 0
DOS_CE_OFFSET dd 0
DOS_CC_SEGMENT dd 0
DOS_CC_OFFSET dd 0
DOS_DATA_SEGMENT dd 0
DOS_STACK_SEGMENT dd 0
DOS_EXTRA_SEGMENT dd 0
DOS_FS_SEGMENT dd 0
DOS_STACK_OFFSET dd 0
DOS_SYSTEM_BUS_TYPE dd 0
DOS_CR0 dd 0
REAL_MODE_INT dd 0
DOS_EXIT dd 0
VENDOR_ID db 12 dup (0)
CPU_TYPE db 0
CPU_FILL db 3 dup (0)
CPU_MODEL dd 0
STEPPING dd 0
ID_FLAG dd 0
FEATURE_FLAGS dd 0
XMS_FUNCTION dd 0
XMS_MEMORY dd 0
XMS_SIZE dd 0
XMS_HANDLE dd 0
XMS_BASE dd 0
MEMORY_HIGH dd 0
MEMORY_HIGH_START dd 0
MEMORY_LOW dd 0
MEMORY_LOW_START dd 0
FP_STATUS dd 0
DOS_DEFAULT_DRIVE dd 0
MASK_8259_A dd 0
MASK_8259_B dd 0
FPU_TYPE db 0
FPU_FILL db 3 dup (0)
INTEL_PROC db 0
INTEL_FILL db 3 dup (0)
RESERVED dd 0
LINE_20_ON dd 0
LINE_20_OFF dd 0
PM_STACK dd 0
PM_CODE_SEGMENT dd 0
PM_DATA_SEGMENT dd 0
JUMP16_SEGMENT dd 0
MSDOS_CREATE dd 0
MSDOS_OPEN dd 0
MSDOS_LSEEK dd 0
MSDOS_READ dd 0
MSDOS_WRITE dd 0
MSDOS_CLOSE dd 0
MSDOS_UNLINK dd 0
PE_HEADER_ADDR dd 0
RELOC_OFFSET dd 0
RELOC32_OFFSET dd 0
CODE_RVA dd 0
DATA_RVA dd 0
CODE_SIZE dd 0
DATA_SIZE dd 0
VIDEO_ADDRESS dd 0
VIDEO_CURSOR_MODE dd 0
VIDEO_PORT_ADDRESS dd 0
VIDEO_SCREEN_TYPE dd 0
VIDEO_COLOR_FLAG dd 0
START_OF_CODE_16 dd 0
END_OF_CODE_16 dd 0
DEBUG_TABLE dd 0
CODE_VIRT_SIZE dd 0
DATA_VIRT_SIZE dd 0
EXTENDED_MEMORY_LEN dd 0
EXTENDED_MEMORY_ADDR dd 0
CODE_16_ENTRY dd 0
DEBUG_SIZE dd 0
STARTUP_SEGMENT dd 0
STARTUP_CODE dd 0
STARTUP_JUMP dd 0
RELOC_SIZE dd 0
SYSTEM_OFFSET dd 0
REAL_INT_SEGMENT dd 0
CURRENT_DIRECTORY dd 0
DISPLAY_CODE dd 0
DISPLAY_STATE db 128 dup (0)
; basic video display types
MONOCHROME_SCN EQU 00000001b
CGA_SCN EQU 00000010b
VGA_MONOCHROME_SCN EQU 00000100b
EGA_VGA_SCN EQU 00001000b
CURSOR_STD EQU 0C0Bh
CURSOR_HEAVY EQU 0C09h
CURSOR_BLK EQU 0C00h
CURSOR_UP EQU 0400h
align 16
public MSDOSIDTTable
MSDOSIDTTable label pword
MSDOSIDTIndex dw 0
MSDOSIDTOffset dd 0
align 16
public MSDOSGDTTable
MSDOSGDTTable label pword
MSDOSGDTIndex dw 0
MSDOSGDTOffset dd 0
align 16
public NullGDT
NullGDT GDTDescriptor <> ; 00h
CodeSegment GDTDescriptor <,,,9Ah> ; 08h
DataSegment GDTDescriptor <> ; 10h
RealModeCode GDTDescriptor <,,,9Ah,0> ; 18h
RealModeData GDTDescriptor <,,,,0> ; 20h
align 16
public GDTTable
GDTTable label pword
GDTIndex dw 40
GDTOffset dd 0
align 16
public init_code
init_code proc near
STARTUPCODE
; MS-DOS EXE programs have all available memory allocated to them
; so we have to read the PSP, and free paragraphs we are not using
; the borland startup code will set ds: to an incorrect value
; but we assume ds: = cs:
IF DOSHEAP
; Release all memory except the amount currently being used
; End of stack is end of non-heap portion of program
; es: = PSP memory block, ds:= code segment
;
; until we detect what processor we are running on, some
; things to be careful with:
; 1. all jumps must be short jmp instructions
; 2. we cannot use any opcodes that reference 386 registers
;
mov ax, cs
mov ds, ax
mov ax, blocks_in_file ; convert 512 blocks in paragraphs
or ax, ax ; if llink was not run, then
jz short no_psp_fixup ; don't do the fixup
mov ax, blocks_in_file ; convert 512 blocks in paragraphs
add ax, 32 ; add 16K stack for startup
mov dx, 32 ; multiply by 32 to get number of paragraphs
mul dx
mov bx, ax
mov total_paragraphs, bx ; save total size of image (paragraphs)
mov ah, 4Ah ;resize memory block with PSP
int 21h ;address in ES
jc short ResizeError
mov ax, es ; ES PSP address
add ax, total_paragraphs ; add to our total size
add ax, 15 ; round up
and ax, 0FFF0h ; align on paragraph boundry
mov es:PSPMemTotal, ax ; adjust PSP end of memory
mov ds:psp_next_segment, ax
jmp short init_continue
no_psp_fixup:
mov dx, offset llinkmsg
call OutputMessage
mov ah, 4Ch
xor al, al
int 21h
ENDIF
init_continue:
;
; if the PE bit in CR0 is already set, them exit with
; error. The machine is already in protected mode
;
xor ax, ax
smsw ax
test ax, 01h
jz short CheckHardware
mov dx, offset InProt
call OutputMessage
mov ah, 4Ch
xor al, al
int 21h
CheckHardware:
call DetectProcessorInformation
mov al, CPU_TYPE
cmp al, 3
jl short ProcessorNotSupported
call DetectDOSVersion
call GetVideoInfo
call DetectBusInformation
call PEFixup ; fixup PE image attached to INIT.EXE
call DetectXMS ; if XMS is not present, then query int 15
or eax, eax
jnz ExecSystem
call DetectExtendedMemory
ExecSystem:
call EnterProtectedMode
; Exit to DOS when complete or if error
mov ah, 4Ch
xor al, al
int 21h
ProcessorNotSupported:
mov dx, offset unsup_proc
call OutputMessage
mov ah, 4Ch
xor al, al
int 21h
ResizeError:
mov dx, offset resize_error
call OutputMessage
mov ah, 4Ch
xor al, al
int 21h
init_code endp
;*************************************************************************
;
; Enter Protected Mode
;
;*************************************************************************
public EnterProtectedMode
EnterProtectedMode proc near
cli
mov ax, cs
mov ds, ax
;
; point of no return. Here we will go to protected mode
; at this point, it is assumed we have performed all the
; necessary checks, and have passed this system as
; capable of suppporting a protected mode operating
; system.
;
;
; MSDOS documentation states that the control-c and critical
; error handlers are vectored to the PSP by MSDOS, requiring
; that the IVT (interrupt vector table) be patched to hook
; these vectors. If someone presses control-c or we get a
; critical error, then the system will hang if these vectors
; are not stubbed during load.
;
call HookDOSHandlers
cmp dword ptr ds: XMS_FUNCTION, 0
jnz Line20XMSEnable
call BitLine20
Line20XMSEnable:
call DisableMouse
call GetDOSDefaultDrive
call GetDefaultDirectory
; read the current 8259 mask values for PICA and PICB
OperSize
sgdt ds:MSDOSGDTTable
OperSize
sidt ds:MSDOSIDTTable
in al, 21h
mov byte ptr ds:MASK_8259_A, al
Synch
; Move the default vector number for PIC0 to 28h
;
; ICW1 - 11h-> ICW1, LTIM=ignored, ADI=ignored, SNGL=cascade, ICW4 needed
mov eax, DOS_SYSTEM_BUS_TYPE
and eax, PS2
jz NotLevelPIC
mov al, 19h ; set to level triggered
out 20h, al
Synch
jmp ICW2Next
NotLevelPIC:
mov al, 11h ; set to edge triggered
out 20h, al
Synch
ICW2Next:
mov al, 28h ; MANOS Vector 28h
out 21h, al
Synch
; MSDOS is Vector 8h
; ICW3 - 0000 0100 INT2 is cascaded
mov al, 4h
out 21h, al
Synch
; ICW4 - 0000 0001: 8086/8088 mode
mov al, 1h
out 21h, al
Synch
mov al, 0FFh ; (11111111b)
out 21h, al
Synch
in al, 0A1h
mov byte ptr ds:MASK_8259_B, al
Synch
mov al, 0FFh
out 0A1h, al
Synch
mov al, 0Ah ; IRR reads ISR
out 20h, al
out 0A0h, al
Synch
; calculate 32 bit linear address
; (cs << 4) + offset <entry32>
; here we patch the GDT to create a far 16-bit
; segment to return to real mode.
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: RealMode16Segment
mov dword ptr ds:JUMP16_SEGMENT, eax
mov bx, offset ds: RealModeCode
mov ds: [bx].Base1, ax
shr eax, 16
mov ds: [bx].Base2, al
mov ds: [bx].Base3, ah
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: RealMode16Segment
mov bx, offset ds: RealModeData
mov ds: [bx].Base1, ax
shr eax, 16
mov ds: [bx].Base2, al
mov ds: [bx].Base3, ah
mov eax, offset ds: jump_16
sub eax, offset ds: RealMode16Segment
mov dword ptr ds: RealOffsetValue, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: MSDOSIDTTable
mov dword ptr ds: DOS_IDT_TABLE, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: GDTTable
mov dword ptr ds: GDT_POINTER, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: CurrentDir
mov dword ptr ds: CURRENT_DIRECTORY, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: NullGDT
mov dword ptr ds: GDTOffset, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: MSDOSGDTTable
mov dword ptr ds: GDT_TABLE, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: PSNull
mov dword ptr ds: PSGDTOffset, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: PSSegment
mov dword ptr ds: STARTUP_SEGMENT, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: PSStart
mov dword ptr ds: STARTUP_CODE, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: PSGDTOffsetValue
mov dword ptr ds: STARTUP_JUMP, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset cs: BitLine20
mov dword ptr ds: LINE_20_ON, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset cs: DisableLine20
mov dword ptr ds: LINE_20_OFF, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset cs: RealMode16Segment
mov dword ptr ds: START_OF_CODE_16, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset cs: init_code
mov dword ptr ds: CODE_16_ENTRY, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset cs: RealMode16SegmentEnd
mov dword ptr ds: END_OF_CODE_16, eax
xor eax, eax
xor ecx, ecx
mov ax, cs
shl eax, 4
mov ecx, dword ptr ds: startup_pe_header
add eax, ecx
mov dword ptr ds: PE_HEADER_ADDR, eax
xor eax, eax
xor ecx, ecx
mov ax, cs
shl eax, 4
mov ecx, dword ptr ds: startup_reloc
add eax, ecx
mov dword ptr ds: RELOC_OFFSET, eax
xor eax, eax
xor ecx, ecx
mov ax, cs
shl eax, 4
mov ecx, dword ptr ds: startup_reloc_32
add eax, ecx
mov dword ptr ds: RELOC32_OFFSET, eax
xor eax, eax
xor ecx, ecx
mov ax, cs
shl eax, 4
mov ecx, dword ptr ds: startup_debug
add eax, ecx
mov dword ptr ds: DEBUG_TABLE, eax
xor eax, eax
mov eax, dword ptr ds: code_rva
mov dword ptr ds: CODE_RVA, eax
xor eax, eax
mov eax, dword ptr ds: data_rva
mov dword ptr ds: DATA_RVA, eax
xor eax, eax
mov eax, dword ptr ds: code_size
mov dword ptr ds: CODE_SIZE, eax
xor eax, eax
mov eax, dword ptr ds: data_size
mov dword ptr ds: DATA_SIZE, eax
xor eax, eax
mov eax, dword ptr ds: code_virt_size
mov dword ptr ds: CODE_VIRT_SIZE, eax
xor eax, eax
mov eax, dword ptr ds: data_virt_size
mov dword ptr ds: DATA_VIRT_SIZE, eax
xor eax, eax
mov eax, dword ptr ds: debug_size
mov dword ptr ds: DEBUG_SIZE, eax
xor eax, eax
mov eax, dword ptr ds: system_offset
mov dword ptr ds: SYSTEM_OFFSET, eax
xor eax, eax
mov eax, dword ptr ds: reloc_size
mov dword ptr ds: RELOC_SIZE, eax
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset cs: MSDOSExit
mov dword ptr ds: DOS_EXIT, eax
xor eax, eax
xor ecx, ecx
mov ax, cs
shl eax, 4
mov ecx, dword ptr ds: startup_32_code ; COMBINE provided fixup
add eax, ecx
mov dword ptr ds: GDTOffsetValue, eax ; startup jump address
mov dword ptr ds: PM_CODE_SEGMENT, eax
xor eax, eax
mov ax, cs
shl eax, 4
mov ecx, dword ptr ds: startup_32_data ; COMBINE provided fixup
add eax, ecx
mov dword ptr ds: PM_DATA_SEGMENT, eax
xor eax, eax
movzx eax, word ptr ds:psp_next_segment
shl eax, 4
sub eax, 32
mov dword ptr ds: PM_STACK, eax
pushf ; save real mode flags
mov ax, ss
mov word ptr ds: DOS_STACK_SEGMENT, ax
mov ax, sp
mov word ptr ds: DOS_STACK_OFFSET, ax
mov ax, ds
mov word ptr ds: DOS_DATA_SEGMENT, ax
mov ax, es
mov word ptr ds: DOS_EXTRA_SEGMENT, ax
mov ax, fs
mov word ptr ds: DOS_FS_SEGMENT, ax
; put the ds: segment value into the edx register
xor edx, edx
mov dx, ds
; pass the base address of the MSDOS Data Table in ebx
xor eax, eax
mov ax, cs
shl eax, 4
add eax, offset ds: DOS_TABLE
mov dword ptr ds: DOS_TABLE, eax
mov ebx, eax
;
; at this point, DS: is in the edx register
; and the MSDOS data table is in the ebx
; register.
;
xor ecx, ecx ; tell startup caller is real mode loader
;
; enable protected mode
;
mov eax, CR0
mov dword ptr ds: DOS_CR0, eax
OperSize
lgdt ds: GDTTable
mov eax, CR0
and eax, 0FFFFFFF1h ; clear TS/EM/MP
cmp ds: FPU_TYPE, 0
jnz FloatingPointUnitPresent
or eax, 4 ; set Math Emulation bit (EM)
jmp NoFloatingPointUnit
FloatingPointUnitPresent:
or eax, 2 ; set the Math Present bit (MP)
NoFloatingPointUnit:
or eax, 1
mov CR0, eax
jmp short ClearPreFetch ; jump is required to clear
; the the processor pre-fetch
ClearPreFetch:
AddrSize
OperSize
mov eax, 10h ; assume cs:segment 08h, all
mov ds, ax ; other segment registers assume
mov es, ax ; ds:segment 10h
mov ss, ax
mov fs, ax
AddrSize
OperSize
db 0EAh ; jmp far 0008:00000000 start of 32 bit code
GDTOffsetValue label dword
dd 0
dw 8h
EnterProtectedMode endp
;
; Symmetrical Muliprocessing entry point for processors 1-31
;
align 16
public PSNull
PSNull GDTDescriptor <> ;00
PSCodeGDT GDTDescriptor <,,,9Ah> ;08
PSDataGDT GDTDescriptor <> ;10
align 16
public PSSegment
PSSegment label dword
PSGDTPointerTable label pword
PSGDTPointer dw 18h
PSGDTOffset dd 0
public PSStart
PSStart:
cli
mov ax, cs
mov ds, ax
xor ebx, ebx
lgdt ds: [ebx]
mov eax, CR0
or eax, 1
mov CR0, eax
jmp short PrefetchClear
PrefetchClear:
AddrSize
OperSize
mov eax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
AddrSize
OperSize
db 0EAh
PSGDTOffsetValue label dword
dd 0
dw 8h
;*************************************************************************
;
; Exit to MSDOS
;
;*************************************************************************
align 16
public MSDOSExit
MSDOSExit proc
cli
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
db 0EAh ; jmp far
RealOffsetValue label dword