-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest4.asm
More file actions
745 lines (643 loc) · 22.8 KB
/
test4.asm
File metadata and controls
745 lines (643 loc) · 22.8 KB
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
PAGE 118,121
TITLE TEST4 ---- 06/10/85 POST AND BIOS UTILITY ROUTINES
.286C
.LIST
CODE SEGMENT BYTE PUBLIC
PUBLIC BEEP
PUBLIC BLINK_INT
PUBLIC CMOS_READ
PUBLIC CMOS_WRITE
PUBLIC CONFTG_BAD
PUBLIC D11
PUBLIC DDS
PUBLIC DUMMY_RETURN_1
PUBLIC ERR_BEEP
PUBLIC E_MSG
PUBLIC INT_287
PUBLIC KBD_RESET
PUBLIC POST4
PUBLIC PROT_PRT_HEX
PUBLIC PROC_SHUTDOWN
PUBLIC PRT_HEX
PUBLIC PRT_SEG
PUBLIC P_MSG
PUBLIC RE_DIRECT
PUBLIC ROM_CHECK
PUBLIC ROM_CHECKSUM
PUBLIC SET_TOD
PUBLIC WAITF
PUBLIC XPC_BYTE
EXTRN E163:NEAR
EXTRN OBF_42:NEAR
EXTRN ROM_ERR:NEAR
EXTRN XMIT_8042:NEAR
ASSUME CS:CODE,DS:DATA
POST4:
;--- CMOS_READ -----------------------------------------------------------------
; READ BYTE FROM CMOS_SYSTEM CLOCK CONFIGURATION TABLE :
; :
; INPUT: (AL)= CMOS_TABLE ADDRESS TO BE READ :
; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT :
; BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ :
; :
; OUTPUT: (AL) VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS :
; ON THEN NMI LEFT DISABLED, DURING THE CMOS READ BOTH NMI AND :
; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND :
; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. :
; ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED. :
;-------------------------------------------------------------------------------
CMOS_READ PROC NEAR ; READ LOCATION (AL) INTO (AL)
PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS
ROL AL,1 ; MOVE NMI BIT TO LOW POSITION
STC ; FORCE NMI BIT ON IN CARRY FLAG
RCR AL,1 ; HIGH BIT ON TO DISABLE NMI - OLD IN CY
CLI ; DISABLE INTERRUPTS
OUT CMOS_PORT,AL ; ADDRESS LOCATION AND DISABLE NMI
NOP ; I/O DELAY
IN AL,CMOS_DATA ; READ THE REQUESTED CMOS LOCATION
PUSH AX ; SAVE (AH) REGISTER VALUE AND CMOS BYTE
MOV AL,CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
RCR AL,1 ; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
OUT CMOS_PORT,AL ; SET DEFAULT TO READ ONLY REGISTER
POP AX ; RESTORE (AH) AND (AL), CMOS BYTE
PUSH CS ; *PLACE CODE SEGMENT IN STACK AND
CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286
RET ; RETURN WITH FLAGS RESTORED
CMOS_READ ENDP
CMOS_POPF PROC NEAR ; POPF FOR LEVEL B- PARTS
IRET ; RETURN FAR AND RESTORE FLAGS
CMOS_POPF ENDP
;--- CMOS_WRITE ----------------------------------------------------------------
; WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE :
; :
; INPUT: (AL)= CMOS TABLE ADDRESS TO BE WRITTEN TO :
; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT :
; BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE :
; (AH)= NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION :
; :
; OUTPUT: VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED :
; IF BIT 7 OF (AL) IS ON, DURING THE CMOS UPDATE BOTH NMI AND :
; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND :
; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. :
; ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED. :
;-------------------------------------------------------------------------------
CMOS_WRITE PROC NEAR ; WRITE (AH) TO LOCATION (AL)
PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS
PUSH AX ; SAVE WORK REGISTER VALUES
ROL AL,1 ; MOVE NMI BIT TO LOW POSITION
STC ; FORCE NMI BIT ON IN CARRY FLAG
RCR AL,1 ; HIGH BIT ON TO DISABLE NMI - OLD IN CY
CLI ; DISABLE INTERRUPTS
OUT CMOS_PORT,AL ; ADDRESS LOCATION AND DISABLE NMI
MOV AL,AH ; GET THE DATA BYTE TO WRITE
OUT CMOS_DATA,AL ; PLACE IN REQUESTED CMOS LOCATION
MOV AL,CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
RCR AL,1 ; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
OUT CMOS_PORT,AL ; SET DEFAULT TO READ ONLY REGISTER
POP AX ; RESTORE WORK REGISTERS
PUSH CS ; PLACE CODE SEGMENT IN STACK AND
CALL CMOS_POPF ; HANDLE POPF FOR B- LEVEL 80286
RET
CMOS_WRITE ENDP
DDS PROC NEAR ; LOAD (DS) TO DATA AREA
MOV DS,CS:DDSDATA ; PUT SEGMENT VALUE OF DATA AREA INTO DS
RET ; RETURN TO USER WITH (DS)= DATA
DDSDATA DW DATA ; SEGMENT SELECTOR VALUE FOR DATA AREA
DDS ENDP
;--- E_MSG -- P MSG ------------------------------------------------------
; THIS SUBROUTINE WILL PRINT A MESSAGE ON THE DISPLAY :
; :
; ENTRY REQUIREMENTS: :
; SI = OFFSET(ADDRESS) OF MESSAGE BUFFER :
; CX = MESSAGE BYTE COUNT :
; MAXIMUM MESSAGE LENGTH IS 36 CHARACTERS :
; BP = BIT 0=E161/E162, BIT 1=CONFIG_BAD, 2-15= FIRST MSG OFFSET :
;-------------------------------------------------------------------------
E_MSG PROC NEAR
TEST SP,03FFFH ; CHECK FOR NOT FIRST ERROR MESSAGE
JNZ E_MSG1 ; SKIP IF NOT FIRST ERROR MESSAGE
PUSH SI ; SAVE MESSAGE POINTER
AND SI,03FFFH ; USE LOW 14 BITS OF MESSAGE OFFSET
OR BP,SI ; AS FIRST ERROR MESSAGE FLAG
POP SI ; (BIT 0 = E161/E162, BIT 1 = BAD_CONFIG
E_MSG1:
CALL P_MSG ; PRINT MESSAGE
PUSH DS ; SAVE CALLERS (DS)
CALL DDS ; POINT TO POST/BIOS DATA SEGMENT
TEST BYTE PTR @EQUIP_FLAG,01H ; LOOP/HALT ON ERROR SWITCH ON ?
JZ MFG_HLT ; YES - THEN GO TO MANUFACTURING HALT
POP DS ; RESTORE CALLERS (DS)
RET
MFG_HALT: ; MANUFACTURING LOOP MODE ERROR TRAP
CLI ; DISABLE INTERRUPTS
MOV AL,@MFG_ERR_FLAG ; RECOVER ERROR INDICATOR
OUT MFG_PORT,AL ; SET INTO MANUFACTURING PORT
HLT ; HALT SYSTEM
JMP MFG_HALT ; HOT NMI TRAP
E_MSG ENDP
P_MSG PROC NEAR ; DISPLAY STRING FROM (CS:)
MOV AL,CS:[SI] ; PUT CHARACTER IN (AL)
INC SI ; POINT TO NEXT CHARACTER
PUSH AX ; SAVE PRINT CHARACTER
CALL PRT_HEX ; CALL VIDEO_IO
POP AX ; RECOVER PRINT CHARACTER
CMP AL,LF ; WAS IT LINE FEED?
JNE P_MSG ; NO, KEEP PRINTING STRING
RET
P_MSG ENDP
;--- ERR BEEP -----------------------------------------------------------
; THIS PROCEDURE WILL ISSUE LONG TONES (1-3/4 SECONDS) AND ONE OR :
; MORE SHORT TONES (9/32 SECOND) TO INDICATE A FAILURE ON THE :
; PLANAR BOARD, A BAD MEMORY MODULE, OR A PROBLEM WITH THE CRT. :
; ENTRY PARAMETERS: :
; DH = NUMBER OF LONG TONES TO BEEP. :
; DL = NUMBER OF SHORT TONES TO BEEP. :
;------------------------------------------------------------------------
ERR_BEEP PROC NEAR
PUSHF ; SAVE FLAGS
CLI ; DISABLE SYSTEM INTERRUPTS
OR DH,DH ; ANY LONG ONES TO BEEP
JZ G3 ; NO, DO THE SHORT ONES
CL: ; LONG BEEPS
MOV BL,112 ; COUNTER FOR LONG BEEPS (1-3/4 SECONDS)
MOV CX,1280 ; DIVISOR FOR 932 HZ
CALL BEEP ; DO THE BEEP
MOV CX,49715 ; 2/3 SECOND DELAY AFTER LONG BEEP
CALL WAITF ; DELAY BETWEEN BEEPS
DEC DH ; ANY MORE LONG BEEPS TO DO
JNZ G1 ; LOOP TILL DONE
PUSH DS ; SAVE DS REGISTER CONTENTS
CALL DDS
CMP @MFG_TST,01H ; MANUFACTURING TEST MODE?
POP DS ; RESTORE ORIGINAL CONTENTS OF (DS)
JE MFG_HALT ; YES - STOP BLINKING LED
G3: ; SHORT BEEPS
MOV BL,18 ; COUNTER FOR A SHORT BEEP (9/32
MOV CX,1208 ; DIVISOR FOR 987 HZ
CALL BEEP ; DO THE SOUND
MOV CX,33144 ; 1/2 SECOND DELAY AFTER SHORT BEEP
CALL WAITF ; DELAY BETWEEN BEEPS
DEC DL ; DONE WITH SHORT BEEPS COUNT
JNZ G3 ; LOOP TILL DONE
MOV CX,33144 ; 1/2 SECOND DELAY AFTER LAST BEEP
CALL WAITF ; MAKE IT ONE SECOND DELAY BEFORE RETURN
POPF ; RESTORE FLAGS TO ORIGINAL SETTINGS
RET ; RETURN TO CALLER
ERR_BEEP ENDP
;--- BEEP ----------------------------------------------------------------
; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE :
; ENTRY: :
; (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND ) :
; (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ) :
; EXIT: :
; (AX),(BL),(CX) MODIFIED. :
;-------------------------------------------------------------------------
BEEP PROC NEAR ; SETUP TIMER 2
PUSHF ; SAVE INTERRUPT STATUS
CLI ; BLOCK INTERRUPTS DURING UPDATE
MOV AL,10110110B ; SELECT TIMER 2,LSB,MSB,BINARY
OUT TIMER+3,AL ; WRITE THE TIMER MODE REGISTER
JMP $+2 ; I/O DELAY
MOV AL,CL ; DIVISOR FOR HZ (LOW)
OUT TIMER+2,AL ; WRITE TIMER 2 COUNT - LSB
JMP $+2 ; I/O DELAY
MOV AL,CH ; DIVISOR FOR HZ (HIGH)
OUT TIMER+2,AL ; WRITE TIMER 2 COUNT - MSB
IN AL,PORT_B ; GET CURRENT SETTING OF PORT
MCV AH,AL ; SAVE THAT SETTING
OR AL,GATE2+SPK2 ; GATE TIMER 2 AND TURN SPEAKER ON
OUT PORT_B,AL ; AND RESTORE INTERRUPT STATUS
POPF
G7: ; 1/64 SECOND PER COUNT (BL)
MOV CX,1035 ; DELAY COUNT FOR 1164 OF A SECOND
CALL WAITF ; GO TO BEEP DELAY 1/64 COUNT
DEC BL ; (BL) LENGTH COUNT EXPIRED?
JNZ G7 ; NO - CONTINUE BEEPING SPEAKER
PUSHF ; SAVE INTERRUPT STATUS
CLI ; BLOCK INTERRUPTS DURING UPDATE
IN AL,PORT_B ; GET CURRENT PORT VALUE
OR AL,NOT (GATE2+SPK2) ; ISOLATE CURRENT SPEAKER BITS N CASE
AND AH,AL ; SOMEONE TURNED THEM OFF DURING BEEP
MOV AL,AH ; RECOVER VALUE OF PORT
AND AL,NOT (GATE2+SPK2) ; FORCE SPEAKER DATA OFF
OUT PORT_B,AL ; AND STOP SPEAKER TIMER
POPF ; RESTORE INTERRUPT FLAG STATE
MOV CX,1035 ; FORCE 1/64 SECOND DELAY (SHORT)
CALL WAITF ; MINIMUM DELAY BETWEEN ALL BEEPS
PUSHF ; SAVE INTERRUPT STATUS
CLI ; BLOCK INTERRUPTS DURING UPDATE
IN AL,PORT_B ; GET CURRENT PORT VALUE IN CASE
AND AL,GATE2+SPK2 ; SOMEONE TURNED THEM ON
OR AL,AH ; RECOVER VALUE OF PORT_B
OUT PORT_B,AL ; RESTORE SPEAKER STATUS
POPF ; RESTORE INTERRUPT FLAG STATE
RET
BEEP ENDP
;--- WAITF ---------------------------------------------------------------
; FIXED TIME WAIT ROUTINE HARDWARE CONTROLLED - NOT PROCESSOR) :
; :
; ENTRY: :
; (CX) = COUNT OF 15.,085737 MICROSECOND INTERVALS TO WAIT :
; MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE :
; EXIT: :
; AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS) :
; (CX) = 0 :
;-------------------------------------------------------------------------
WAITF PROC NEAR ; DELAY FOR (CX)*15.085737 US
PUSH AX ; SAVE WORK REGISTER (AH)
WAITFI: ; USE TIMER 1 OUTPUT BITS
IN AL,PORT_B ; READ CURRENT COUNTER OUTPUT STATUS
AND AL,REFRESH_BIT ; MASK FOR REFRESH DETERMINE BIT
CMP AL,AH ; DID IT JUST CHANGE
JE WAITF1 ; WAIT FOR A CHANCE IN OUTPUT LINE
MOV AH,AL ; SAVE NEW FLAG STATE
LOOP WAITF1 ; DECREMENT HALF CYCLES TILL COUNT END
POP AX ; RESTORE (AH)
RET ; RETURN (CX)= 0
WAITF ENDP
;--- CONFIG_BAD ----------------------------------------------------------
; SET CMOS_DIAG WITH CONFIG ERROR BIT (WITH NMI DISABLED) :
; (BP) BIT 14 SET ON TO INDICATE CONFIGURATION ERROR :
;-------------------------------------------------------------------------
CONFIG_BAD PROC NEAR
PUSH AX
MOV AX,X*(CMOS_DIAG+NMI) ; ADDRESS CMOS DIAGNOSTIC STATUS BYTE
CALL CMOS_READ ; GET CURRENT VALUE
OR AL,BAD_CONFIG ; SET BAD CONFIGURATION BIT
XCHG AH,AL ; SETUP FOR WRITE
CALL CMOS_WRITE ; UPDATE CMOS WITH BAD CONFIGURATION
POP AX
OR BP,04000H ; SET CONFIGURATION BAD FLAG IN (BP)
RET
CONFIG_BAD ENDP
;--- XPC_BYTE -- XLATE_PR -- PRT_HEX -------------------------------------
; :
; CONVERT AND PRINT ASCII CODE CHARACTERS :
; :
; AL CONTAINS NUMBER TO BE CONVERTED. :
; AX AND BX DESTROYED. :
;-------------------------------------------------------------------------
XPC_BYTE PROC NEAR ; DISPLAY TWO HEX DIGITS
PUSH AX ; SAVE FOR LOW NIBBLE DISPLAY
SHR AL,4 ; NIBBLE SWAP
CALL XLAT_PR ; DO THE HIGH NIBBLE DISPLAY
POP AX ; RECOVER THE NIBBLE
AND AL,0FH ; ISOLATE TO LOW NIBBLE
; FALL INTO LOW NIBBLE CONVERSION
XLAT_PR PROC NEAR ; CONVERT 00-0F TO ASCII CHARACTER
ADD AL,090H ; ADD FIRST CONVERSION FACTOR
DAA ; ADJUST FOR NUMERIC AND ALPHA RANGE
ADC AL,040H ; ADD CONVERSION AND ADJUST LOW NIBBLE
DAA ; ADJUST HIGH NIBBLE TO ASCII RANGE
PRT-HEX PROC NEAR
MOV AH,0EH ; DISPLAY CHARACTER IN (AL) COMMAND
MOV BH,0
INT 10H ; CALL VIDEO_IO
RET
PRT_HEX ENDP
XLAT_PR ENDP
XPC_BYTE ENDP
;--- PRT_SEG ----------------------------------------------------
; PRINT A SEGMENT VALUE TO LOOK LIKE A 21 BIT ADDRESS :
; DX MUST CONTAIN SEGMENT VALUE TO BE PRINTED :
;----------------------------------------------------------------
PRT_SEG PROC NEAR
MOV AL,DH ; GET MSB
CALL XPC_BYTE ; DISPLAY SEGMENT HIGH BYTE
MOV AL,DL ; LSB
CALL XPC_BYTE ; DISPLAY SEGMENT LOW BYTE
MOV AL,'0' ; PRINT A '0 '
CALL PRT_HEX ; TO MAKE LOOK LIKE ADDRESS
MOV AL,' ' ; ADD ENDING SPACE
CALL PRT_HEX
RET
PRT_SEG ENDP
;--- PROT_PRT_HEX -------------------------------------------------------
; :
; PUT A CHARACTER TO THE DISPLAY BUFFERS WHEN IN PROTECTED MODE :
; :
; (AL)= ASCII CHARACTER :
; (DI)= DISPLAY REGEN BUFFER POSITION :
;------------------------------------------------------------------------
PROT_PRT_HEX PROC NEAR
PUSH ES ; SAVE CURRENT SEGMENT REGISTERS
PUSH DI
SAL DI,1 ; MULTIPLY OFFSET BY TWO
;----- MONOCHROME VIDEO CARD
PUSH BYTE PTR C_BWCRT_PTR ; GET MONOCHROME BUFFER SEGMENT SELECTOR
POP ES ; SET (ES) TO B/W DISPLAY BUFFER
STOSB ; PLACE CHARACTER IN SUPPER
DEC DI ; ADJUST POINTER BACK
; ----- ENHANCED GRAPHICS ADAPTER
PUSH BYTE PTR E_CCRT_PTR ; ENHANCED COLOR DISPLAY POINTER LOW 64K
POP ES ; LOAD SEGMENT SELECTOR
STOSB ; PLACE CHARACTER IN BUFFER
DEC DI ; ADJUST POINTER BACK
PUSH BYTE PTR E_CCRT_PTR2 ; ENHANCED COLOR DISPLAY POINTER HI 64K
POP ES ; LOAD SEGMENT SELECTOR
STOSB ; PLACE CHARACTER IN BUFFER
DEC DI ; ADJUST POINTER BACK
;----- COMPATIBLE COLOR
PUSH BYTE PTR C_CCRT_PTR ; SET (OS) TO COMPATIBLE COLOR MEMORY
POP ES
PUSH BX ; SAVE WORK REGISTERS
PUSH DX
PUSH CX
XOR CX,CX ; TIMEOUT LOOP FOR "BAD" HARDWARE
MOV DX,03DAH ; STATUS ADDRESS OF COLOR CARD
XCHG AX,BX ; SAVE IN (BX) REGISTER
PROT_S:
IN AL,DX ; GET COLOR CARD STATUS
TEST AL,RVRT+RHRZ ; CHECK FOR VERTICAL RETRACE (OR HORZ)
LOOPZ PROT_S ; TIMEOUT LOOP TILL FOUND
XCHG AX,BX ; RECOVER CHARACTERS
STOSB ; PLACE CHARACTER IN BUFFER
POP CX ; RESTORE REGISTERS
POP DX
POP BX
POP DI
POP ES
RET
PROT_PRT_HEX ENDP
;------------------------------------------
; ROM CHECKSUM SUBROUTINE :
;------------------------------------------
RoM_CHECKSUM PROC NEAR
SUB CX,CX ; NUMBER OF BYTES TO ADD IS 64K
ROM_CHECKSUM_CNT: ; ENTRY FOR OPTIONAL ROM TEST
XOR AL,AL
ROM-L:
ADD AL,[BX] ; GET (DS:BX)
INC BX ; POINT TO NEXT BYTE
LOOP ROM_L ; ADD ALL BYTES IN ROM MODULE
OR AL,AL ; SUM = 0?
RET
ROM_CHECKSUM ENDP
;------------------------------------------------------------------------
; THIS ROUTINE CHECKSUMS OPTIONAL ROM MODULES AND :
; IF CHECKSUM IS OK, CALLS INITIALIZATION/TEST CODE IN MODULE :
;------------------------------------------------------------------------
ROM_CHECK PROC NEAR
MOV AX,DATA ; POINT ES TO DATA AREA
MOY ES,AX
SUB AH,AH ; ZERO OUT AH
MOV AL,[BX+2] ; GET LENGTH INDICATOR
SHL AX,9 ; MULTIPLY BY 512
MOV CX,AX ; SET COUNT
SHR AX,4
ADD DX,AX ; SET POINTER TO NEXT MODULE
CALL ROM_CHECKSUM_CNT ; DO CHECKSUM
JZ ROM_CHECK_1
CALL ROM_ERR ; POST CHECKSUM ERROR
JMP SHONT ROM_CHECK_END ; AND EXIT
ROM_CHECK_1:
PUSH DX ; SAVE POINTER
MOV ES:@IO_ROM_INIT,0003H ; LOAD OFFSET
MOV ES:@IO_ROM_SEG,DS ; LOAD SEGMENT
CALL DWORD PTR ES:@IO_ROM_INIT ; CALL INITIALIZE/TEST ROUTINE
POP DX
ROM_CHECK_END:
RET ; RETURN TO CALLER
ROM_CHECK ENDP
;--- KBD_RESET-----------------------------------------------------------
; THIS PROCEDURE WILL SEND A SOFTWARE RESET TO THE KEYBOARD. :
; SCAN CODE 0AAH SHOULD BE RETURNED TO THE PROCESSOR. :
; SCAN CODE 065H IS DEFINED FOR MANUFACTURING TEST :
;------------------------------------------------------------------------
KBD_RESET PROC NEAR
MOV AL,0FFH ; SET KEYBOARD RESET COMMAND
CALL XMIT_8042 ; GO ISSUE THE COMMAND
JCXZ G13 ; EXIT IF ERROR
CMP AL,KB_ACK
JNZ G13
MOV AL,0FDH ; ENABLE KEYBOARD INTERRUPTS
OUT INTA01,AL ; WRITE 8259 INTERRUPT MASK REGISTER
MOV @INTR_FLAG,0 ; RESET INTERRUPT INDICATOR
STI ; ENABLE INTERRUPTS
MOV BL,10 ; TRY FOR 400 MILLISECONDS
SUB CX,CX ; SETUP INTERRUPT TIMEOUT COUNT
G11:
TEST @INTR_FLAG,02H ; DID A KEYBOARD INTERRUPT OCCUR 7
JNZ G12 ; YES - READ SCAN CODE RETURNED
LOOP GI1 ; NO - LOOP TILL TIMEOUT
DEC BL
JNZ G11 ; TRY AGAIN
G12:
IN AL,PORT_A ; READ KEYBOARD SCAN CODE
MOV BL,AL ; SAVE SCAN CODE JUST READ
G13:
RET ; RETURN TO CALLER
KBD_RESET ENDP
;--------------------------------------------------------
; BLINK LED PROCEDURE FOR MFG RUN-IN TESTS :
; IF LED IS ON, TURN IT OFF. IF OFF, TURN ON. :
;--------------------------------------------------------
BLINK_INT PROC NEAR
STI
PUSH AX ; SAVE AX REGISTER CONTENTS
IN AL,MFG_PORT ; READ CURRENT VALUE OF MFG_PORT
XOR AL,01000000B ; FLIP CONTROL BIT
OUT MFG_PORT,AL
MOY AL,EOI
OUT INTA00,AL
POP AX ; RESTORE AX REGISTER
IRET
BLINK_INT ENDP
;-------------------------------------------------------------------------------
; THIS ROUTINE INITIALIZES THE TIMER DATA AREA IN THE ROM BIOS :
; DATA AREA. IT IS CALLED BY THE POWER ON ROUTINES. IT CONVERTS :
; HR:MIN:SEC FROM CMOS TO TIMER TICS. IF CMOS IS INVALID, TIMER :
; IS SET TO ZERO. :
; :
; INPUT NONE PASSED TO ROUTINE BY CALLER :
; CMOS LOCATIONS USED FOR TIME :
; ;
; OUTPUT @TIMER_LOW :
; @TIMER_HIGH :
; @TIMER_OFL :
; ALL REGISTERS UNCHANGED :
;-------------------------------------------------------------------------------
COUNTS_SEC EQU 18 ; TIMER DATA CONVERSION EQUATES
COUNTS_MIN EQU 1092
COUNTS_HOUR EQU 7 ; 65543 - 65536
UPDATE_TIMER EQU 10000000B ; RTC UPDATE IN PROCESS BIT MASK
SET_TOD PROC NEAR
PUSHA
PUSH DS
CALL DDS ; ESTABLISH SEGMENT
SUB AX,AX
MOV @TIMER_OFL,AL ; RESET TIMER ROLL OVER INDICATOR
MOV @TIMER_LOW,AX ; AND TIMER COUNT
MOV @TIMER_HIGH,AX
MOV AL,CMOS_DIAG+NMI ; CHECK CMOS VALIDITY
CALL CMOS_READ ; READ DIAGNOSTIC LOCATION IN CMOS
AND AL,BAD_BAT+BAD_CKSUM+CMOS_CLK_FAIL
SUB CX,CX ; BAD BATTERY, CHKSUM ERROR, CLOCK ERROR
JNZ POD_DONE ; CMOS NOT VALID -- TIMER SET TO ZERO
UIP:
MOV AL,CMOS_REG_A+NMI ; ACCESS REGISTER A
CALL CMOS_READ ; READ CMOS CLOCK REGISTER A
TEST AL,UPDATE_TIMER
LOOPZ UIP ; WAIT TILL UPDATE BIT IS ON
JCXZ POD_DONE ; CMOS CLOCK STUCK IF TIMEOUT
UIPOFF:
MOV AL,CMOS_REG_A+NMI ; ACCESS REGISTER A
CALL CMOS_READ ; READ CMOS CLOCK REGISTER A
TEST AL,UPDATE_TIMFR
LOOPNZ UIPOFF ; NEXT WAIT TILL END OF UPDATE
JCXZ POD_DONE ; CMOS CLOCK STUCK IF TIMEOUT
MOV AL,CMOS_SECONDS+NMI ; TIME JUST UPDATED
CALL CMOS_READ ; ACCESS SECONDS VALUE IN CMOS
CMP AL,59H ; ARE THE SECONDS WITHIN LIMITS?
JA TOD_ERROR ; GO IF NOT
CALL CVT_BINARY ; CONVERT IT TO BINARY
MOV CX,AX ; MOVE COUNT TO ACCUMULATION REGISTER
SHR CX,2 ; ADJUST FOR SYSTEMATIC SECONDS ERROR
MOV BL,COUNTS_SEC
MUL BL ; COUNT FOR SECONDS
ADD CX,AX
MOV AL,CMOS_MINUTES+NMI
CALL CMOS_READ ; ACCESS MINUTES VALUE IN CMOS
CMP AL,59H ; ARE THE MINUTES WITHIN LIMITS?
JA TOD_ERROR ; GO IF NOT
CALL CYT_BINARY ; CONVERT IT TO BINARY
PUSH AX ; SAVE MINUTES COUNT
SHR AX,1 ; ADJUST FOR SYSTEMATIC MINUTES ERROR
ADD CX,AX ; ADD ADJUSTMENT TO COUNT
POP AX ; RECOVER BCD MINUTES VALUE
MOV BX,COUNTS_MIN
MUL BX ; COUNT FOR MINUTES
ADD CX,AX ; ADD TO ACCUMULATED VALUE
MOV AL,CMOS_HOURS+NMI
CALL CMOS_READ ; ACCESS HOURS VALUE IN CMOS
CMF AL,23H ; ARE THE HOURS WITHIN LIMITS?
JA TOD_ERROR ; GO IF NOT
CALL CVT_BINARY ; CONVERT IT TO BINARY
MOV DX,AX
MOV BL,COUNTS_HOUR
MUL BL ; COUNT FOR HOURS
ADD AX,CX
ADC DX,0000H
MOV @TIMER_HIGH,DX
MOV @TIMER_LOW,AX
POD_DONE:
POP DS
POPA
RET
TOD_ERROR:
POP DS ; RESTORE SEGMENT
POPA ; RESTORE REGISTERS
MOV SI,OFFSET E163 ; DISPLAY CLOCK ERROR
CALL E_MSG
MOV AX,X*(CMOS_DIAG+NMI) ; SET CLOCK ERROR IN STATUS
CALL CMOS_READ ; READ DIAGNOSTIC CMOS LOCATION
OR AL,CMOS_CLK_FAIL ; SET NEW STATUS WITH CMOS CLOCK ERROR
XCHG AL,AH ; MOVE NEW STATUS TO WORK REGISTER
CALL CMOS_WRITE ; UPDATE STATUS LOCATION
RET
SET_TOD ENDP
CVT_BINARY PROC NEAR
MOV AH,AL ; UNPACK 2 BCD DIGITS IN AL
SHR AH,4
AND AL,0FH ; RESULT IS IN AX
AAD ; CONVERT UNPACKED BCD TO BINARY
RET
CVT_BINARY ENDP
;--- D11 -- INT ?? H - ( IRQ LEVEL ?? ) ---------------------------------------
; TEMPORARY INTERRUPT SERVICE ROUTINE FOR POST :
; :
; THIS ROUTINE IS ALSO LEFT IN PLACE AFTER THE POWER ON DIAGNOSTICS :
; TO SERVICE UNUSED INTERRUPT VECTORS. LOCATION "@INTR_FLAG" WILL :
; CONTAIN EITHER: :
; 1) LEVEL OF HARDWARE INTERRUPT THAT CAUSED CODE TO BE EXECUTED, OR :
; 2) "FF" FOR A NON-HARDWARE INTERRUPT THAT WAS EXECUTED ACCIDENTALLY.:
;------------------------------------------------------------------------------
D11 PROC NEAR
PUSH AX ; SAVE REGISTER AX CONTENTS
PUSH BX
MOV AL,0BH ; READ IN-SERVICE REGISTER
OUT INTA00,AL ; (FIND OUT WHAT LEVEL BEING
JMP $+2 ; SERVICED)
IN AL,INTA00 ; GET LEVEL
MOV AH,AL ; SAVE IT
OR AL,AH ; 00? (NO HARDWARE ISR ACTIVE)
JNZ HW_INT
MOV AH,0FFH
JMP SHORT SET_INTR_FLAG ; SET FLAG TO "FF" IF NON-HARDWARE
HW_INT:
MOV AL,0BH ; READ IN-SERVICE REGISTER FROM
OUT INTB00,AL ; INTERRUPT CHIP #2
JMP $+2 ; I/O DELAY
IN AL,INTB00 ; CHECK THE SECOND INTERRUPT CHIP
MOV BH,AL ; SAVE IT
OR BH,BH
JZ NOT_SEC ; CONTINUE IF NOT
IN AL,INTB01 ; GET SECOND INTERRUPT MASK
OR AL,BH ; MASK OFF LEVEL BEING SERVICED
JMP $+2 ; I/O DELAY
OUT INTB01,AL
MOV AL,EOI ; SEND EOI TO SECOND CHIP
JMP $+2 ; I/O DELAY
OUT INTB00,AL
JMP SHORT IS_SEC
NOT_SEC:
IN AL,INTA01 ; GET CURRENT MASK VALUE
JMP $+2 ; I/O DELAY
AND AH,0FBH ; DO NOT DISABLE SECOND CONTROLLER
OR AL,AH ; MASK OFF LEVEL BEING SERVICED
OUT INTA01,AL ; SET NEW INTERRUPT MASK
JMP $+2 ; I/O DELAY
IS_SEC:
MOV AL,EOI
OUT INTA00,AL
SET_INTR_FLAG:
POP BX ; RESTORE (BX) FROM STACK
PUSH DS ; SAVE ACTIVE (DS)
CALL DDS ; SET DATA SEGMENT
MOV @INTR_FLAG,AH ; SET FLAG
POP DS
POP AX ; RESTORE REGISTER AX CONTENTS
DUMMY_RETURN_1: ; NEED IRET FOR VECTOR TABLE
IRET
D11 ENDP
;--- HARDWARE INT 71 H -- ( IRQ LEVEL 9 ) -- TO INT 0A H ---------------------
; REDIRECT SLAVE INTERRUPT 9 TO INTERRUPT LEVEL 2 :
; THIS ROUTINE FIELDS LEVEL 9 INTERRUPTS AND :
; CONTROL IS PASSED TO WASTER INTERRUPT LEVEL 2 :
;------------------------------------------------------------------------------
RE_DIRECT PROC NEAR
PUSH AX ; SAVE (AX)
MOV AL,EOI
OUT INTB00,AL ; EOI TO SLAVE INTERRUPT CONTROLLER
POP AX ; RESTORE [AX]
INT 0AH ; GIVE CONTROL TO HARDWARE LEVEL 2
IRET ; RETURN
RE_DIRECT ENDP
;--- HARDWARE INT 75 H -- ( IRO LEVEL 13 ) ------------------------------------
; SERVICE X287 INTERRUPTS :
; THIS ROUTINE FIELDS X287 INTERRUPTS AND CONTROL :
; IS PASSED TO THE NMI INTERRUPT HANDLER FOR :
; COMPATIBILITY. :
;------------------------------------------------------------------------------
INT_287 PROC NEAR
PUSH AX ; SAVE (AX)
XOR AL,AL
OUT X287,AL ; REMOVE THE INTERRUPT REQUEST
MOV AL,EOI ; ENABLE THE INTERRUPT
OUT INTB00,AL ; THE SLAVE
OUT INTA00,AL ; THE MASTER
POP AX ; RESTORE (AX)
INT 02H ; GIVE CONTROL TO NMI
IRET ; RETURN
INT_287 ENDP
PROC_SHUTDOWN PROC ; COMMON 80286 SHUTDOWN WAIT
MOV AL,SHUT_CMD ; SHUTDOWN COMMAND
OUT STATUS_PORT,AL ; SEND TO KEYBOARD CONTROL PORT
PROC_S:
HLT ; WAIT FOR 80256 RESET
JMP PROC_S ; INSURE HALT
PROC_SHUTDOWN ENDP
CODE ENDS
END