This repository has been archived by the owner on Dec 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathL24-1.ASM
254 lines (251 loc) · 7.07 KB
/
L24-1.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
; Program to illustrate operation of ALUs and latches of the VGA's
; Graphics Controller. Draws a variety of patterns against
; a horizontally striped background, using each of the 4 available
; logical functions (data unmodified, AND, OR, XOR) in turn to combine
; the images with the background.
; By Michael Abrash.
;
stack segment para stack 'STACK'
db 512 dup(?)
stack ends
;
VGA_VIDEO_SEGMENT equ 0a000h ;VGA display memory segment
SCREEN_HEIGHT equ 350
SCREEN_WIDTH_IN_BYTES equ 80
DEMO_AREA_HEIGHT equ 336 ;# of scan lines in area
; logical function operation
; is demonstrated in
DEMO_AREA_WIDTH_IN_BYTES equ 40 ;width in bytes of area
; logical function operation
; is demonstrated in
VERTICAL_BOX_WIDTH_IN_BYTES equ 10 ;width in bytes of the box used to
; demonstrate each logical function
;
; VGA register equates.
;
GC_INDEX equ 3ceh ;GC index register
GC_ROTATE equ 3 ;GC data rotate/logical function
; register index
GC_MODE equ 5 ;GC mode register index
;
dseg segment para common 'DATA'
;
; String used to label logical functions.
;
LabelString label byte
db 'UNMODIFIED AND OR XOR '
LABEL_STRING_LENGTH equ $-LabelString
;
; Strings used to label fill patterns.
;
FillPatternFF db 'Fill Pattern: 0FFh'
FILL_PATTERN_FF_LENGTH equ $ - FillPatternFF
FillPattern00 db 'Fill Pattern: 000h'
FILL_PATTERN_00_LENGTH equ $ - FillPattern00
FillPatternVert db 'Fill Pattern: Vertical Bar'
FILL_PATTERN_VERT_LENGTH equ $ - FillPatternVert
FillPatternHorz db 'Fill Pattern: Horizontal Bar'
FILL_PATTERN_HORZ_LENGTH equ $ - FillPatternHorz
;
dseg ends
;
; Macro to set indexed register INDEX of GC chip to SETTING.
;
SETGC macro INDEX, SETTING
mov dx,GC_INDEX
mov ax,(SETTING SHL 8) OR INDEX
out dx,ax
endm
;
;
; Macro to call BIOS write string function to display text string
; TEXT_STRING, of length TEXT_LENGTH, at location ROW,COLUMN.
;
TEXT_UP macro TEXT_STRING, TEXT_LENGTH, ROW, COLUMN
mov ah,13h ;BIOS write string function
mov bp,offset TEXT_STRING ;ES:BP points to string
mov cx,TEXT_LENGTH
mov dx,(ROW SHL 8) OR COLUMN;position
sub al,al ;string is chars only, cursor not moved
mov bl,7 ;text attribute is white (light gray)
int 10h
endm
;
cseg segment para public 'CODE'
assume cs:cseg, ds:dseg
start proc near
mov ax,dseg
mov ds,ax
;
; Select 640x350 graphics mode.
;
mov ax,010h
int 10h
;
; ES points to VGA memory.
;
mov ax,VGA_VIDEO_SEGMENT
mov es,ax
;
; Draw background of horizontal bars.
;
mov dx,SCREEN_HEIGHT/4
;# of bars to draw (each 4 pixels high)
sub di,di ;start at offset 0 in display memory
mov ax,0ffffh ;fill pattern for light areas of bars
mov bx,DEMO_AREA_WIDTH_IN_BYTES / 2 ;length of each bar
mov si,SCREEN_WIDTH_IN_BYTES - DEMO_AREA_WIDTH_IN_BYTES
mov bp,(SCREEN_WIDTH_IN_BYTES * 3) - DEMO_AREA_WIDTH_IN_BYTES
BackgroundLoop:
mov cx,bx ;length of bar
rep stosw ;draw top half of bar
add di,si ;point to start of bottom half of bar
mov cx,bx ;length of bar
rep stosw ;draw bottom half of bar
add di,bp ;point to start of top of next bar
dec dx
jnz BackgroundLoop
;
; Draw vertical boxes filled with a variety of fill patterns
; using each of the 4 logical functions in turn.
;
SETGC GC_ROTATE, 0 ;select data unmodified
; logical function...
mov di,0
call DrawVerticalBox ;...and draw box
;
SETGC GC_ROTATE, 08h ;select AND logical function...
mov di,10
call DrawVerticalBox ;...and draw box
;
SETGC GC_ROTATE, 10h ;select OR logical function...
mov di,20
call DrawVerticalBox ;...and draw box
;
SETGC GC_ROTATE, 18h ;select XOR logical function...
mov di,30
call DrawVerticalBox ;...and draw box
;
; Reset the logical function to data unmodified, the default state.
;
SETGC GC_ROTATE, 0
;
; Label the screen.
;
push ds
pop es ;strings we'll display are passed to BIOS
; by pointing ES:BP to them
;
; Label the logical functions, using the VGA BIOS's
; write string function.
;
TEXT_UP LabelString, LABEL_STRING_LENGTH, 24, 0
;
; Label the fill patterns, using the VGA BIOS's
; write string function.
;
TEXT_UP FillPatternFF, FILL_PATTERN_FF_LENGTH, 3, 42
TEXT_UP FillPattern00, FILL_PATTERN_00_LENGTH, 9, 42
TEXT_UP FillPatternVert, FILL_PATTERN_VERT_LENGTH, 15, 42
TEXT_UP FillPatternHorz, FILL_PATTERN_HORZ_LENGTH, 21, 42
;
; Wait until a key's been hit to reset screen mode & exit.
;
WaitForKey:
mov ah,1
int 16h
jz WaitForKey
;
; Finished. Clear key, reset screen mode and exit.
;
Done:
mov ah,0 ;clear key that we just detected
int 16h
;
mov ax,3 ;reset to text mode
int 10h
;
mov ah,4ch ;exit to DOS
int 21h
;
start endp
;
; Subroutine to draw a box 80x336 in size, using currently selected
; logical function, with upper left corner at the display memory offset
; in DI. Box is filled with four patterns. Top quarter of area is
; filled with 0FFh (solid) pattern, next quarter is filled with 00h
; (empty) pattern, next quarter is filled with 33h (double pixel wide
; vertical bar) pattern, and bottom quarter is filled with double pixel
; high horizontal bar pattern.
;
; Macro to draw a column of the specified width in bytes, one-quarter
; of the height of the box, with the specified fill pattern.
;
DRAW_BOX_QUARTER macro FILL, WIDTH
local RowLoop, ColumnLoop
mov al,FILL ;fill pattern
mov dx,DEMO_AREA_HEIGHT / 4 ;1/4 of the full box height
RowLoop:
mov cx,WIDTH
ColumnLoop:
mov ah,es:[di] ;load display memory contents into
; GC latches (we don't actually care
; about value read into AH)
stosb ;write pattern, which is logically
; combined with latch contents for each
; plane and then written to display
; memory
loop ColumnLoop
add di,SCREEN_WIDTH_IN_BYTES - WIDTH
;point to start of next line down in box
dec dx
jnz RowLoop
endm
;
DrawVerticalBox proc near
DRAW_BOX_QUARTER 0ffh, VERTICAL_BOX_WIDTH_IN_BYTES
;first fill pattern: solid fill
DRAW_BOX_QUARTER 0, VERTICAL_BOX_WIDTH_IN_BYTES
;second fill pattern: empty fill
DRAW_BOX_QUARTER 033h, VERTICAL_BOX_WIDTH_IN_BYTES
;third fill pattern: double-pixel
; wide vertical bars
mov dx,DEMO_AREA_HEIGHT / 4 / 4
;fourth fill pattern: horizontal bars in
; sets of 4 scan lines
sub ax,ax
mov si,VERTICAL_BOX_WIDTH_IN_BYTES ;width of fill area
HorzBarLoop:
dec ax ;0ffh fill (smaller to do word than byte DEC)
mov cx,si ;width to fill
HBLoop1:
mov bl,es:[di] ;load latches (don't care about value)
stosb ;write solid pattern, through ALUs
loop HBLoop1
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
mov cx,si ;width to fill
HBLoop2:
mov bl,es:[di] ;load latches
stosb ;write solid pattern, through ALUs
loop HBLoop2
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
inc ax ;0 fill (smaller to do word than byte DEC)
mov cx,si ;width to fill
HBLoop3:
mov bl,es:[di] ;load latches
stosb ;write empty pattern, through ALUs
loop HBLoop3
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
mov cx,si ;width to fill
HBLoop4:
mov bl,es:[di] ;load latches
stosb ;write empty pattern, through ALUs
loop HBLoop4
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
dec dx
jnz HorzBarLoop
;
ret
DrawVerticalBox endp
cseg ends
end start