-
Notifications
You must be signed in to change notification settings - Fork 0
/
BLPMI.ASM
2749 lines (2017 loc) · 60.8 KB
/
BLPMI.ASM
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
TITLE "Ballan Luca Protected Mode Interface V. 2.11"
SUBTTL "Entering in Protected Mode"
.486P
.MODEL SMALL
;*******************************************************************************
;************************ DECLARE CONSTANTS *******************************
;*******************************************************************************
INCLUDE STRUCT.INC
INCLUDE MACRO.INC
;*****************************************************************
;******************* PM Program Information **********************
;*****************************************************************
extrn Start:dword
extrn Start_Limit:dword
extrn StartData_Limit:dword
public PSP
public LOW_FREE_MEM
public LOW_START_SEG
public LOW_START_MEM
public XMS_FREE_MEM
public XMS_START_MEM
public VENDOR_ID
public CPU_TYPE
public INTEL_PROC
public Svga_Mem
public Svga_VH
public Svga_VL
public SvgaSetLinerar_Buffer
;********************* SEGMENTS ORDER ****************************
Kernel_Code SEGMENT PUBLIC PARA USE16 'CODE' ; <-- Entry Point
Kernel_Code ENDS
Kernel_Data SEGMENT PUBLIC PARA USE16 'DATA'
Kernel_Data ENDS
Global_Data SEGMENT PUBLIC PARA USE32 'DATA'
Global_Data ENDS
Kernel_Stack SEGMENT PUBLIC PARA USE32 STACK 'STACK'
Kernel_Stack ENDS
IDT_Stack SEGMENT PUBLIC PARA USE32 STACK 'STACK'
IDT_Stack ENDS
PM2Real_Stack SEGMENT PUBLIC PARA USE32 STACK 'STACK'
PM2Real_Stack ENDS
Int_Code SEGMENT PUBLIC PARA USE32 'INTERRUPT'
Int_Code ENDS
Int_Data SEGMENT PUBLIC PARA USE32 'INTERRUPT'
Int_Data ENDS
Start_SEG SEGMENT PUBLIC PARA USE32 'CODE'
Start_SEG ENDS
Start_Data SEGMENT PUBLIC PARA USE32 'DATA'
Start_Data ENDS
;*****************************************************************
;-----------------------------------------------------------------------------
;--------------------- Selettori del Kernel -----------------------
SelCode EQU Code_Desc - GDTStart
SelData EQU Data_Desc - GDTStart
SelGlobal EQU Global_Desc - GDTStart
SelStack EQU Stack_Desc - GDTStart
SelIDTStack EQU IDTStack_Desc - GDTStart
SelInterrupt EQU Int_Desc - GDTStart
SelInt_Data EQU Int_DDesc - GDTStart
;------------------ Selettori del Programma in PM -----------------
StartTSS EQU StartTSS_Desc - GDTStart
SelInfo EQU Info_Desc - GDTStart
SelPSP EQU PSP_Desc - GDTStart
SelStart EQU Start_Desc - GDTStart
SelStart_Data EQU Start_DescD - GDTStart
;---------------------- Interrupt Tasks ---------------------------
SelExTSS_0 EQU Desc_Ex_00 - GDTStart
SelExTSS_1 EQU Desc_Ex_01 - GDTStart
SelExTSS_2 EQU Desc_Ex_02 - GDTStart
SelExTSS_3 EQU Desc_Ex_03 - GDTStart
SelExTSS_4 EQU Desc_Ex_04 - GDTStart
SelExTSS_5 EQU Desc_Ex_05 - GDTStart
SelExTSS_6 EQU Desc_Ex_06 - GDTStart
SelExTSS_7 EQU Desc_Ex_07 - GDTStart
SelExTSS_8 EQU Desc_Ex_08 - GDTStart
SelExTSS_9 EQU Desc_Ex_09 - GDTStart
SelExTSS_10 EQU Desc_Ex_10 - GDTStart
SelExTSS_11 EQU Desc_Ex_11 - GDTStart
SelExTSS_12 EQU Desc_Ex_12 - GDTStart
SelExTSS_13 EQU Desc_Ex_13 - GDTStart
SelExTSS_14 EQU Desc_Ex_14 - GDTStart
SelExTSS_16 EQU Desc_Ex_16 - GDTStart
SelExTSS_17 EQU Desc_Ex_17 - GDTStart
SelExTSS_Unk EQU Desc_Ex_Unk - GDTStart
;------------------- Selettori della Memoria ----------------------
SelFlat EQU Flat_Desc - GDTStart
SelLowMem EQU LOW_Desc - GDTStart
SelXMS EQU XMS_Desc - GDTStart
SelCharMap EQU Char_Desc - GDTStart
;--------------------- Selettori per OUTPUT -----------------------
Sel_VGA_Text EQU VGA_Text_Desc - GDTStart
Sel_VGA_13 EQU VGA_13_Desc - GDTStart
Sel_Svga EQU SVGA_Desc - GDTStart
;-----------------------------------------------------------------------------
;************************* CONSTANTS ******************************
DIM_STACK EQU 200H
IDT_DIMSTACK EQU 200H
DIM_STPM2RM EQU 200H
MAX_DESC EQU 40
DIM_KB_BUFFER EQU 30
PM_PIC1Mask_Init EQU 0FCH
PM_PIC2Mask_Init EQU 0FFH
;*******************************************************************************
;************************** KERNEL DATA ****************************************
;*******************************************************************************
Kernel_Stack SEGMENT PUBLIC PARA USE32 STACK 'STACK'
DD (DIM_STACK/4) DUP (?)
Kernel_Stack ENDS
IDT_Stack SEGMENT PUBLIC PARA USE32 STACK 'STACK'
DD (IDT_DIMSTACK/4) DUP (?)
IDT_Stack ENDS
PM2Real_Stack SEGMENT PUBLIC PARA USE32 STACK 'STACK'
DD (DIM_STPM2RM/4) DUP (?)
PM2Real_Stack ENDS
Kernel_Data SEGMENT PUBLIC PARA USE16 'DATA'
GDTInfo DW GDTEnd-GDTStart-1 ; GDT limit
GDTAddr DD 0 ; GDT linear start address
IDTInfo DW IDTEnd-IDTStart-1 ; IDT limit
IDTAddr DD 0 ; IDT linear start address
;*******************************************************************************
;************************* SYSTEM INFORMATION **********************************
;*******************************************************************************
Old_IDTR DW ? ; Real IDT
DD ?
PIC1Mask DB ? ; Real PIC Mask
PIC2Mask DB ?
P2R_PIC1Mask DB ? ; PM to RM PIC Mask
P2R_PIC2Mask DB ?
PM_PIC1Mask DB PM_PIC1Mask_Init ; PM PIC Mask
PM_PIC2Mask DB PM_PIC2Mask_Init
PSP DW ? ; PSP Segment
;----------------------- PM to Real Function Data --------------------------
ProtESP DD ?
ProtStack DW ?
Dest_Ind LABEL DWORD
Dest_OFF DW ?
Dest_SEG DW ?
;---------------------------------------------------------------------------
LOW_FREE_MEM DD ? ; Memoria bassa libera
LOW_START_MEM DD ? ; Bassa Indirizzo Lineare
LOW_START_SEG DW ? ; Segmento memoria bassa
XMS_DRIVER_ON DB ?
XMS_HANDLE DW ?
XMS_FREE_MEM DD ? ; Memoria estesa libera
XMS_START_MEM DD ? ; Estesa Indirizzo Lineare
XMS_Control LABEL DWORD
XMS_Control_Offset DW ?
XMS_Control_Segment DW ?
;*******************************************************************************
;****************************** MESSAGES ***************************************
;*******************************************************************************
;--------------------------------- SVGA --------------------------------------
Svga_Mess_1 DB 'Vesa Bios ',11
Svga_VH DB 0,'.',11
Svga_VL DB 0,' : ',0
Svga_Mess_2 DB 13,'Video Memory : ',14
Svga_Mem DD 0
DB ' kb.',13,0
;------------------------------ Check CPU ------------------------------------
c8086 DB 'CPU TYPE : 8086/8088 processor.',13,0
c80286 DB 'CPU TYPE : 80286 processor.',13,0
c80386 DB 'CPU TYPE : 80386 processor.',13,0
c80486 DB 'CPU TYPE : 80486 processor.',13,0
c80586 DB 'CPU TYPE : 80586 processor with Vendor ID ',34
VENDOR_ID DB 12 DUP (?),34,'.',13,0
Pentium_msg DB 'CPU TYPE : Genuine Intel Pentium(TM) processor.',13,0
INTEL_ID DB 'GenuineIntel'
CPU_TYPE DB ?
INTEL_PROC DB 0
error_386 DB 13,'Error : 80386 or better required.',13,0
error_v86 DB 13,'Error : System is running in Virtual 8086 mode.',13,0
error_dpmi DB 13,'Error : System is running under a DPMI server.',13,0
error_win DB 13,'Error : System is running under Microsoft Windows.',13,0
error_LowMem DB 13,"Error : All conventional memory is in use.",13,0
error_LowMem_2 DB 13,"Error : Can't free conventional memory.",13,0
error_Extended DB 13,"Error : Can't use extended memory.",13,0
error_Xms DB 13,'Error : All Extended memory is in use or the Xms driver is too old.',13
DB ' Try to unload the Xms Driver.',13,0
error_Xms2 DB 13,"Error : Can't free XMS memory.",13,0
;----------------------------- INIT MESSAGE ----------------------------------
Start_Message DB 10,14,'Ballan Luca',10,7,' Protected Mode Interface. Version '
DB 10,9,'2.11',13,10,7,'Last update ',??date,' time ',??time,'.',13,0
;-------------------------------- TIMER --------------------------------------
Time_Double DD 0
DD 0
Clock_K DB 0,0,0,0AH,0B0H,0,38H,41H ; Double di 18,206 ...
Vet DW 0,31,28,31,30,31,30,31,31,30,31,30,31
Kernel_Data ENDS
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************
;************************** START CODE *****************************************
;*******************************************************************************
;*******************************************************************************
Kernel_Code SEGMENT PUBLIC PARA USE16 'CODE'
ASSUME CS:Kernel_Code,SS:Kernel_Stack
ASSUME DS:Kernel_Data
ASSUME ES:Global_Data
ASSUME GS:Int_Data
;******************************** MAIN *****************************************
@STARTUP:
PUSH DS ; Save PSP
MOV AX,Kernel_Data
MOV DS,AX
POP PSP ; Store PSP
MOV AX,Global_Data
MOV ES,AX
MOV AX,Kernel_Stack
MOV SS,AX ; <- RF FLAG
MOV ESP,DIM_STACK
Setup_Video ; Inizializzazione video
MOV SI,OFFSET Start_Message ; Messaggio di inizio
CALL R_Cout
CALL Check_CPU ; Controllo Processore
CALL R_Cout
MOV AL,CPU_TYPE
CMP AL,3 ; Errore se precede l'
JAE SHORT Cpu_OK ; 80386.
MOV SI,OFFSET error_386
Error: CALL R_Cout ; Esce per errore
RMSetup_Cursor
MOV AX,04C01H ; Exit with error = 1
INT 21H
Cpu_OK:
CALL Check_Win ; Controllo Window
CMP AL,0
JNZ SHORT Error
CALL Check_dpmi ; Controllo DPMI
CMP AL,0
JNZ SHORT Error
MOV SI,OFFSET error_v86 ; Controllo VIRTUAL 86
SMSW AX
TEST AL,1
JNZ SHORT Error
;------------------------------- LOW INIT -------------------------------------
MOV AH,48H
MOV BX,0FFFFH
INT 21H ; BX Free paragraph
PUSH BX
MOVZX EBX,BX
SHL EBX,4
MOV LOW_FREE_MEM,EBX ; EBX Low free mem
POP BX
MOV SI,OFFSET error_LowMem ; Error on BX = 0
OR BX,BX ; Out of memory.
JZ SHORT Error
MOV AH,48H ; Allocate memory
INT 21H
JC SHORT Error ; Error on Carry
; AX Start Segment
MOV LOW_START_SEG,AX
MOVZX EAX,AX
SHL EAX,4
MOV LOW_START_MEM,EAX ; EAX Low Mem START
;------------------------------- XMS INIT -------------------------------------
MOV AX,4300H
INT 2FH
CMP AL,80H
JNE SHORT No_XMS ; JMP se no XMS installed
MOV XMS_DRIVER_ON,1
PUSH ES
MOV AX,4310H
INT 2FH ; Get ES:BX xms code
MOV XMS_Control_Offset,BX ; and save it.
MOV XMS_Control_Segment,ES
POP ES
MOV AH,8
CALL [XMS_Control] ; Get free Memory
MOV SI,OFFSET error_Xms
CMP BL,0
JNZ Error ; JMP on error
PUSH AX
MOVZX EAX,AX
SHL EAX,10
MOV XMS_FREE_MEM,EAX ; Save the Value in bytes
POP DX ; Alloca tutto
MOV AH,9
CALL [XMS_Control]
TEST AX,AX ; JMP on error
JZ Error
MOV XMS_HANDLE,DX
MOV AH,0CH ; Now Lock IT!!
CALL [XMS_Control]
TEST AX,AX ; JMP on error
JZ Error
MOV DI,DX
SHL EDI,16
MOV DI,BX
MOV DWORD PTR XMS_START_MEM,EDI ; Save the linear address
JMP SHORT end_xms_init
No_XMS:
MOV XMS_DRIVER_ON,0
MOV AH,88H
INT 15H ; AX numero di K sopra 1 M
MOV SI,OFFSET error_Extended
CMP AX,64
JLE Error
SUB AX,64 ; tolgo 64 k di HMA.
MOVZX EAX,AX
SHL EAX,10
MOV XMS_FREE_MEM,EAX ; Save the Value in bytes
MOV DWORD PTR XMS_START_MEM,110000H ; Put the start point
end_xms_init:
MOV SI,OFFSET error_Extended
MOV EAX,XMS_FREE_MEM ; Valore divibile per 4 kb
AND EAX,0FFFFF000H ; per difetto.
JZ Error ; Meno di 4096 bytes
; -> Errore.
MOV XMS_FREE_MEM,EAX ; E correggi effettivo.
;--------------------------- PUSH INFORMATION ---------------------------------
SIDT FWORD PTR Old_IDTR ; Save old Real IDTR
CALL Set_GDT ; Set GDT & IDT
IN AL,PIC1_DATA ; Save Real Mask PIC
MOV PIC1Mask,AL
MOV P2R_PIC1Mask,AL
IN AL,PIC2_DATA
MOV PIC2Mask,AL
MOV P2R_PIC2Mask,AL
;************************ PREPARE FOR PROTECTED MODE ******************************
CLI ; No interrupt
Setup_irq 020H,028H ; Put the new IRQ
MOV AL,PM_PIC1Mask ; Put Protected Mask IRQ
OUT PIC1_DATA,AL
MOV AL,PM_PIC2Mask
OUT PIC2_DATA,AL
LGDT FWORD PTR GDTInfo ; Load GDTR
LIDT FWORD PTR IDTInfo ; Load IDTR
MOV EAX,CR0
OR AL,1 ; ENTERING PROTECTED
MOV CR0,EAX
JMP $+2 ; FLUSH PREFETCH
MOV AX,SelPSP
MOV DS,AX
MOV AX,SelInfo
MOV ES,AX
MOV AX,SelStart_Data
MOV FS,AX
MOV GS,AX
MOV AX,SelStack
MOV SS,AX
MOVZX ESP,SP ; ESP point at the right
; point.
MOV AX,StartTSS ; Start of the new Task
LTR AX
PUSH DWORD PTR 000011000000000010b ; Set EFLAGS
POPFD
XOR EAX,EAX ; Reset all Register
XOR EBX,EBX
XOR ECX,ECX
XOR EDX,EDX
XOR ESI,ESI
XOR EDI,EDI
XOR EBP,EBP
DB 66H
DB 67H
DB 0EAH
DD OFFSET Start
DW SelStart ; RELOAD CS:EIP
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;--------------------------- GET BACK REAL ------------------------------------
;------------------------------------------------------------------------------
; BL = return Code
CALL_BACK_REAL_MODE:
MOV AX,SelData
MOV DS,AX ; Reload segment register
MOV ES,AX ; with Real Rights
MOV FS,AX
MOV GS,AX
MOV AX,SelStack ; Use Stack 32 for
MOV SS,AX ; FLUSH IRQ
MOV ESP,DIM_STACK ; Erase all Data
CLI
MOV AL,PIC1Mask ; Put IRQ Mask for FLUSH
OUT PIC1_DATA,AL
MOV AL,PIC2Mask
OUT PIC2_DATA,AL
STI ; FLUSH ALL IRQ
MOV ECX,10000H
FLUSH: LOOP FLUSH
PUSH DWORD PTR 011000000000010b ; Reset EFLAGS and
POPFD ; Interrupt flag
MOV EAX,CR0 ; Reset Task Switch flag
AND EAX,0FFFFFFF7H ; for same real
MOV CR0,EAX ; applications.
MOV AX,SelData
MOV SS,AX ; SS and CS are OK now
MOV EAX,CR0
AND AL,NOT 1
MOV CR0,EAX ; LETS BACK REAL !!
DB 0EAH ; Reload CS and FLUSH
DW OFFSET REAL ; PREFETCH
DW Kernel_Code
REAL:
MOV AX,Kernel_Data
MOV DS,AX
MOV ES,AX ; Read all segment
MOV FS,AX
MOV GS,AX
MOV AX,Kernel_Stack
MOV SS,AX ; ESP point at the right
MOV ESP,DIM_STACK ; point? but to be sure ...
PUSH BX ; Save error code
Setup_irq 08H,70H ; Put the REAL IRQ
MOV AL,PIC1Mask ; Put REAL Mask IRQ
OUT PIC1_DATA,AL
MOV AL,PIC2Mask
OUT PIC2_DATA,AL
LIDT FWORD PTR Old_IDTR ; Put old IDTR ( REAL )
STI ; Put Interrupt ON
;----------------------------- TIMER RESET ------------------------------------
MOV AX,Int_Data
MOV GS,AX
MOV AH,0
INT 1AH
MOV AX,CX
SHL EAX,16
MOV AX,DX ; EAX Clock RM
ADD EAX,Time
MOV Time_Double,EAX ; Eax e in Time_Double
; numero clock PM + RM
MOV EBX,1800B0H
XOR EDX,EDX
DIV DWORD PTR EBX ; Calcolo il modulo
PUSH EDX
POP DX
POP CX
MOV AH,1
INT 1AH ; Setto il clock
WAIT
FINIT ; Resetta Coprocessore
WAIT
FILD QWORD PTR Time_Double
WAIT
FDIV QWORD PTR Clock_K
WAIT ; ST(0) Result
CALL Double2Long
PUSH DX
PUSH AX
POP ESI
MOV AH,2AH
INT 21H
PUSH DX
MOVZX EDX,DL
MOV EAX,ESI
ADD EAX,EDX ; EAX Numero giorni totali
POP DX
XOR EBX,EBX
MOV BL,DH ; EBX=Mese
XOR EDX,EDX ; EDX=Anno
MOV DX,CX
Rip_Go: CMP AX,Vet[EBX*2]
JBE SHORT Go_down
SUB AX,Vet[EBX*2]
INC EBX
CMP EBX,12
JBE SHORT Rip_Go
INC EDX
MOV EBX,1
JMP SHORT Rip_Go
Go_down:
MOV CX,DX
MOV DH,BL
MOV DL,AL
MOV AH,2BH
INT 21H
;------------------------------ LOW RESET -------------------------------------
MOV EAX,LOW_START_MEM
SHR EAX,4
MOV ES,AX ; ES low block
MOV AH,49H
INT 21H
JNC SHORT OVER_PASS_1 ; On Error
MOV SI,OFFSET error_LowMem_2
CALL R_Cout
OVER_PASS_1:
;------------------------------ XMS RESET -------------------------------------
CMP XMS_DRIVER_ON,0 ; Xms Driver ?
JZ SHORT _QUIT ; No --> JMP
MOV DX,XMS_HANDLE ; Unlock XMS
MOV AH,0DH
CALL [XMS_Control]
TEST AX,AX
JNZ SHORT OVER_PASS_2
MOV SI,OFFSET error_Xms2 ; Error
CALL R_Cout
OVER_PASS_2:
MOV AH,0AH ; Free XMS
CALL [XMS_Control]
TEST AX,AX
JNZ SHORT OVER_PASS_3
MOV SI,OFFSET error_Xms2 ; Error
CALL R_Cout
OVER_PASS_3:
_QUIT:
RMSetup_Cursor
POP AX ; Restore Error Code
MOV AH,04CH ; EXIT
INT 21H
;*******************************************************************************
;************************** REAL FUNCTIONS *************************************
;*******************************************************************************
Double2Long PROC NEAR
PUSH BP
MOV BP,SP
SUB SP,0AH
WAIT
FSTCW WORD PTR [BP-2]
NOP
WAIT
MOV AL,[BP-1]
OR BYTE PTR [BP-1],0CH
WAIT
FLDCW WORD PTR [BP-2]
WAIT
FISTP QWORD PTR [BP-0AH]
MOV [BP-1],AL
WAIT
FLDCW WORD PTR [BP-2]
MOV AX,[BP-0AH]
MOV DX,[BP-8]
MOV SP,BP
POP BP
RET
Double2Long ENDP
R_Cout PROC NEAR
; 0 End
; 13 End of Line
; 10 Set color --> Byte
;
PUSH EDI
PUSH ES
PUSH GS
CLD
MOV AX,Int_Data ; Load Segment
MOV GS,AX
MOV AX,0B800H
MOV ES,AX
XOR DH,DH ; Load info
MOV DL,GS:[CursorX]
MOV EDI,GS:[PosXY]
MOV AH,GS:[CurColor]
R_Cout_1: LODSB ; Start
CMP AL,0
JZ SHORT R_Cout_End
CMP AL,13
JZ SHORT R_Cout_EOL
CMP AL,10
JZ SHORT R_Cout_CC
STOSW
INC DL
INC DL
CMP DL,160
JB SHORT R_Cout_1
XOR DL,DL
CMP DI,160*25
JB SHORT R_Cout_1
CALL RNext_Page
JMP SHORT R_Cout_1
R_Cout_EOL:
SUB DI,DX
ADD DI,160
XOR DL,DL
; New Page
CMP DI,160*25
JB SHORT R_Cout_1
CALL RNext_Page
JMP SHORT R_Cout_1
R_Cout_CC:
LODSB
MOV AH,AL
JMP SHORT R_Cout_1
R_Cout_End:
MOV GS:[CursorX],DL ; Save info
MOV GS:[PosXY],EDI
MOV GS:[CurColor],AH
POP GS
POP ES
POP EDI
RET
RNext_Page:
PUSH SI
PUSH DI
PUSH EAX
PUSH CX
PUSH DS
MOV CX,0B800H
MOV DS,CX
MOV CX,160*24/4
XOR DI,DI
MOV SI,160
REP MOVSD
MOV CL,AH
MOV AL,32
SHL EAX,16
MOV AH,CL
MOV AL,32
MOV CX,160/4
REP STOSD
POP DS
POP CX
POP EAX
POP DI
POP SI
SUB DI,160
RETN
R_Cout ENDP
Check_dpmi PROC NEAR
MOV AX,01687H
INT 02FH
CMP AX,0
JZ SHORT DPMI
XOR AL,AL ; No error
RET
DPMI: MOV SI,OFFSET error_dpmi
MOV AL,1 ; Error
RET
Check_dpmi ENDP
Check_Win PROC NEAR
MOV AX,04680H
INT 02FH
CMP AX,0
JZ SHORT Find_Win
MOV AX,01600H
INT 02FH
TEST AL,07FH
JNZ SHORT Find_Win
XOR AL,AL ; No error
RET
Find_Win: MOV SI,OFFSET error_win
MOV AL,1 ; Error
RET
Check_Win ENDP
Check_CPU PROC NEAR
PUSHFD
CLI
; Intel 8086 CPU check
; Bits 12-15 of the FLAGS register are always set on the
; 8086 processor.
;
PUSHF
POP AX
MOV CX,AX ; CX Flags
AND AX,0FFFH ; Clear 12 - 15
PUSH AX
POPF ; Put new FLAGS
PUSHF ; Get new FLAGS
POP AX
AND AX,0F000H ; if bits 12-15 are
CMP AX,0F000H ; set, then CPU is 8086
JNZ SHORT Check_80286
MOV CPU_TYPE,0
MOV SI,OFFSET c8086
JMP End_Get_CPUID
; Intel 286 CPU check
; Bits 12-15 of the FLAGS register are always clear on the
; Intel 286 processor in real-address mode.
;
Check_80286:
OR CX,0F000H ; try to set bits 12-15
PUSH CX
POPF ; Put new FLAGS
PUSHF ; Get new FLAGS
POP AX
AND AX,0F000H ; if bits 12-15 clear,
JNZ SHORT Check_80386 ; CPU=80286
MOV CPU_TYPE,2
MOV SI,OFFSET c80286
JMP End_Get_CPUID
; Intel386 CPU check
; The AC bit, bit #18, is a new bit introduced in the EFLAGS
; register on the Intel486 DX CPU to generate alignment faults.
; This bit cannot be set on the Intel386 CPU.
;
Check_80386:
PUSHFD
MOV EBX,ESP
AND ESP,NOT 3 ; align stack to avoid
PUSHFD ; AC fault
POP EAX ; Get EFLAGS
XOR EAX,40000H ; Cambio bit 18
MOV ECX,EAX
PUSH EAX
POPFD ; Put EFLAGS
PUSHFD
POP EAX ; Get EFLAGS
MOV ESP,EBX
POPFD ; Restore Flag
CMP EAX,ECX ; Se uguale 486 o superiore
JZ SHORT check_80486
MOV CPU_TYPE,3
MOV SI,OFFSET c80386
JMP SHORT End_Get_CPUID
; Intel486 DX CPU, Intel487 SX NDP, and Intel486 SX CPU check
; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
; which indicates the presence of a processor
; with the ability to use the CPUID instruction.
;
check_80486:
PUSHFD
PUSHFD
POP EAX
XOR EAX,200000H ; Cambia il bit 21
MOV ECX,EAX
PUSH EAX
POPFD ; Put flags
PUSHFD
POP EAX ; Get flags
POPFD