-
Notifications
You must be signed in to change notification settings - Fork 0
/
video.asm
1930 lines (1773 loc) · 59.9 KB
/
video.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
PAGE 118,121
TITLE VIDEO1 --- 06/10/85 VIDEO DISPLAY BIOS
.286C
.LIST
CODE SEGMENT BYTE PUBLIC
PUBLIC ACT_DISP_PAGE
PUBLIC READ_AC_CURRENT
PUBLIC READ_CURSOR
PUBLIC READ_DOT
PUBLIC READ_LPEN
PUBLIC SCROLL_DOWN
PUBLIC SCROLL_UP
PUBLIC SET_COLOR
PUBLIC SET_CPOS
PUBLIC SET_CTYPE
PUBLIC SET_MODE
PUBLIC WRITE_AC_CURRENT
PUBLIC WRITE_C_CURRENT
PUBLIC WRITE_DOT
PUBLIC WRITE_TTY
PUBLIC VIDEO_IO_1
PUBLIC VIDEO_STATE
EXTRN BEEP:NEAR ; SPEAKER BEEP ROUTINE
EXTRN CRT_CHAR_GEN:NEAR ; CHARACTER GENERATOR GRAPHICS TABLE
EXTRN DSS:NEAR ; LOAD (DS) WITH DATA SEGMENT SELECTOR
EXTRN M5:WORD ; REGEN BUFFER LENGTH TABLE
EXTRN M6:BYTE ; COLUMNS PER MODE TABLE
EXTRN M7:BYTE ; MODE SET VALUE PER MODE TABLE
;--- INT 10 H -------------------------------------------------------------------
; VIDEO_IO :
; THESE ROUTINES PROVIDE THE CRT DISPLAY INTERFACE :
; THE FOLLOWING FUNCTIONS ARE PROVIDED: :
; :
; (AH)= 00H SET MODE (AL) CONTAINS MODE VALUE :
; (AL) = 00H 40X25 BW MODE (POWER ON DEFAULT) :
; (AL) = 01H 40X25 COLOR :
; (AL) = 02H 80X25 BW :
; (AL) = 03H 80X25 COLOR :
; GRAPHICS MODES :
; (AL) = 04H 320X200 COLOR :
; (AL) = 05H 320X200 BW MODE :
; (AL) = 06H 640X200 BW MODE :
; (AL) = 07H 80X25 MONOCHROME (USED INTERNAL TO VIDEO ONLY) :
; *** NOTES -BW MODES OPERATE SAME AS COLOR MODES, BUT COLOR :
; BURST IS NOT ENABLED :
; -CURSOR IS NOT DISPLAYED IN GRAPHICS MODE :
; (AH)= 01H SET CURSOR TYPE :
; (CH) = BITS 4-0 = START LINE FOR CURSOR :
; ** HARDWARE WILL ALWAYS CAUSE BLINK :
; ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING :
; OR NO CURSOR AT ALL :
; (CL) = BITS 4-0 = END LINE FOR CURSOR :
; (AH)= 02H SET CURSOR POSITION :
; (DH,DL) = ROW,COLUMN (00H,00H) IS UPPER LEFT :
; (BH) = A PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES) :
; (AH)= 03H READ CURSOR POSITION :
; (BH) = PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES) :
; ON EXIT (DH,DL) = ROW,COLUMN OF CURRENT CURSOR :
; (CH,CL) = CURSOR MODE CURRENTLY SET :
; (AH)= 04H READ LIGHT PEN POSITION :
; ON EXIT: :
; (AH) = 00H -- LIGHT PEN SWITCH NOT DOWN/NOT TRIGGERED :
; (AH) = 01H -- VALID LIGHT PEN VALUE IN REGISTERS :
; (DH,DL) = ROW,COLUMN OF CHARACTER LP POSITION :
; (CH) = RASTER LINE (0-199) :
; (BX) = PIXEL COLUMN (0-319,639) :
; (AH)= 05H SELECT ACTIVE DISPLAY PAGE (VALID ONLY FOR ALPHA MODES) :
; (AL) = NEW PAGE VALUE (0-7 FOR MODES 0&1, 0-3 FOR MODES 2&3) :
; (AH)= 06H SCROLL ACTIVE PAGE UP :
; (AL) = NUMBER OF LINES. ( LINES BLANKED AT BOTTOM OF WINDOW ) :
; (AL) = 00H MEANS BLANK ENTIRE WINDOW :
; (CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL :
; (DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL :
; (BH) = ATTRIBUTE TO BE USED ON BLANK LINE :
; (AH)= 07H SCROLL ACTIVE PAGE DOWN :
; (AL) = NUMBER OF LINES, INPUT LINES BLANKED AT TOP OF WINDOW :
; (AL) = 00H MEANS BLANK ENTIRE WINDOW :
; (CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL :
; (DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL :
; (BH) = ATTRIBUTE TO BE USED ON BLANK LINE :
; :
; CHARACTER HANDLING ROUTINES :
; :
; (AH)= 08H READ ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION :
; (BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY) :
; ON EXIT: :
; (AL) = CHAR READ :
; (AH) = ATTRIBUTE OF CHARACTER READ (ALPHA MODES ONLY) :
; (AH)= 09H WRITE ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION :
; (BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY) :
; (CX) = COUNT OF CHARACTERS TO WRITE :
; (AL) = CHAR TO WRITE :
; (BL) = ATTRIBUTE OF CHARACTER (ALPHA)/COLOR OF CHAR (GRAPHICS) :
; SEE NOTE ON WRITE DOT FOR BIT 7 OF BL = 1. :
; (AH) = 0AH WRITE CHARACTER ONLY AT CURRENT CURSOR POSITION :
; (BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY) :
; (CX) = COUNT OF CHARACTERS TO WRITE :
; (AL) = CHAR TO WRITE :
; NOTE: USE FUNCTION (AH)= 09H IN GRAPHICS MODES :
; FOR READ/WRITE CHARACTER INTERFACE WHILE IN GRAPHICS MODE, THE :
; CHARACTERS ARE FORMED FROM A CHARACTER GENERATOR IMAGE :
; MAINTAINED IN THE SYSTEM ROM. ONLY THE 1ST 128 CHARS :
; ARE CONTAINED THERE. TO READ/WRITE THE SECOND 128 CHARS, :
; THE USER MUST INITIALIZE THE POINTER AT INTERRUPT 1FH :
; (LOCATION 0007CH) TO POINT TO THE 1K BYTE TABLE CONTAINING :
; THE CODE POINTS FOR THE SECOND 128 CHARS (128-255). :
; FOR WRITE CHARACTER INTERFACE IN GRAPHICS MODE, THE REPLICATION FACTOR :
; CONTAINED IN (CX) ON ENTRY WILL PRODUCE VALID RESULTS ONLY :
; FOR CHARACTERS CONTAINED ON THE SAME ROW. CONTINUATION TO :
; SUCCEEDING LINES WILL NOT PRODUCE CORRECTLY. :
; :
; GRAPHICS INTERFACE :
; (AH)= 0BH SET COLOR PALETTE :
; (BH) = PALETTE COLOR ID BEING SET (0-127) :
; (BL) = COLOR VALUE TO BE USED WITH THAT COLOR ID :
; NOTE: FOR THE CURRENT COLOR CARD, THIS ENTRY POINT HAS :
; MEANING ONLY FOR 320X200 GRAPHICS. :
; COLOR ID = 0 SELECTS THE BACKGROUND COLOR (0-15) :
; COLOR ID = 1 SELECTS THE PALETTE TO BE USED: :
; 0 = GREEN(1)/RED(2)/YELLOW(3) :
; 1 = CYAN(1)/MAGENTA(2)/WHITE(3) :
; IN 40X25 OR 80X25 ALPHA MODES, THE VALUE SET FOR :
; PALETTE COLOR 0 INDICATES THE BORDER COLOR :
; TO BE USED (VALUES 0-31, WHERE 16-31 SELECT :
; THE HIGH INTENSITY BACKGROUND SET. :
; (AH)= 0CH WRITE DOT :
; (DX) = ROW NUMBER :
; (CX) = COLUMN NUMBER :
; (AL) = COLOR VALUE :
; IF BIT 7 OF AL = 1, THEN THE COLOR VALUE IS EXCLUSIVE :
; ORed WITH THE CURRENT CONTENTS OF THE DOT :
; (AH)= ODH READ DOT :
; (DX) = ROW NUMBER :
; (CX) = COLUMN NUMBER :
; (AL) = RETURNS THE DOT READ :
; :
; ASCII TELETYPE ROUTINE FOR OUTPUT :
; :
; (AH)= 0EH WRITE TELETYPE TO ACTIVE PAGE :
; (AL) = CHAR TO WRITE :
; (BL) = FOREGROUND COLOR IN GRAPHICS MODE :
; NOTE -- SCREEN WIDTH IS CONTROLLED BY PREVIOUS MODE SET :
; (AH)= 0FH CURRENT VIDEO STATE :
; RETURNS THE CURRENT VIDEO STATE :
; (AL) = MODE CURRENTLY SET ( SEE (AH)=00H FOR EXPLANATION) :
; (AH) = NUMBER OR CHARACTER COLUMNS ON SCREEN :
; (BH) = CURRENT ACTIVE DISPLAY PAGE :
; (AH)= 10H RESERVED :
; (AH)= 11H RESERVED :
; (AH)= 12H RESERVED :
; (AH)= 13H WRITE STRING :
; ES:BP - POINTER T0 STRING TO BE WRITTEN :
; CX - LENGTH OF CHARACTER STRING TO WRITTEN :
; DX - CURSOR POSITION FOR STRING TO BE WRITTEN :
; BH - PAGE NUMBER :
; (AL)= 00H WRITE CHARACTER STRING :
; BL - ATTRIBUTE :
; STRING IS <CHAR,CHAR, ... ,CHAR> :
; CURSOR NOT MOVED :
; (AL)= 01H WRITE CHARACTER STRING AND MOVE CURSOR :
; BL - ATTRIBUTE :
; STRING IS <CHAR,CHAR, ... ,CHAR> :
; CURSOR MOVED :
; (AL)= 02H WRITE CHARACTER AND ATTRIBUTE STRING :
; (VALID FOR ALPHA MODES ONLY) :
; STRING IS <CHAR,ATTR,CHAR,ATTR .. ,CHAR,ATTR> :
; CURSOR IS NOT MOVED :
; (AL)= 03H WRITE CHARACTER AND ATTRIBUTE STRING AND MOVE CURSOR :
; (VALID FOR ALPHA MODES ONLY) :
; STRING IS <CHAR,ATTR,CHAR,ATTR .. ,CHAR,ATTR> :
; CURSOR IS MOVED :
; NOTE: CARRIAGE RETURN, LINE FEED, BACKSPACE, AND BELL ARE :
; TREATED AS COMMANDS RATHER THAN PRINTABLE CHARACTERS. :
; ;
; BX,CX,DX,SI,DI,BP,SP,DS,ES,SS PRESERVED DURING CALLS EXCEPT FOR :
; BX,CX,DX RETURN VALUES ON FUNCTIONS 03H,04H,0DH AND 0FH. ON ALL CALLS :
; AX IS MODIFIED. :
;--------------------------------------------------------------------------------
ASSUME CS:CODE,DS:DATA,ES:NOTHING
M1 DW OFFSET SET_MOOE ; TABLE OF ROUTINES WITHIN VIDEO I/O
DW OFFSET SET_CTYPE
DW OFFSET SET_CPOS
DW OFFSET READ_CURSOR
DW OFFSET READ_LPEN
DW OFFSET ACT_DISP_PAGE
DW OFFSET SCROLL_UP
DW OFFSET SCROLL_DOWN
DW OFFSET READ_AC_CURRENT
DW OFFSET WRITE_AC_CURRENT
DW OFFSET WRITE_C_CURRENT
DW OFFSET SET_COLOR
DW OFFSET WRITE_DOT
DW OFFSET READ_DOT
DW OFFSET WRITE_TTY
DW OFFSET VIDEO_STATE
DW OFFSET VIDEO_RETURN ; RESERVED
DW OFFSET VIDEO_RETURN ; RESERVED
DW OFFSET VIDEO_RETURN ; RESERVED
DW OFFSET WRITE_STRING ; CASE 19H, WRITE STRING
M1L EQU $-M1
VIDEO_IO_1 PROC NEAR ; ENTRY POINT FOR ORG 0F065H
STI ; INTERRUPTS BACK ON
CLD ; SET DIRECTION FORWARD
PUSH ES
PUSH DS ; SAVE WORK AND PARAMETER REGISTERS
PUSH DX
PUSH CX
PUSH BX
PUSH SI
PUSH DI
PUSH BP
CALL DDS ; POINT DS: TO DATA SEGMENT
MOV SI,0B800H ; GET SEGMENT FOR COLOR CARD
MOV DI,@EQUIP_FLAG ; GET EQUIPMENT FLAGS SETTING
AND DI,30H ; ISOLATE CRT SWITCHES
CMP DI,30H ; IS SETTING FOR BW CARD?
JNE M2 ; SKIP IF NOT BW CARD
MOV SI,0B000H ; ELSE GET SEGMENT FOR BW CARD
M2:
CMP AH,13H ; TEST FOR WRITE STRING OPERATION
JE M3 ; SKIP IF ES:BP VALID AS PASSED
MOV ES,SI ; SET UP TO POINT AT VIDEO MEMORY AREAS
M3:
MOV SI,AX ; MOVE COMMAND TO LOOK UP REGISTER
SHR SI,8 ; SHIFT COMMAND TO FORM BYTE OFFSET
SAL SI,1 ; TIMES 2 FOR WORD TABLE LOOKUP
CMP SI,M1L ; TEST FOR WITHIN TABLE RANGE
JNB M4 ; BRANCH TO EXIT IFNOT A VALID COMMAND
MOV AH,@CRT_MODE ; MOVE CURRENT MODE INTO AH
JMP WORD PTR CS:[SI+OFFSET M1] ; GO TO SELECTED FUNCTION
M4: ; COMMAND NOT VALID
JMP VIDEO_RETURN ; DO NOTHING IF NOT IN VALID RANGE
VIDEO_IO_1 ENDP
;------------------------------------------------------
; SET MODE :
; THIS ROUTINE INITIALIZES THE ATTACHMENT TO :
; THE SELECTED MODE, THE SCREEN IS BLANKED. :
; INPUT :
; (AL) - MODE SELECTED (RANGE 0-7) :
; OUTPUT :
; NONE :
;------------------------------------------------------
SET_MODE PROC NEAR
MOV DX,03D4H ; ADDRESS OF COLOR CARD
CMP DI,30H ; IS BW CARD INSTALLED
JNE M8 ; OK WITH COLOR
MOV AL,7 ; INDICATE INTERNAL BW CARD MODE
MOV DL,0B4H ; ADDRESS OF BW (MONOCHROME) CARD
M8:
MOV @CRT_MODE,AL ; SAVE MODE IN GLOBAL VARIABLE
MOV @ADDR_6845,DX ; SAVE ADDRESS OF BASE
MOV @ROWS,25-1 ; INITIALIZE DEFAULT ROW COUNT OF 25
PUSH DS ; SAVE POINTER TO DATA SEGMENT
PUSH AX ; SAVE MODE NUMBER (AL)
CBW ; CLEAR HIGH BYTE OF MODE
MOV SI,AX ; SET TABLE POINTER, INDEXED BY MODE
MOV AL,CS:[SI + OFFSET M7] ; GET THE MODE SET VALUE FROM TABLE
MOV @CRT_MODE_SET,AL ; SAVE THE MODE SET VALUE
AND AL,037H ; VIDEO OFF, SAVE HIGH RESOLUTION SIT
PUSH DX ; SAVE OUTPUT PORT VALUE
ADD DX,4 ; POINT TO CONTROL REGISTER
OUT DX,AL ; RESET VIDEO TO OFF TO SUPPRESS ROLLING
POP DX ; BACK TO BASE REGISTER
ASSUME DS:ABS0
SUB BX,BX ; SET UP FOR ABS0 SECMENT
MOV DS,BX ; ESTABLISH VECTOR TABLE ADDRESSING
LDS BX,@PARM_PTR ; GET POINTER TO VIDEO PARMS
ASSUME DS:CODE
POP AX ; RECOVER MODE NUMBER IN (AL)
MOV CX,16 ; LENGTH OF EACH ROW OF TABLE
CMP AL,2 ; DETERMINE WHICH ONE TO USE
JC M9 ; MODE IS 0 OR 1
ADD BX,CX ; NEXT ROW OF INITIALIZATION TABLE
CMP AL,4
JC M9 ; MODE IS 2 OR 3
ADD BX,CX ; MOVE TO GRAPHICS ROW OF INIT_TABLE
CMP AL,7
JC M9 ; MODE IS 4,5, OR 6
ADD BX,CX ; MOVE TO BW CARD ROW OF INIT_TABLE
;----- BX POINTS TO CORRECT ROW OF INITIALIZATION TABLE
M9: ; OUT_INIT
PUSH AX ; SAVE MODE IN (AL)
MOV AX,[BX+10] ; GET THE CURSOR MODE FROM THE TABLE
XCHG AH,AL ; PUT CURSOR MODE IN CORRECT POSITION
PUSH DS ; SAVE TABLE SEGMENT POINTER
ASSUME DS:DATA
CALL DDS ; POINT DS TO DATA SEGMENT
MOV @CURSOR_MODE,AX ; PLACE INTO BIOS DATA SAVE AREA
ASSUME DS:CODE
POP DS ; RESTORE THE TABLE SEGMENT POINTER
XOR AH,AH ; AH IS REGISTER NUMBER DURING LOOP
;----- LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
M10: ; INITIALIZATION LOOP
MOV AL,AH ; GET 6845 REGISTER NUMBER
OUT DX,AL
INC DX ; POINT TO DATA PORT
INC AH ; NEXT REGISTER VALUE
MOV AL,[BX] ; GET TABLE VALUE
OUT DX,AL ; OUT TO CHIP
INC BX ; NEXT IN TABLE
DEC DX ; BACK TO POINTER REGISTER
LOOP M10 ; DO THE WHOLE TABLE
POP AX ; GET MODE BACK INTO (AL)
POP DS ; RECOVER SEGMENT VALUE
ASSUME DS:DATA
;----- FILL REGEN AREA WITH BLANK
XOR DI,DI ; SET UP POINTER FOR REGEN
MOV @CRT_START,DI ; START ADDRESS SAVED IN GLOBAL
MOV @ACTTVE_PAGE,0 ; SET PAGE VALUE
MOV CX,8192 ; NUMBER OF WORDS IN COLOR CARD
CMP AL,4 ; TEST FOR GRAPHICS
JC M12 ; NO_GRAPHICS_INIT
CMP AL,7 ; TEST FOR BW CARD
JE M11 ; BW_CARD_INIT
XOR AX,AX ; FILL FOR GRAPHICS MODE
JMP SHORT M13 ; CLEAR BUFFER
M11: ; BW_CARD_INIT
MOV CH,08H ; BUFFER SIZE ON BW CARD (2048)
M12: ; NO_GRAPHICS_INIT
MOV AX,' '+7*H ; FIL CHAR FOR ALPHA - ATTRIBUTE
M13: ; CLEAR BUFFER
REP STOSW ; FILL THE REGEN BUFFER WITH BLANKS
;----- ENABLE VIDEO AND CORRECT PORT SETTING
MOV DX,@ADDR_6845 ; PREPARE TO OUTPUT TO VIDEO ENABLE PORT
ADD DX,4 ; POINT TO THE MODE CONTROL REGISTER
MOV AL,@CRT_MODE_SET ; GET THE MODE SET VALUE
OUT DX,AL ; SET VIDEO ENABLE PORT
;----- DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
;----- AND THE NUMBER TO BE USED FOR TTY INTERFACE
MOV AL,CS:[SI + OFFSET M6] ; GET NUMBER OF COLUMNS ON THIS SCREEN
CBW ; CLEAR HIGH BYTE
MOV @CRT_COLS,AX ; INITIALIZE NUMBER OF COLUMNS COUNT
;----- SET CURSOR POSITIONS
AND SI,000EH ; WORD OFFSET INTO CLEAR LENGTH TABLE
MOV AX,CS:[SI + OFFSET M5] ; LENGTH TO CLEAR
MOV @CRT_LEN,AX ; SAVE LENGTH OF CRT -- NOT USED FOR SW
MOV CX,8 ; CLEAR ALL CURSOR POSITIONS
MOV DI,OFFSET @CURSOR_POSN
PUSH DS ; ESTABLISH SEGMENT
POP ES ; ADDRESSING
XOR AX,AX
REP STOSW ; FILL WITH ZEROES
;----- SET UP OVERSCAN REGISTER
INC DX ; SET OVERSCAN PORT TO A DEFAULT
MOV AL,30H ; 30H VALUE FOR ALL MODES EXCEPT 640X200
CMP @CRT_MODE,6 ; SEE IF THE MODE IS 640X200 BW
JNZ M14 ; IF NOT 640X200, THEN GO TO REGULAR
MOV AL,3FH ; IF IT IS 640X200, THEN PUT IN 3FM
M14:
OUT DX,AL ; OUTPUT THE CORRECT VALUE TO 3D9 PORT
MOV @CRT_PALETTE,AL ; SAVE THE VALUE FOR FUTURE USE
;----- NORMAL RETURN FROM ALL VIDEO RETURNS
VIDEO_RETURN:
POP BP
POP DI
POP SI
POP BX
M15: ;VIDEO_RETURN_C
POP CX
POP DX
POP DS
POP ES ; RECOVER SEGMENTS
IRET ; ALL DONE
SET_MODE ENDP
;------------------------------------------------
; SET_CTYPE
; THIS ROUTINE SETS THE CURSOR VALUE
; INPUT
; (CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
; OUTPUT
; NONE
;------------------------------------------------
SET_CTYPE PROC NEAR
MOV AH,10 ; 6845 REGISTER FOR CURSOR SET
MOV @CURSOR_MODE,CX ; SAVE IN DATA AREA
CALL M16 ; OUTPUT CX REGISTER
JMP VIDEO_RETURN
;----- THIS ROUTINE OUTPUTS THE CX REGISTER TO THE 6845 REGISTERS NAMED IN (AH)
M16:
MOV DX,@ADDR_6845 ; ADDRESS REGISTER
MOV AL,AH ; GET VALUE
OUT DX,AL ; REGISTER SET
INC DX ; DATA REGISTER
JMP $+2 ; I/O DELAY
MOV AL,CH ; DATA
OUT DX,AL
DEC DX
MOV AL,AH
INC AL ; POINT TO OTHER DATA REGISTER
OUT DX,AL ; SET FOR SECOND REGISTER
INC DX
JMP $+2 ; I/O DELAY
MOV AL,CL ; SECOND DATA VALUE
OUT DX,AL
RET ; ALL DONE
SET_CTYPE ENDP
;----------------------------------------------
; SET_CPOS
; THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
; NEW X-Y VALUES PASSED
; INPUT
; DX - ROW,COLUMN OF NEW CURSOR
; BH - DISPLAY PAGE OF CURSOR
; OUTPUT
; CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
;----------------------------------------------
SET_CPOS PROC NEAR
MOV AL,BH ; MOVE PAGE NUMBER TO WORK REGISTER
CBW ; CONVERT PAGE TO WORD VALUE
SAL AX,1 ; WORD OFFSET
XCHG AX,SI ; USE INDEX REGISTER
MOV [SI+OFFSET @CURSOR_POSN],DX ; SAVE THE POINTER
CMP @ACTIVE_PAGE,BH
JNZ M17 ; SET_CPOS_RETURN
MOV AX,DX ; GET ROW/Z~QLUMN TO AX
CALL M18 ; CURSOR SET
M17: ; SET_CPOS_RETURN
JMP VIDEO_RETURN
SET_CPOS ENDP
;----- SET CURSOR POSITION, AX HAS ROW/COLUMN FOR CURSOR
M18 PROC NEAR
CALL POSITION ; DETERMINE LOCATION IN REGEN BUFFER
MOV CX,AX
ADD CX,@CRT_START ; ADD IN THE START ADDRESS FOR THIS PAGE
SAR CX,1 ; DIVIDE BY 2 FOR CHAR ONLY COUNT
MOV AH,14 ; REGISTER NUMBER FOR CURSOR
CALL M16 ; OUTPUT THE VALUE TO THE 6845
RET
M18 ENDP
;------------------------------------------------------
; READ_CURSOR
; THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
; 6845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
; INPUT
; BH - PAGE OF CURSOR
; OUTPUT
; DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
; CX - CURRENT CURSOR MODE
;------------------------------------------------------
READ-CURSOR PROC NEAR
MOV BL,BH
XOR BH,BH
SAL BX,1 ; WORD OFFSET
MOV DX,[BX+OFFSET @CURSOR_POSN]
MOV CX,@CURSOR_MODE
POP BP
POP DI
POP SI
POP BX
POP AX ; DISCARD SAVED CX AND DX
POP AX
POP DS
POP ES
IRET
READ_CURSOR ENDP
;-----------------------------------------------------
; ACT_DISP_PAGE
; THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
; THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
; INPUT
; AL HAS THE NEW ACTIVE DISPLAY PAGE
; OUTPUT
; THE 6845 IS RESET TO DISPLAY THAT PAGE
;-----------------------------------------------------
ACT_DISP_PAGE PROC NEAR
MOV @ACTIVE_PAGE,AL ; SAVE ACTIVE PAGE VALUE
MOV CX,@CRT_LEN ; GET SAVED LENGTH OF REGEN BUFFER
CBW ; CONVERT AL TO WORD
PUSH AX ; SAVE PAGE VALUE
MUL CX ; DISPLAY PAGE TIMES REGEN LENGTH
MOV @CRT_START,AX ; SAVE START ADDRESS FOR LATER
MOV CX,AX ; START ADDRESS TO CX
SAR CX,1 ; DIVIDE BY 2 FOR 6845 HANDLING
MOV AH,12 ; 6845 REGISTER FOR START ADDRESS
CALL M16
POP BX ; RECOVER PAGE VALUE
SAL BX,1 ; *2 FOR WORD OFFSET
MOV AX,[BX + OFFSET @CURSOR_POSN) ; GET CURSOR FOR THIS PAGE
CALL M18 ; SET THE CURSOR POSITION
JMP VIDEO_RETURN
ACT_DISP_PAGE ENDP
;-----------------------------------------------
; SET_COLOR
; THIS ROUTINE SILL ESTABLISH THE BACKGROUND COLOR, THE OVERSCAN COLOR,
; AND THE FOREGROUND COLOR SET FOR MEDIUM RESOLUTION GRAPHICS
; INPUT
; (BH) HAS COLOR ID
; IF BH=0, THE BACKGROUND COLOR VALUE IS SET
; FROM THE LOW BITS OF BIT (0-31)
; IF BH=1, THE PALETTE SELECTION IS MADE
; BASED ON THE LOW BIT OF BL:
; 0 = GREEN, RED, YELLOW FOR COLORS 1,2,3
; 1 = BLUE, CYAN, MAGENTA FOR COLORS 1,2,3
; (BL) HAS THE COLOR VALUE TO BE USED
; OUTPUT
; THE COLOR SELECTION IS UPDATED
;------------------------------------------------
SET_COLOR PROC NEAR
MOV DX,@ADDR_6845 ; I/O PORT FOR PALETTE
ADD DX,5 ; OVERSCAN PORT
MOV AL,@CRT_PALETTE ; GET THE CURRENT PALETTE VALUE
OR BH,BH ; IS THIS COLOR 0?
JNZ M20 ; OUTPUT COLOR 1
;----- HANDLE COLOR 0 BY SETTING THE BACKGROUND COLOR
AND AL,0E0H ; TURN OFF LOW 5 BITS OF CURRENT
AND BL,01FH ; TURN OFF HIGH 3 BITS OF INPUT VALUE
OR AL,BL ; PUT VALUE INTO REGISTER
M19: ; OUTPUT THE PALETTE
OUT DX,AL ; OUTPUT COLOR SELECTION TO 3D9 PORT
MOV @CRT_PALETTE,AL ; SAVE THE COLOR VALUE
JMP VIDEO_RETURN
;----- HANDLE COLOR 1 BY SELECTING THE PALETTE TO BE USED
M20:
AND AL,0DFH ; TURN OFF PALETTE SELECT BIT
SHR BL,1 ; TEST THE LOW ORDER BIT OF SL
JNC M19 ; ALREADY DONE
OR AL,20H ; TURN ON PALETTE SELECT BIT
JMP M19 ; GO DO IT
SET_COLOR ENDP
;---------------------------------------------------
; VIDEO STATE
; RETURNS THE CURRENT VIDEO STATE IN AX
; AH = NUMBER OF COLUMNS ON THE SCREEN
; AL = CURRENT VIDEO MODE
; BH = CURRENT ACTIVE PAGE
;---------------------------------------------------
VIDEO_STATE PROC NEAR
MOV AH,BYTE PTR @CRT_COLS ; GET NUMBER OF COLUMNS
MOV AL,@CRT_MODE ; CURRENT MODE
MOV BH,@ACTTVE_PAGE ; GET CURRENT ACTIVE PAGE
POP BP ; RECOVER REGISTERS
POP DI
POP SI
POP CX ; DISCARD SAVED BX
JMP M15 ; RETURN TO CALLER
VIDEO-STATE ENDP
;-----------------------------------------
; POSITION
; THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
; OF A CHARACTER IN THE ALPHA MODE
; INPUT
; AX = ROW, COLUMN POSITION
; OUTPUT
; AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
;-----------------------------------------
POSITION PROC NEAR
PUSH BX ; SAVE REGISTER
MOV BX,AX
MOV AL,AH ; ROWS TO AL
MUL BYTE PTR @CRT_COLS ; DETERMINE BYTES TO ROW
XOR BH,BH
ADD AX,BX ; ADD IN COLUMN VALUE
SAL AX,1 ; * 2 FOR ATTRIBUTE BYTES
POP BX
RET
POSITION ENDP
;----------------------------------------------
; SCROLL UP
; THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
; ON THE SCREEN
; INPUT
; (AH) = CURRENT CRT MODE
; (AL) = NUMBER OF ROWS TO SCROLL
; (CX) = ROW/COLUMN OF UPPER LEFT CORNER
; (DX) = ROW/COLUMN OF LOWER RIGHT CORNER
; (BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
; (DS) = DATA SEGMENT
; (ES) = REGEN BUFFER SEGMENT
; OUTPUT
; NONE -- THE REGEN BUFFER IS MODIFIED
;--------------------------------------------
ASSUME DS:DATA,ES:DATA
SCROLL_UP PROC NEAR
CALL TEST_LINE_COUNT
CMP AH,4 ; TEST FOR GRAPHICS MODE
JC N1 ; HANDLE SEPARATELY
CMP AH,7 ; TEST FOR BW CARD
JE N1
JMP GRAPHICS_UP
N1: ; UP_CONTINUE
PUSH BX ; SAVE FILL ATTRIBUTE IN BH
MOV AX,CX ; UPPER LEFT POSITION
CALL SCROLL_POSITION ; DO SETUP FOR SCROLL
JZ N7 ; BLANK_FIELD
ADD SI,AX ; FROM ADDRESS
MOV AH,DH ; # ROWS IN BLOCK
SUB AH,BL ; # ROWS TO BE MOVED
N2: ; ROW LOOP
CALL N10 ; MOVE ONE ROW
ADD SI,BP
ADD DI,BP ; POINT TO NEXT LINE IN BLOCK
DEC AH ; COUNT OF LINES TO MOVE
JNZ N2 ; ROW_LOOP
N3: ; CLEAR ENTRY
POP AX ; RECOVER ATTRIBUTE IN AH
MOV AL,' ' ; FILL WITH BLANKS
N4: ; CLEAR_LOOP
CALL N11 ; CLEAR THE ROW
ADD DI,BP ; POINT TO NEXT LINE
DEC BL ; COUNTER OF LINES TO SCROLL
JNZ N4 ; CLEAR_LOOP
N5: ; SCROLL_END
CALL DDS
CMP @CRT_MODE,7 ; IS THIS THE BLACK AND WHITE CARD
JE N6 ; IF SO, SKIP THE MODE RESET
MOV AL,@CRT_MODE_SET ; GET THE VALUE OF THE MODE SET
MOV DX,03D8H ; ALWAYS SET COLOR CARD PORT
OUT DX,AL
N6: ; VIDEO_RET_HERE
JMP VIDEO_RETURN
N7: ; BLANK_FIELD
MOV BL,DH ; GET ROW COUNT
JMP N3 ; GO CLEAR THAT AREA
SCROLL_UP ENDP
I ----- HANDLE COMMON SCROLL SET UP HERE
SCROLL_POSITION PROC NEAR
CALL POSITION ; CONVERT TO REGEN POINTER
ADD AX,@CRT_START ; OFFSET OF ACTIVE PAGE
MOV DI,AX ; TO ADDRESS FOR SCROLL
MOV SI,AX ; FROM ADDRESS FOR SCROLL
SUB DX,CX ; DX = #ROWS, #COLS IN BLOCK
INC DH
INC DL ; INCREMENT FOR 0 ORIGIN
XOR CH,CH ; SET HIGH BYTE OF COUNT TO ZERO
MOV BP,@CRT_COLS ; GET NUMBER OF COLUMNS IN DISPLAY
ADD BP,BP ; TIMES 2 FOR ATTRIBUTE BYTE
MOV AL,BL ; GET LINE COUNT
MUL BYTE PTR @CRT_COLS ; DETERMINE OFFSET TO FROM ADDRESS
ADD AX,AX ; *2 FOR ATTRIBUTE BYTE
PUSH AX ; SAVE LINE COUNT
MOV AL,@CRT_MODE ; GET CURRENT MODE
PUSH ES ; ESTABLISH ADDRESSING TO REGEN BUFFER
POP DS ; FOR BOTH POINTERS
CMP AL,2 ; TEST FOR COLOR CARD SPECIAL CASES HERE
JB N9 ; HAVE TO HANDLE 80X25 SEPARATELY
CMP AL,3
JA N9
;----- ; 80X25 COLOR CARD SCROLL
PUSH DX
MOV DX,3DAH ; GUARANTEED TO BE COLOR CARD HERE
N8: ; WAIT_DISP_ENABLE
IN AL,DX ; GET PORT
TEST AL,RVRT ; WAIT FOR VERTICAL RETRACE
JZ N8 ; WAIT_DISP_ENABLE
MOV AL,25H
MOV DL,0D8H ; ADDRESS CONTROL PORT
OUT DX,AL ; TURN OFF VIDEO DURING VERTICAL RETRACE
POP DX
N9:
POP AX ; RESTORE LINE COUNT
OR BL,BL ; 0 SCROLL MEANS BLANK FIELD
RET ; RETURN WITH FLAGS SET
SCROLL_POSITION ENDP
;----- MOVE_ROW
N10 PROC NEAR
MOV CL,DL ; GET # OF COLS TO MOVE
PUSH SI
PUSH DI ; SAVE START ADDRESS
REP MOVSW ; MOVE THAT LINE ON SCREEN
POP DI
POP SI ; RECOVER ADDRESSES
RET
N10 ENDP
;----- CLEAR_ROW
N11 PROC NEAR
MOV CL,DL ; GET # COLUMNS TO CLEAR
PUSH DI
REP STOSW ; STORE THE FILL CHARACTER
POP DI
RET
N11 ENDP
;------------------------------------------
; SCROLL DOWN
; THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
; BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
; WITH A DEFINED CHARACTER
; INPUT
; (AH) = CURRENT CRT MODE
; (AL) = NUMBER OF LINES TO SCROLL
; (CX) = UPPER LEFT CORNER OF RECION
; (DX) = LOWER RIGHT CORNER OF REGION
; (BH) = FILL CHARACTER
; (DS) = DATA SEGMENT
; (ES) = REGEN SEGMENT
; OUTPUT
; NONE -- SCREEN IS SCROLLED
;------------------------------------------
SCROLL_DOWN PROC NEAR
STD ; DIRECTION FOR SCROLL DOWN
CALL TEST_LINE_COUNT
CMP AH,4 ; TEST FOR GRAPHICS
JC N12
CMP AH,7 ; TEST FOR BW CARD
JE N12
JMP GRAPHICS_DOWN
N12: ; CONTINUE_DOWN
PUSH BX ; SAVE ATTRIBUTE IN BH
MOV AX,DX ; LOWER RIGHT CORNER
CALL SCROLL_POSITION ; GET REGEN LOCATION
JZ N16
SUB SI,AX ; SI IS FROM ADDRESS
MOV AH,DH ; GET TOTAL # ROWS
SUB AH,BL ; COUNT TO MOVE IN SCROLL
N13:
CALL N10 ; MOVE ONE ROW
SUB SI,BP
SUB DI,BP
DEC AH
JNZ N13
N14:
POP AX ; RECOVER ATTRIBUTE IN AH
MOV AL,' '
N15:
CALL N11 ; CLEAR ONE ROW
SUB DL,BP ; GO TO NEXT ROW
DEC BL
JNZ N15
JMP N5 ; SCROLL_END
N16:
MOV BL,DH
JMP N14
SCROLL_DOWN ENDP
;----- IF AMOUNT OF LINES TO BE SCROLLED = AMOUNT OF LINES IN WINDOW
;----- THEN ADJUST AL; ELSE RETURN;
TEST_LINE_COUNT PROC NEAR
MOV BL,AL ; SAVE LINE COUNT IN BL
OR AL,AL ; TEST IF AL IS ALREADY ZERO
JZ BL_SET ; IF IT IS THEN RETURN
PUSH AX ; SAVE AX
MOV AL,DH ; SUBTRACT LOWER ROW FROM UPPER ROW
SUB AL,CH
INC AL ; ADJUST DIFFERENCE BY 1
CMP AL,BL ; LINE COUNT = AMOUNT OF ROWS IN WINDOW?
POP AX ; RESTORE AX
JNE BL_SET ; IF NOT THEN WE'RE ALL SET
SUB BL,BL ; OTHERWISE SET BL TO ZERO
BL_SET:
RET ; RETURN
TEST_LINE_COUNT ENDP
;------------------------------------------------------------------------------
; READ_AC_CURRENT :
; THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT :
; CURSOR POSITION AND RETURNS THEM TO THE CALLER :
; INPUT :
; (AH) = CURRENT CRT MODE :
; (BH) = DISPLAY PAGE ( ALPHA MODES ONLY ) :
; (DS) = DATA SEGMENT :
; (ES) = REGEN SEGMENT :
; OUTPUT :
; (AL) = CHARACTER READ :
; (AH) = ATTRIBUTE READ :
;------------------------------------------------------------------------------
ASSUME DS:DATA,ES:DATA
READ_AC_CURRENT PROC NEAR
CMP AH,4 ; IS THIS GRAPHICS
JC P10
CMP AH,7 ; IS THIS BW CARD
JE P10
JMP GRAPHICS_READ ; READ_AC_CONTINUE
P10:
CALL FIND_POSITION ; GET REGEN LOCATION AND PORT ADDRESS
MOV SI,DI ; ESTABLISH ADDRESSING IN SI
PUSH ES ; GET REGEN SEGMENT FOR QUICK ACCESS
POP DS
;----- WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
OR BL,BL ; CHECK MODE FLAG FOR COLOR CARD IN 80
JNZ P13 ; ELSE SKIP RE-RACE WAIT - DO FAST READ
P11: ; WAIT FOR HORZ RETRACE LOW OR VERTICAL
STI ; ENABLE INTERRUPTS FIRST
NOR ; ALLOW FOR SMALL INTERRUPT WINDOW
CLI ; BLOCK INTERRUPTS FOR SINGLE LOOP
IN AL,DX ; GET STATUS FROM THE ADAPTER
TEST AL,RHRZ ; IS HORIZONTAL RETRACE LOW
JNZ P11 ; WAIT UNTIL IT IS
P12: ; NOW WAIT FOR EITHER RETRACE HIGH
IN AL,DX ; GET STATUS
TEST AL,RVRT+RHRZ ; IS HORIZONTAL OR VERTICAL RETRACE HIGH
JZ P12 ; WAIT UNTIL EITHER IS ACTIVE
P13:
LODSW ; GET THE CHARACTER AND ATTRIBUTE
JMP VIDEO_RETURN ; EXIT WITH (AX)
READ_AC_CURRENT ENDP
FIND_POSITTON PROC NEAR ; SETUP FOR BUFFER READ OR WRITE
XCHG AH,BL ; SWAP MODE TYPE WITH ATTRIBUTE
MOV BP,AX ; SAVE CHARACTER/ATTR IN (BP) REGISTER
SUB BL,2 ; CONVERT DISPLAY MODE TYPE TO A
SHR BL,1 ; ZERO VALUE FOR COLOR IN 80 COLUMN
MOV SI,BX ; AND SAVE (2 OR 3 --> ZERO)
MOV BL,BH ; MOVE DISPLAY PAGE TO LOW BYTE
XOR BH,BH ; CLEAR HIGH BYTE OF COUNT/BYTE OFFSET
MOV DI,BX ; MOVE DISPLAY PAGE (COUNT) TO WORK REG
SAL DI,1 ; TIMES 2 FOR WORD OFFSET
MOV AX,[DI+OFFSET @CURSOR_POSN) ; GET ROW/COLUMN OF THAT PAGE
JZ P21 ; SKIP BUFFER ADJUSTMENT IF PAGE ZERO
XOR DI,DI ; ELSE SET BUFFER START ADDRESS TO ZERO
P20:
ADD DI,@CRT_LEN ; ADD LENGTH OF BUFFER FOR ONE PAGE
DEC BX ; DECREMENT PAGE COUNT
JNZ P20 ; LOOP TILL PAGE COUNT EXHAUSTED
P21:
CALL POSITION ; DETERMINE LOCATION IN REGEN IN PAGE
ADD DI,AX ; ADD LOCATION TO START OF REGEN PAGE
MOV DX,@ADDR_6845 ; GET BASE ADDRESS OF ACTIVE DISPLAY
ADD DX,6 ; POINT AT STATUS PORT
MOV AX,SI ; RECOVER CONVERTED MODE TYPE IN (BL)
RET ; BP= ATTRIBUTE/CHARACTER (FROM BL/AL)
; DI= POSITION (OFFSET IN REGEN BUFFER)
; DX= STATUS PORT ADDRESS OF ADAPTER
FIND_POSITION ENDP ; BL= MODE FLAG (ZERO FOR 80X25 COLOR)
;------------------------------------------------------------------------------
; WRITE_AC_CURRENT :
; THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER :
; AT THE CURRENT CURSOR POSITION :
; INPUT :
; (AH) = CURRENT CRT MODE :
; (BH) = DISPLAY PAGE :
; (CX) = COUNT OF CHARACTERS TO WRITE :
; (AL) = CHAR TO WRITE :
; (BL) = ATTRIBUTE OF CHAR TO WRITE :
; (DS) = DATA SEGMENT :
; (ES) = REGEN SEGMENT :
; OUTPUT :
; DISPLAY REGEN BUFFER UPDATED :
;------------------------------------------------------------------------------
WRITE_AC_CURRENT PROC NEAR
CMP AH,4 ; IS THIS GRAPHICS
JC P30
CMP AH,7 ; IS THIS BW CARD
JE P30
JMP GRAPHICS_WRITE
P30: ; WRITE_AC_CONTINUE
CALL FIND_POSITION ; GET REGEN LOCATION AND PORT ADDRESS
; ADDRESS IN (DI) REGISTER
OR BL,BL ; CHECK MODE FLAG FOR COLOR CARD AT 80
JZ P32 ; SKIP TO RETRACE WAIT IF COLOR AT 80
XCHG AX,BP ; GET THE ATTR/CHAR SAVED FOR FAST WRITE
REP STOSW ; STRING WRITE THE ATTRIBUTE A CHARACTER
JMP SHORT P35 ; EXIT FAST WRITE ROUTINE
;----- WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
P31: ; LOOP FOR EACH ATTR/CHAR WRITE
XCHG BP,AX ; PLACE ATTR/CHAR BACK IN SAVE REGISTER
P32: ; WAIT FOR HORZ RETRACE LOW OR VERTICAL
STI ; ENABLE INTERRUPTS FIRST
NOP ; ALLOW FOR INTERRUPT WINDOW
CLI ; BLOCK INTERRUPTS FOR SINGLE LOOP
IN AL,DX ; GET STATUS FROM THE ADAPTER
TEST AL,RVRT ; CHECK FOR VERTICAL RETRACE FIRST
JNZ P34 ; DO FAST WRITE NOW IF VERTICAL RETRACE
TEST AL,RHRZ ; HORIZONTAL RETRACE LOW THEN
JNZ P32 ; WAIT UNTIL IT IS
P33: ; WAIT FOR EITHER RETRACE HIGH
IN AL,DX ; GET STATUS AGAIN
TEST AL,RVRT+RHRZ ; IS HORIZONTAL OR VERTICAL RETRACE HIGH
JZ P33 ; WAIT UNTIL EITHER IS ACTIVE
P34:
XCHG AX,BP ; GET THE ATTR/CHAR SAVED IN (BP)
STOSW ; WRITE THE ATTRIBUTE AND CHARACTER
LOOP P31 ; AS MANU TIMES AS REQUESTED - TILL CX=0
P35:
JMP VIDEO_RETURN ; EXIT
WRITE_AC_CURRENT ENDP
;------------------------------------------------------------------------------
; WRITE_C_CURRENT :
; THIS ROUTINE WRITES THE CHARACTER AT :
; THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED :
; INPUT :
; (AH) = CURRENT CRT MODE :
; (BH) = DISPLAY PAGE :
; (CX) = COUNT OF CHARACTERS TO WRITE :
; (AL) = CHAR TO WRITE :
; (DS) = DATA SEGMENT :
; (ES) = REGEN SEGMENT :
; OUTPUT :
; DISPLAY REGEN BUFFER UPDATED :
;------------------------------------------------------------------------------
WRITE_C_CURRENT PROC NEAR
CMP AH,4 ; IS THIS GRAPHICS
JC P40
CMP AH,7 ; IS THIS BW CARD
JE P40
JMP GRAPHICS_WRITE
P40:
CALL FIND_POSITION ; GET REGEN LOCATION AND PORT ADDRESS
; ADDRESS OF LOCATION IN (DI)
;----- WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
P41: ; WAIT FOR HORZ RETRACE LOW OR VERTICAL
STI ; ENABLE INTERRUPTS FIRST
OR BL,BL ; CHECK MODE FLAG FOR COLOR CARD IN 80
JNZ P43 ; ELSE SKIP RETRACE WAIT - DO FAST WRITE
CLI ; BLOCK INTERRUPTS FOR SINGLE LOOP
IN AL,DX ; GET STATUS FROM THE ADAPTER
TEST AL,RVRT ; CHECK FOR VERTICAL RETRACE FIRST
JNZ P43 ; DO FAST WRITE NOW IF VERTICAL RETRACE
TEST AL,RHRZ ; IS HORIZONTAL RETRACE LOW THEN
JNZ P41 ; WAIT UNTIL IT IS
P42: ; WAIT FOR EITHER RETRACE HIGH
IN AL,DX ; GET STATUS AGAIN
TEST AL,RVRT+RHRZ ; IS HORIZONTAL OR VERTICAL RETRACE HIGH
JZ P42 ; WAIT UNTIL EITHER RETRACE ACTIVE
P43:
MOV AX,BP ; GET THE CHARACTER SAVE IN (BP)
STOSB ; PUT THE CHARACTER INTO REGEN BUFFER
INC DI ; BUMP POINTER PAST ATTRIBUTE
LOOP P41 ; AS MANY TIMES AS REQUESTED
JMP VIDEO_RETURN
WRITE_C_CURRENT ENDP
;------------------------------------------------------------------------------
; WRITE_STRING :
; THIS ROUTINE WRITES A STRING OF CHARACTERS TO THE CRT. :
; INPUT :
; (AL) = WRITE STRING COMMAND 0 - 3 :
; (BH) = DISPLAY PAGE :
; (CX) = COUNT OF CHARACTERS TO WRITE, IF (CX) = 0 THEN RETURN :
; (DX) = CURSOR POSITION FOR START OF STRING WRITE :
; (BL) = ATTRIBUTE OF CHARACTER TO WRITE IF (AL) = 0 OR (AL) = 1 :
; (ES) = SOURCE STRING SEGMENT :
; (BP) = SOURCE STRING OFFSET :
; OUTPUT :
; NONE :
;------------------------------------------------------------------------------
WRITE_STRING PROC NEAR
CMP AL,04 ; TEST FOR INVALID WRITE STRING OPTION
JNB P59 ; IF OPTION INVALID THEN RETURN
JCXZ P59 ; IF ZERO LENGTH STRING THEN RETURN
MOV SI,BX ; GET CURRENT CURSOR PAGE
SHR SI,8 ; CLEAR HIGH BYTE
SAL SI,1 ; CONVERT TO PAGE OFFSET (SI= PAGE)
PUSH [SI+OFFSET @CURSOR_POSN] ; SAVE CURRENT CURSOR POSITION IN STACK
PUSH AX ; SAVE WRITE STRING OPTION
MOV AX,0200H ; SET NEW CURSOR POSITION
INT 10H
POP AX ; RESTORE WRITE STRING OPTION
P50:
PUSH CX
PUSH BX
PUSH AX
XCHG AH,AL ; PUT THE WRITE STRING OPTION INTO 'AH)
MOV AL,ES:[BP] ; GET CHARACTER FROM INPUT STRING
INC BP ; BUMP POINTER TC CHARACTER