forked from dspinellis/GW-BASIC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOEM.ASM
2102 lines (1988 loc) · 39.2 KB
/
OEM.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
.RADIX 8
DGROUP GROUP DSEG,SSEG
CSEG SEGMENT PUBLIC 'CODESG'
ASSUME CS:CSEG,DS:DSEG
INCLUDE OEM.H
TITLE OEM - Vendor provided code
COMMENT *
Written by: Stjepan Gros <[email protected]>
A lot of screen related rutines use INT 10H services, so much of
data can be inferred by reading documentation for INT 10H.
Some routines written or disassembled by: TK Chia <https://github.com/tkchia>
Many of the routines missing from the GW-BASIC code release are
present in Microsoft's previous release of MS-DOS v1.25 BASICA.COM
(https://github.com/microsoft/MS-DOS/tree/master/v1.25/bin),
though only in binary form. These are indicated.
Many other routines are not even in BASICA.COM though, and have to be
written from scratch.
*
.SALL
EXTRN SCNSWI:NEAR,SCNCLR:NEAR,SCNTRM:NEAR,FCERR:NEAR,SFTOFF:NEAR
EXTRN CBKSTA:NEAR,CBKTRM:NEAR,SNDSTA:NEAR,SNDTRM:NEAR
EXTRN EVSTA:NEAR,EVTRM:NEAR
;; Text screen group of subroutines
; OEM supplied Clear-Screen Routine
;
; INPUT
; AL Per argument supplied to CLS command, i.e.
; 0 Clear everything
; 1 Clear graphics viewport (not in this version)
; 2 Clear text window
;
PUBLIC CLRSCN
CLRSCN: CMP AL,2
JZ CLRWDO
XOR CX,CX
MOV DH,LINCNT
MOV DL,CRTWID
JMP SHORT CLRALL
CLRWDO: MOV CH,WDOTOP
MOV CL,WDOLFT
SUB CX,0101H
MOV DH,WDOBOT
MOV DL,WDORGT
CLRALL: SUB DX,0101H
CALL FILATR
MOV BH,AL
MOV AX,0600H
INT 10H
JMP SCNCLR
; Internal function: return in AL the screen attribute to use for INT 10H
; text blanking operations
;
FILATR: CALL TXTMOD
MOV AL,TXTATR
JC FILAT2
PUSH CX
MOV CL,4
SHR AL,CL
POP CX
FILAT2: RET
; Internal function: say whether the current video mode is a text mode
;
TXTMOD: PUSH CX
MOV CH,10001111B
MOV CL,CRTMOD
INC CX
SHR CH,CL
POP CX
RET
; OEM supplied screen clear to end of line
; Clear from (DH,DL) to EOL (from GWSTS.ASM)
PUBLIC CLREOL
CLREOL: PUSH AX
PUSH BX
PUSH CX
PUSH DX
XCHG DH,DL
SUB DX,0101H
MOV CX,DX
MOV DL,CRTWID
DEC DX
CALL FILATR
MOV BH,AL
MOV AX,0600H
INT 10H
POP DX
POP CX
POP BX
POP AX
RET
; OEM supplied SCROLL routine
; Does not blank out parts of screen that are not scrolled into
;
; INPUT
; AX (AH, AL) = Top left corner (column, row) of source
; region
; BX (BH, BL) = Top left corner of destination region
; CX (CH, CL) = Dimensions of area to move
; OUTPUT
;
; REGISTERS AFFECTED
;
PUBLIC SCROLL
SCROLL: PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES
PUSHF
PUSH AX
MOV DL,CRTMOD
XOR DH,DH
MOV SI,DX
SHL DX,1
SHL DX,1
ADD DX,SI
MOV BP,DX
ADD BP,OFFSET CSEG:SCLTAB
MOV DX,AX
CLC
CALL POSOFF
MOV SI,DX ; SI = starting source offset
MOV DX,BX
CLC
CALL POSOFF
MOV DI,DX ; DI = starting destination offset
XOR AH,AH
PUSH CX
MOV AL,CH
XOR AH,AH
MOV CL,CS:3[BP]
SHL AX,CL ; AX = bytes to move per graphics row
POP CX
MOV DL,CS:2[BP]
XOR DH,DH ; DX = how much SI and DI should
SUB DX,AX ; skip after each row
CLD
CMP SI,DI
JNB SCLFWD
POP SI ; If moving backwards, recompute
PUSH SI ; SI, DI, and DX...
PUSH DX
MOV DX,SI
ADD DX,CX
SUB DX,0101H
STC
CALL POSOFF
MOV SI,DX
MOV DX,BX
ADD DX,CX
SUB DX,0101H
STC
CALL POSOFF
MOV DI,DX
POP DX
NEG DX
STD
SCLFWD: MOV BL,CL
XOR BH,BH
MOV CL,CS:4[BP]
SHL BX,CL ; BX = count of graphics rows to move
MOV CH,CS:0[BP] ; Now move even-numbered graphics rows
XOR CL,CL
MOV DS,CX
MOV ES,CX
PUSH SI
PUSH DI
PUSH BX
SCLOT1: MOV CX,AX
REP MOVSB
ADD SI,DX
ADD DI,DX
DEC BX
JNZ SCLOT1
POP BX
POP DI
POP SI
MOV CH,CS:1[BP] ; Move odd-numbered graphics rows if
JCXZ SCLFIN ; applicable
MOV DS,CX
MOV ES,CX
SCLOT2: MOV CX,AX
REP MOVSB
ADD SI,DX
ADD DI,DX
DEC BX
JNZ SCLOT2
SCLFIN: POP AX
POPF
POP ES
POP DS
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
RET
; Internal data structure: information for scrolling a portion of the screen,
; used by SCROLL
;
SCLTAB LABEL BYTE ; For INT 10H video mode 0:
DB 0B8H ; * high byte of video memory address, for
; even-numbered graphics rows
DB 0 ; * high byte of video memory address, for
; odd-numbered graphics rows, or 0 if
; video is not interlaced
DB 80D ; * number of bytes per graphics row
DB 1 ; * shift for number of bytes per text column
DB 0 ; * shift for number of graphics rows per
; text row
DB 0B8H,0,80D,1,0 ; For mode 1
DB 0B8H,0,160D,1,0 ; For mode 2
DB 0B8H,0,160D,1,0 ; For mode 3
DB 0B8H,0BAH,80D,1,2 ; For mode 4
DB 0B8H,0BAH,80D,1,2 ; For mode 5
DB 0B8H,0BAH,80D,0,2 ; For mode 6
DB 0B0H,0,160D,1,0 ; For mode 7
; Internal function: convert a text (column, row), in the active display
; page, to an offset into video memory
;
; INPUT
; CS:[BP] SCLTAB element for current video mode
; DX (DH, DL) = (column, row)
; FLAGS CF=0 Return offset of first byte
; CF=1 Return offset of last byte
;
; OUTPUT
; DX Offset into video memory
;
POSOFF: PUSH AX
PUSH CX
PUSH ES
PUSHF
SUB DX,0101H
XCHG DH,DL
MOV AL,CS:2[BP]
MUL DH
MOV CL,CS:4[BP]
SHL AX,CL
XOR DH,DH
MOV CL,CS:3[BP]
SHL DX,CL
ADD DX,AX
XOR CX,CX ; Remember to add the page offset...
MOV ES,CX
ADD DX,ES:044EH
POPF
JNC POSOF2
MOV AL,CS:2[BP]
XOR AH,AH
MOV CL,CS:4[BP]
SHL AX,CL
SUB AL,CS:2[BP]
SBB AH,0
ADD DX,AX
MOV AX,1
MOV CL,CS:3[BP]
SHL AX,CL
DEC AX
ADD DX,AX
POSOF2: POP ES
POP CX
POP AX
RET
; OEM supplied screen input(read character)
;
; INPUT
; DH,DL Coordinates, DH->Column, DL->Row
; CF=0 Indicates call is from Screen Editor
; OUTPUT
; X=Character at (DH,DL)
; REGISTERS AFFECTED
PUBLIC SCRINP
SCRINP: CALL CSRHAK
PUSH BX
MOV AH,08H
MOV BH,ACTPAG
INT 10H
XOR AH,AH
TEST AL,AL
JNZ SCRIN2
MOV AL," "
SCRIN2: POP BX
RET
; OEM supplied character output
;
; INPUT
; AL Character to output
; DH, DL Position
; OUTPUT
; FLAGS CF=1 if inside escape sequence (?)
; CF=0 otherwise
;
; REGISTERS AFFECTED
;
PUBLIC SCROUT
SCROUT: PUSH DX
PUSH CX
PUSH BX
PUSH AX
CALL CSRHAK
MOV CX,1
MOV BH,ACTPAG
MOV BL,TXTATR
MOV AH,09H
INT 10H
POP AX
POP BX
POP CX
POP DX
CLC
RET
; Internal function: pretend to the BIOS that the text output cursor is at
; (DH, DL), but without actually moving the hardware cursor
;
CSRHAK: PUSH BX
PUSH DX
PUSH ES
XOR BX,BX
MOV ES,BX
MOV BL,ACTPAG
SHL BX,1
XCHG DH,DL
SUB DX,0101H
MOV ES:0450H[BX],DX
POP ES
POP DX
POP BX
RET
; From BASICA.COM CSEG:2215H
; Load (BX, AL) with the current pixel's byte offset & mask
; This is likely to have been calculated earlier with MAPXYC
;
PUBLIC FETCHC
FETCHC: MOV BX,PIXOFS
MOV AL,ATRMSK
RET
; From BASICA.COM CSEG:221DH
; Set the current pixel's byte offset & mask to (BX, AL)
; This is likely to have been calculated earlier with MAPXYC & then
; retrieved with FETCHC
;
PUBLIC STOREC
STOREC: MOV PIXOFS,BX
MOV ATRMSK,AL
RET
;Let screen editor set width
;pass Width in AL
;pass Height in CL
PUBLIC SWIDTH
SWIDTH: CMP CL,25D
JNZ SWDERR
MOV BX,OFFSET CSEG:SMMP40
CMP AL,40D
JZ SWIDT2
MOV BX,OFFSET CSEG:SMMP80
CMP AL,80D
JZ SWIDT2
SWDERR: STC
RET
SWIDT2: MOV AL,CRTMOD
XLAT CS:[BX]
TEST AL,AL
JS SWDERR
CALL SCNRST
CLC
RET
; Internal data structure: how to switch to another BIOS video mode, given
; that we want to change the screen width
SMMP40 DB 0,1,0,1,4,5,4,7
SMMP80 DB 2,3,2,3,6,6,6,7
; Sets a horizontal series of pixels on the screen to the current colour
; The desired pixel location and colour should be set first
; using MAPXYC and SETATR
;
; INPUT
; BX Number of pixels to set
; REGISTERS AFFECTED
; (?)
;
PUBLIC NSETCX
NSETCX: TEST BX,BX
JZ NSCZRO
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH ES
PUSHF
MOV AX,0B800H ; Set things up
MOV ES,AX
MOV CL,PIXBTS
MOV DI,PIXOFS
MOV DH,ATRPAT
MOV DL,ATRMSK
TEST DL,DL ; If we are not on a byte boundary,
JS NSCBND ; then slowly fill in pixels until
MOV AL,ES:[DI] ; we are
NSCLFT: MOV AH,DH
XOR AH,AL
AND AH,DL
XOR AL,AH
DEC BX
JZ NSCFIN
ROR DL,CL
JNC NSCLFT
STOSB
NSCBND: MOV SI,10H ; Count number of pixels per shortword
CMP CL,1
JZ NSCPS1
SHR SI,1
NSCPS1: CMP BX,SI ; Try to quickly draw pixels in the
JNA NSCRG1 ; middle
MOV AH,DH
MOV AL,DH
SUB BX,SI
NSCMID: STOSW
SUB BX,SI
JA NSCMID
ADD BX,SI
NSCRG1: MOV AL,ES:[DI] ; Fill in pixels on the right
NSCRGT: MOV AH,DH
XOR AH,AL
AND AH,DL
XOR AL,AH
DEC BX
JZ NSCFIN
ROR DL,CL
JNC NSCRGT
STOSB
JMP SHORT NSCRG1
NSCFIN: MOV PIXOFS,DI ; Update PIXOFS and ATRMSK
MOV ATRMSK,DL
STOSB
POPF
POP ES
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
NSCZRO: RET
; Modified from BASICA.COM CSEG:34F7H
; Send a byte to a printer
;
; INPUT
; AH Printer number (0 = LPT1:, 1 = LPT2:, etc.)
; AL Byte to send
; OUTPUT
; AH 0 Success
; 1 Device not available
; 2 Device timeout
; 3 Out of paper
; > 3 Device I/O error
; REGISTERS AFFECTED
; AL (?)
;
PUBLIC SNDLPT
SNDLPT: PUSH DX
XOR DX,DX ; Send out the character
XCHG AH,DL
PUSH BX ; RBIL says "BUGS: Some print
INT 17H ; spoolers trash the BX register on
POP BX ; return"
MOV AL,AH
TEST AL,00100000B ; Test for out-of-paper condition
JNZ LPTOTP
TEST AL,00000001B ; Test for timeout condition
JNZ LPTDTO
TEST AL,01000000B ; Test for device-not-available
JZ LPTDNA ; condition
XOR AL,00010000B
TEST AL,00011000B ; Test for general I/O error
JNZ LPTDIO
MOV AH,0
POP DX
RET
LPTDNA: MOV AH,1
DB 3DH
LPTDTO: MOV AH,2
DB 3DH
LPTOTP: MOV AH,3
DB 3DH
LPTDIO: MOV AH,4
POP DX
RET
; Filter a PEEK operation
;
; INPUT
; ES:BX Address to peek
; OUTPUT
; FLAGS ZF=0 Go ahead and do the actual PEEK
; ZF=1 Do not do the actual PEEK
; AL Value to return for PEEK function if ZF=1
;
PUBLIC PEKFLT
PEKFLT: TEST SP,SP
RET
; Filter a POKE operation
;
; INPUT
; ES:DX Address to poke
; AL Value to poke
; OUTPUT
; FLAGS ZF=0 Go ahead and do the actual POKE
; ZF=1 Do not do the actual POKE
; REGISTERS AFFECTED
; DI (?)
;
PUBLIC POKFLT
POKFLT: TEST AL,AL ; MS-DOS v1.25 DONKEY.BAS uses
JNZ POKOK ; 975 DEF SEG: POKE 106,0
CMP DX,106D ; to stop any ongoing expansion of
JNZ POKOK ; of function keys & Alt- keys ---
PUSH AX ; map it to a call to SFTOFF; (?) also
MOV AX,ES ; do the actual POKE for good measure
MOV DI,DS
CMP AX,DI
POP AX
JNZ POKOK
CALL SFTOFF
POKOK: TEST SP,SP
RET
; Set serial port (COM1, COM2, etc.) buffer location and size
;
; INPUT
; CX Segment for COM buffer
; OUTPUT
; FLAGS CF=0 OK
; CF=1 Out of memory
; REGISTERS AFFECTED
;
PUBLIC SETCBF
SETCBF: JNZ CBSPEC ; If no buffer size given, use a
MOV DX,100H ; default size
CBSPEC: MOV CBFSEG,CX ; Record the COM buffer location
CLC ;
RET
; From BASICA.COM CSEG:2265H
; Set current pixel to the pixel just to its left
;
PUBLIC LEFTC
LEFTC: MOV AL,CL
MOV CL,PIXBTS
ROL ATRMSK,CL
MOV CL,AL
JC LEFTC2
RET
LEFTC2: DEC PIXOFS
RET
; Set current pixel to the pixel just to its right
; (Not in BASICA.COM (?))
;
PUBLIC RIGHTC
RIGHTC: MOV AL,CL
MOV CL,PIXBTS
ROR ATRMSK,CL
MOV CL,AL
JC RGHTC2
RET
RGHTC2: INC PIXOFS
RET
; From BASICA.COM CSEG:2295H
; Set "current pixel" to given (X, Y) --- map coordinates to a byte offset
; in video memory & a bit mask, & update PIXOFS & ATRMSK
;
; INPUT
; (CX, DX) (X, Y) coordinates
; REGISTERS AFFECTED
; AX, BX, CX, DX, BP
;
PUBLIC MAPXYC
MAPXYC: MOV BP,CX
SHR DX,1
LAHF
MOV BX,DX
MOV CL,2
SHL DX,CL
ADD DX,BX
MOV CL,4
SHL DX,CL
SAHF
JNC MXYEVN
ADD DX,2000H ; Add interlace offset
MXYEVN: MOV PIXOFS,DX
MOV DX,BP
MOV CL,DL
TEST PIXBTS,1
JZ MXYPX2
MOV AL,07H
AND CL,AL
MOV AL,10000000B
SHR AL,CL
MOV ATRMSK,AL
MOV CL,3
SHR DX,CL
ADD PIXOFS,DX
RET
MXYPX2: MOV AL,03H
AND CL,AL
ADD CL,CL
MOV AL,11000000B
SHR AL,CL
MOV ATRMSK,AL
MOV CL,2
SHR DX,CL
ADD PIXOFS,DX
RET
; Map keystrokes to values for INKEY$
;
; INPUT
; FLAGS ZF=1 (?) Impossible
; ZF=0, CF=0 One-byte character key or IBM scan code
; ZF=0, CF=1 (?) Special key sequence (e.g. ^Break)
; AX, DX Keystroke, in format similar to KEYINP output (?)
; OUTPUT
; FLAGS ZF=1 Discard keystroke
; ZF=0 CF=0 Return keystroke as 1 byte
; ZF=0 CF=1 Return keystroke as 2 bytes
; AX Mapped keystroke
;
PUBLIC INKMAP
INKMAP: JC INKZAP
CMP AL,0FEH
CLC
JNZ INKSNG
MOV AX,DX
TEST SP,SP
STC
RET
INKZAP: CMP SP,SP
INKSNG: RET
; Map keystrokes to values for (?) purposes other than INKEY$
;
; INPUT
; FLAGS ZF=1 (?) Impossible
; ZF=0, CF=0 One-byte character key or IBM scan code
; ZF=0, CF=1 (?) Special key sequence (e.g. ^Break)
; AX, DX Keystroke, in format similar to KEYINP output (?)
; OUTPUT
; FLAGS ZF=1 Discard keystroke
; ZF=0 CF=0 Return keystroke as 1 byte
; ZF=0 CF=1 Return keystroke as 2 bytes
; AX Mapped keystroke
;
PUBLIC INFMAP
INFMAP: CALL INKMAP
JNC INFNDB
CMP SP,SP
INFNDB: RET
; Set foreground and background colours for text or graphics operations
;
; INPUT
; FLAGS CF=0 Text colours
; CF=1 Graphics colours
; AL Foreground colour
; BL Background colour
;
PUBLIC SETFBC
SETFBC: JC SETFBG
CALL TXTMOD ; Do not try to set text colours in
JNC SETFBF ; graphics mode --- doing so will
; make the function key display text
; disappear!
MOV TXTFGC,AL
MOV TXTBGC,BL
PUSH AX
PUSH BX
PUSH CX
MOV CL,5
SHL BL,CL
DEC CX
SHL AL,CL ; Handle the "blinking" flag!
RCR BL,1
SHR AL,CL
OR AL,BL
MOV TXTATR,AL
POP CX
POP BX
POP AX
RET
SETFBG: MOV FORCLR,AL
MOV BAKCLR,BL
SETFBF: RET
PUBLIC INICOM
INICOM: ;Dummy function
INT 3
MOV AH,6
RET
DB "INICOM"
; Get OEM specific portion of splash header
;
; INPUT
;
; OUTPUT
; CS:[BX] OEM header
; FLAGS ZF=1 Only print OEM header for interactive session
; ZF=0 Always print OEM header
;
PUBLIC GETHED
GETHED: MOV BX,OFFSET CSEG:OEMHED
CMP BX,BX
RET
OEMHED: DB "GW-BASIC "
IFDEF OEMVER ; If an OEMVER macro is defined,
IRPC X,OEMVER ; assume it gives more detailed
DB "&X&" ; version information; use it
ENDM
ELSE
DB "2022"
ENDIF
DB " version"
IFDEF __JWASM__
DB " (JWasm)"
ENDIF
DB ", MIT License"
ACRLF
DB "(C) Copyright D. Spinellis, S. Gros, T.K. Chia 2020--2022"
DB 0
; From BASICA.COM CSEG:2225H
; Set current pixel to the pixel just above it, unless pixel is already on
; first row, then just return with CF=1
;
PUBLIC TUPC
TUPC: MOV AX,PIXOFS
CMP AX,80D
JNB UPC1
STC
RET
; From BASICA.COM CSEG:222FH
; Set current pixel to the pixel just above it
;
PUBLIC UPC
UPC: MOV AX,PIXOFS
UPC1: CMP AH,20H
JB UPC2
SUB AH,20H
MOV PIXOFS,AX
RET
UPC2: ADD AX,2000H-80D
MOV PIXOFS,AX
RET
; From BASICA.COM CSEG:2306H; SXYERR is from CSEG:22FAH
; Clip graphics coordinates to the boundaries of the graphics screen
;
; INPUT
; (CX, DX) (X, Y) coordinates
; OUTPUT
; (CX, DX) Clipped (X, Y) coordinates
; FLAGS CF=1 if coordinates were not clipped
; REGISTERS AFFECTED
; AX, BX
;
PUBLIC SCALXY
SCALXY: MOV AL,PIXBTS
OR AL,AL
JZ SXYERR
OR CH,CH
JS SXYXNG
MOV BX,640D
TEST AL,1
JNZ SXYWID
SHR BX,1
SXYWID: CMP CX,BX
LAHF
JB SXYXOK
DEC BX
MOV CX,BX
SXYXOK: OR DH,DH
JS SXYYNG
CMP DX,200D
JB SXYYOK
MOV DX,199D
RET
SXYYOK: SAHF
RET
SXYYNG: XOR DX,DX
RET
SXYXNG: XOR CX,CX
LAHF
JMP SHORT SXYXOK
SXYERR: JMP FCERR
; From BASICA.COM CSEG:233AH
; Return the screen's pixel aspect ratio (?)
;
; OUTPUT
; BX (?) 100H * (width of 1 pixel) / (height of 1 pixel)
; DX (?) 100H * (height of 1 pixel) / (width of 1 pixel)
;
PUBLIC GTASPC
GTASPC: MOV BX,00D5H
MOV DX,0133H
TEST PIXBTS,1
JZ ASPFIN
SHR BX,1
INC BX
ADD DX,DX
ASPFIN: RET
; From BASICA.COM CSEG:24A3H; added CLC
; Initialize variables for a PAINT operation
;
; INPUT
; AL Border colour
;
PUBLIC PNTINI
PNTINI: MOV CH,ATRPAT
CALL SETATR
MOV BORPAT,AL
MOV ATRPAT,CH
CLC
RET
; From BASICA.COM CSEG:24B2H
;
SLRCHG: MOV AL,BH
XOR AL,DL
AND AL,CH
JZ SLRC1
MOV AL,BH
XOR AL,DH
AND AL,CH
OR BL,AL
XOR BH,AL
STC
SLRC1: RET
; From BASICA.COM CSEG:24C6H
;
SLRL: MOV CL,PIXBTS
ROL CH,CL
JNC SLR4
MOV ES:[DI],BH
CALL SLR1
LAHF
DEC DI
MOV BH,ES:[DI]
SAHF
RET
SLRR: MOV CL,PIXBTS
ROR CH,CL
JNC SLR4
MOV ES:[DI],BH
INC DI
MOV BH,ES:[DI]
SLR1: TEST DI,000FH
JNZ SLR4
MOV AX,DI ; Super-complicated way to test if
MOV CL,4 ; (DI AND 1FFFH) is divisible by 5 (?)
MOV SI,BX ; If it is divisible by both 5 & 16,
MOV BH,AH ; i.e. by 80, then we have reached
SHR AX,CL ; an edge of a graphics row
AND AL,0FH
AND BH,0FH
SHR AH,1
ADC AL,BH
MOV BX,SI
INC CX
ADD AL,CL
CMP AL,25D
JB SLR2
SUB AL,25D
SLR2: JZ SLR3
SUB AL,CL
JNB SLR2
SLR3: CMC
SLR4: RET
; From BASICA.COM CSEG:2516H
; (?) Initialize state for SCANL & SCANR
;
SLRBEG: MOV DI,0B800H ; ES:0 = video memory
MOV ES,DI
MOV DI,PIXOFS ; (DI, CH) = current pixel position
MOV CH,ATRMSK ; within scan
MOV DL,BORPAT ; DL = border pattern bitmap for PAINT
MOV DH,ATRPAT ; DH = current foreground colour
XOR BL,BL
MOV BH,ES:[DI] ; What is currently at ES:[DI]
RET
; From BASICA.COM CSEG:2531H
; Scan leftwards from current pixel to flood area with colour to paint (?)
;
PUBLIC SCANL
SCANL: PUSH ES
MOV BP,-1
CALL SLRBEG
SCL1: INC BP
CALL SLRL
JC SCL2
CALL SLRCHG
JC SCL1
SCL2: CALL SLRR
MOV ES:[DI],BH
MOV PIXOFS,DI
MOV ATRMSK,CH
MOV CL,BL
MOV BX,BP
POP ES
RET
; From BASICA.COM CSEG:2557H
; Scan rightwards from current pixel to flood area with colour to paint (?)
;
PUBLIC SCANR
SCANR: PUSH ES
MOV BP,DX
CALL SLRBEG
SCR1: CALL SLRCHG
JC SCR3
DEC BP
JZ SCR2
CALL SLRR
JNC SCR1
XOR BP,BP
SCR2: PUSH BP
JMP SHORT SCR7
SCR3: MOV CSAVEA,DI
MOV CSAVEM,CH
PUSH BP
XOR BP,BP
JMP SHORT SCR5
SCR4: CALL SLRCHG
JNC SCR6
SCR5: INC BP
CALL SLRR
JNC SCR4
CALL SLRL
SCR6: MOV PIXOFS,DI
MOV ATRMSK,CH
SCR7: POP DX
MOV ES:[DI],BH
MOV CL,BL
MOV BX,BP
POP ES
RET
; Get current foreground and background colours for text or graphics
; operations
;
; INPUT
; FLAGS CF=0 Text colours
; CF=1 Graphics colours
; OUTPUT
; AL Foreground colour
; BL Background colour
;