Skip to content

Commit 41ad330

Browse files
authored
Commit
1 parent 4f8da19 commit 41ad330

File tree

5 files changed

+773
-0
lines changed

5 files changed

+773
-0
lines changed

SC.ASM

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
;-----------------------------------------------------------------------:
2+
; A true matrix screensaver, this version works ONLY in bw modes :
3+
; Use command tail in PSP as stack and local var space :
4+
; Written by: Yll Buzoku :
5+
; Date: 27/08/2021 :
6+
;-----------------------------------------------------------------------:
7+
CODE SEGMENT
8+
ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE
9+
;-----------------------------------------------------------------------:
10+
; PSP equates area. :
11+
;-----------------------------------------------------------------------:
12+
ORG 0FFh
13+
VARS PROC NEAR
14+
stkend db ? ;Stack tail, max 60 bytes, go into FCB area
15+
seed dw ? ;RNG seed value, overlay jmp TRANS
16+
inFlag db ? ;Bits [7:1] reserved, Bit [0]-inTSR flag
17+
VARS ENDP
18+
;-----------------------------------------------------------------------:
19+
ORG 100H
20+
EP PROC NEAR
21+
jmp TRANS ;Just save a word by recycling this instruction
22+
curs dw ? ;Saves BDA cursor word before modification
23+
ticks dw ? ;Timeout comparator var, 0888h is 2 minutes
24+
ogss dw ? ;Caller stack segment
25+
ogsp dw ? ;Caller stack pointer
26+
EP ENDP
27+
28+
TSRMAIN PROC NEAR
29+
;Saves current screen and starts scrolling ascii chars down the screen.
30+
;First manually set segregs
31+
cli
32+
mov word ptr cs:[ogsp], sp
33+
mov sp, ss
34+
mov word ptr cs:[ogss], sp
35+
mov sp, cs ;Move code segment into ss
36+
mov ss, sp
37+
mov sp, word ptr cs:[stkend] ;Point sp to offset of the bottom of stk
38+
sti
39+
40+
push ax
41+
push bx
42+
push cx
43+
push dx
44+
push ds
45+
push es
46+
push si
47+
push di
48+
;Reset segvars
49+
push cs
50+
pop ax
51+
mov ds, ax
52+
mov es, ax
53+
;Now detect video mode
54+
;mov ah, 0Fh
55+
;int 10h
56+
;Returns al=Vid mode, ah=#of cols, bh=active page
57+
;mov byte ptr [mode], al
58+
;mov byte ptr [cols], ah
59+
;mov byte ptr [page], bh
60+
;mov word ptr [regseg], 0b800h ;Assume colour card
61+
;cmp al, 07h ;Are we a BW card, currently active?
62+
;jne i1
63+
;sub word ptr [regseg], 800h ;Move it back to bw space
64+
i1:
65+
;First we create a first seed
66+
xor ah, ah
67+
int 1Ah
68+
mov word ptr [seed], dx ;Get ticks into seed var
69+
70+
xor bh, bh ;0 page
71+
mov ah, 03h ;read cursor pos
72+
int 10h
73+
mov word ptr [curs], dx ;Save cursor pos
74+
75+
; mov ax, word ptr [regseg] ;Get actual segment
76+
mov ax, 0b000h ;Load bw seg
77+
push ds
78+
mov ds, ax ;Set ds to point to bios regen
79+
xor si, si
80+
mov di, OFFSET regen ;es points to current code segment
81+
mov cx, 2000 ;2000 words to be transferred
82+
rep movsw
83+
pop ds ;Get original ds back
84+
;Buffers copied, time for some fun!
85+
iloop: ;Main loop of this meme
86+
87+
; mov bl, byte ptr [cols]
88+
mov bl, 80 ;80 columns, hardcoded
89+
call rndgen
90+
mov al, bl ;Move the random column into al
91+
;Get a random column function
92+
mov bl, 0FFh ;Sub function options
93+
call rndgen
94+
mov ah, bl ;Move random column function into ah
95+
call col
96+
97+
test byte ptr [inFlag], 1 ;Will only be zero if key pressed
98+
jnz iloop
99+
iexit:
100+
;Exit below here. Return regen to regseg
101+
push cs
102+
pop ds
103+
; mov ax, word ptr [regseg]
104+
mov ax, 0b000h ;bw seg
105+
mov es, ax
106+
mov si, OFFSET regen
107+
xor di, di
108+
mov cx, 2000
109+
rep movsw
110+
mov dx, word ptr [curs] ;Get original cursor position back
111+
xor bh, bh ;0 page
112+
mov ah, 02h ;set cursor
113+
int 10h
114+
115+
pop di
116+
pop si
117+
pop es
118+
pop ds
119+
pop dx
120+
pop cx
121+
pop bx
122+
pop ax
123+
cli
124+
mov sp, word ptr cs:[ogss]
125+
mov ss, sp
126+
mov sp, word ptr cs:[ogsp]
127+
sti
128+
iret ;Alternate exit point, when exiting from screensaver
129+
TSRMAIN ENDP
130+
131+
IRQ0 PROC FAR ;Timer replacement
132+
;Timer initiates whether or not to go into screensaver
133+
;Wraps old int 09h, to continue gracefully after hardware EOI
134+
jmp short irq0in
135+
dw 55AAh ;Installed signature
136+
irq0in:
137+
pushf ;Fake interrupt call, could just inc sp
138+
db 09Ah ;Far Call, manually encoded
139+
irq0o: dw ?
140+
irq0s: dw ?
141+
test byte ptr cs:[inFlag], 1
142+
jnz irq0cont ;If its 1, dont inc ticks, proceed as normal
143+
inc word ptr cs:[ticks]
144+
;DEBUG DEBUG DEBUG DEBUG DEBUG
145+
; cmp word ptr cs:[ticks], 0B6h ;Temp 10 seconds 0888h
146+
;DEBUG DEBUG DEBUG DEBUG DEBUG
147+
cmp word ptr cs:[ticks], 0888h
148+
jb irq0cont
149+
150+
inc byte ptr cs:[inFlag] ;Set bit 0, indicate going into TSR
151+
mov word ptr cs:[ticks], 0
152+
jmp tsrmain
153+
irq0cont:
154+
iret
155+
IRQ0 ENDP
156+
157+
IRQ1 PROC FAR ;Keyb replacement
158+
mov word ptr cs:[ticks], 0 ;Null out the ticks counter
159+
mov byte ptr cs:[inFlag],0
160+
db 0EAh ;Far jump to original interrupt handler
161+
irq1o: dw ? ;Var space for og handler/part of opcode
162+
irq1s: dw ?
163+
IRQ1 ENDP
164+
165+
RNDGEN PROC NEAR
166+
;----------------------------------------------------
167+
; Generates a random 8 bit value and returns it. :
168+
; Input: bl = Modulo value (max value plus 1). :
169+
; Ret: bl = Random return value. :
170+
; All registers preserved. :
171+
;----------------------------------------------------
172+
push ax
173+
push cx
174+
push dx
175+
mov ax, 25173 ;Random multiplier
176+
mul word ptr [seed] ;Multiply to seed
177+
add ax, 13849
178+
mov word ptr [seed], ax
179+
;ax now has new random value
180+
mov cl, bl ;Get max number in cl
181+
xor ch, ch
182+
xor dx, dx ;Clear upper word for division for no overflow?
183+
div cx ;Divide ax by cl
184+
mov bl, dl ;move remainder into bl
185+
186+
pop dx
187+
pop cx
188+
pop ax
189+
ret
190+
RNDGEN ENDP
191+
192+
COL PROC NEAR
193+
;-----------------------------------------------------
194+
; Takes column to scroll down, and scrolls it down. :
195+
; Might generate a new char or even clear column. :
196+
; Input: al=Column number (0-49), ah=Bit 7 :
197+
; ah(7) clear = Scroll column :
198+
; ah(7) set = Add new char + scroll :
199+
; Output: Nothing, ax destroyed. :
200+
;-----------------------------------------------------
201+
push dx
202+
push cx
203+
push bx
204+
push si
205+
206+
xor ch, ch ;Upper row
207+
mov dh, 24 ;Lower row
208+
mov cl, al ;Column to scroll in cl
209+
mov dl, al ;Column to scroll in dl
210+
mov si, ax ;Save col number in si
211+
mov bx, 0700h ;Usual char attrib in bh
212+
test ah, 80h
213+
jz colsub0
214+
215+
mov ax, 0701h ;Scroll col down 1
216+
int 10h
217+
;Now insert a new random char at top
218+
mov dx, si ;Return col number into dl
219+
xor dh, dh ;Row 0
220+
xor bh, bh ;Page 0
221+
mov ah, 02h ;Set cursor pos
222+
int 10h
223+
mov bl, 0FFh ;Max ASCII char value
224+
call rndgen ;Get the char
225+
mov cx, 1 ;1 char to print
226+
mov al, bl ;Move char code into al
227+
mov bh, 00h ;Page number
228+
mov ah, 0Ah ;Write char function
229+
int 10h
230+
jmp short colexit
231+
colsub0:
232+
mov ax, 0701h ;Scroll col down 1
233+
int 10h
234+
colexit:
235+
pop si
236+
pop bx
237+
pop cx
238+
pop dx
239+
ret
240+
COL ENDP
241+
regen: db 4000 dup(?) ;Regen space
242+
;Jettison the code below here
243+
TRANS PROC NEAR ;Transient loader
244+
mov ax, 3508h ;Int 08h, timer hook, to look for signature
245+
int 21h
246+
push cs
247+
pop ds ;Fix ds to current cs
248+
cmp word ptr es:[bx+2], 55AAh ;Check signature
249+
jne proceed
250+
mov dx, OFFSET instmsg
251+
mov ah, 09h
252+
int 21h
253+
mov ax, 4c00h
254+
int 21h
255+
instmsg: db 'Screensaver already installed!',0Ah,0Dh, '$'
256+
proceed:
257+
;Initialise variables
258+
mov word ptr [ticks], 0
259+
mov byte ptr [inFlag], 0
260+
;Turn off interrupts, install handlers
261+
cli
262+
mov ax, 3508h
263+
int 21h ;Save old values
264+
mov word ptr [irq0o], bx
265+
mov bx, es
266+
mov word ptr [irq0s], bx
267+
268+
mov ax,3509h
269+
int 21h
270+
mov word ptr [irq1o], bx
271+
mov bx, es
272+
mov word ptr [irq1s], bx
273+
274+
mov dx, OFFSET IRQ0
275+
mov ax, 2508h ;ah=25 setvector, al=Int 08h
276+
int 21h
277+
278+
push cs ;Reset ds incase int21h clobbers it
279+
pop ds
280+
mov dx, OFFSET IRQ1
281+
mov ax, 2509h
282+
int 21h
283+
284+
sti ;Restart Interrupts
285+
;Print install message
286+
push cs
287+
pop ds
288+
mov dx, OFFSET sucmsg
289+
mov ah, 09h
290+
int 21h ;Print string
291+
;Compute size for TSR
292+
mov ax, OFFSET TRANS
293+
mov cl, 4
294+
shr ax, cl ;Turn number of bytes into paragraphs
295+
inc ax ;Add one for good measure
296+
mov dx, ax
297+
mov ax, 3100h
298+
int 21h
299+
sucmsg: db "Successfully connected to the matrix!",0Ah,0Dh,"$"
300+
TRANS ENDP
301+
302+
CODE ENDS
303+
END EP

SC.COM

4.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)