Repository navigation
Expand file tree
/
Copy pathmatrix.asm
More file actions
198 lines (146 loc) · 8.09 KB
/
Copy pathmatrix.asm
File metadata and controls
198 lines (146 loc) · 8.09 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
; matrix rain code ;
; ;
; by Gabor Kotik ;
; github: codexclusive ;
; ;
; recreates the digital rain ;
; effect from the movie ;
; The Matrix, using 16-bit ;
; assembly and the ascii ;
; character set ;
;
;
org 0100h ;
; ------------ initialize the 80x25 character screen and the random seed
start: mov ax, 0003h ; set video mode
int 10h ;
mov ah, 01h ; disable cursor
mov cx, 2000h ;
int 10h ;
mov ah, 2ch ; get system time
int 21h ;
ror dx, 1 ; fill two highest bits
ror dx, 1 ;
mov bx, dx ; initialize random seed (bx)
mov ax, 0b800h ;
mov ds, ax ; set ds,es to video memory
mov es, ax ;
xor di, di ; set di to top-left corner
cld ; of screen
; ------------ fill the visible screen with pseudo-random characters
mov cx, 07d0h ; repeat 2000x
@01: mov ax, 41a7h ;
mul bx ;
mov bx, ax ; bx=new pseudo-random number
mov al, ah ;
xor ah, ah ; al=character, ah=color code
stosw ;
loop @01 ; after loop, di=0fa0h
; ------------ initialize second page of video memory. a counter and a
; cycle length is assigned to each character.
mov cx, 07d0h ; repeat 2000x
@02: mov ax, 41a7h ;
mul bx ;
mov bx, ax ; values between 01h-0ffh
or ah, 01h ;
mov al, ah ; al=counter, ah=cycle length
stosw ;
loop @02 ; after loop, di=1f40h
; ------------ initialize beam positions
mov cx, 0050h ; repeat 80x
@03: mov ax, 41a7h ;
mul bx ;
mov bx, ax ;
xchg al, ah ; rotate ah to highest bits
rol ax, 1 ; of beam position
rol ax, 1 ;
and ah, 03h ; beam position between 0-03ffh
stosw ;
loop @03 ; after loop, di=1fe0h
;------------- main cycle ------------------ ;
; ------------ decrease counter and change character if counter=0
xor bp, bp ; bp=virtual screen size
main: xor di, di ;
@04: mov si, 0fa0h ; si points to page 2
add si, di ;
dec byte [si] ; decrease counter
jnz @06 ;
mov ax, 41a7h ; get new pseudo-random number
mul bx ;
mov bx, ax ;
mov [di], ah ; change character on screen
test ah, 2ah ;
jz @05 ;
; ------------ reset counter and change speed if necessary
mov ax, [si] ; do not change speed
@05: mov al, ah ; change speed
mov [si], ax ; reset counter
@06: inc di ;
inc di ; move to next character
cmp di, 0fa0h ;
jnz @04 ; after loop, di=0fa0h
; ------------ vertical blank timing
mov dx, 03dah ;
@07: in al, dx ;
test al, 08h ;
jnz @07 ; jump if vb in progress
@08: in al, dx ;
test al, 08h ;
jz @08 ; jump if no vb in progress
; ------------ update virtual screen size & beam position
shl di, 1 ; move to page 3
cmp bp, 0100h ; check if virtual screen has
jnc @09 ; reached its full size
inc bp ;
@09: mov ax, [di] ;
inc ax ;
cmp ax, 0400h ; if beam position=0400h then
jnz @10 ; set beam position to 0
cbw ;
@10: stosw ; update beam position
; ------------ check where the beam is located on the screen
cmp ax, bp ; beam vs. virtual screen size
jnc @12 ;
mov cx, 00a0h ; cl=row size, ch=color code
mov dx, 00e4h ; dl=offset, dh=head+body status
cmp al, dl ;
jnc @11 ; take action according to
cmp al, 1ch ; beam position
jnc @12 ;
mov ch, 0fh ;
xor dl, dl ;
cmp al, 03h ;
jc @11 ;
mov ch, 0ah ;
mov dl, 03h ;
cmp al, 19h ;
rcl dh, 1 ; set dh=1 if 02h<al<19h
; ------------ update colors on visible screen
@11: sub al, dl ; calculate memory address
mul cl ; of color code
lea si, [di-1f41h] ;
add si, ax ;
mov [si], ch ; update color on screen
or dh, dh ;
jz @12 ; if 02h<al<19h then
add si, 01e0h ; update color 3 rows below
mov ch, 0fh ;
mov [si], ch ;
; ------------ loop through all the beams and check if the user has
; pressed a key
@12: cmp di, 1fe0h ; go to next beam
jnz @09 ;
mov ah, 01h ; get keyboard status
int 16h ;
jnz exit ; exit if a key is pressed
jmp main ; if not, continue main cycle
; ------------ reset screen and exit to system
exit: xor ax, ax ; read character from buffer
int 16h ;
mov ax, 0003h ; clear screen
int 10h ;
mov ah, 01h ; enable cursor
mov cx, 0607h ;
int 10h ;
mov ax, 4c00h ; exit to system
int 21h ;