In the year 1991 it was not very common in old Germany that we pupils in eleventh grade had computer science classes at school. As unusual as the computer science lessons were for us students, those lessons were even more unusual for our teachers. Few of my mates and me already had computers since the 4th or 5th grade, however our teachers encountered computers and programming in their adulthood for the first time. So there was some kind of generation gap.
Nevertheless, our computer science teacher had very solid knowledge on programming with Pascal (especially Turbo Pascal) and he was very keen to see what we youngsters were up to on computing. So he had a great idea and proposed that for our certificate grade of that year’s computer science course we were allowed to present a program of our own (if we wanted to). Yes, I wanted to! A class mate of mine already got very much into object orientated programming with the newest version of Turbo Pascal back then, and as I did not want to submit some “me-too” code, I decided to go for an X86 assembly program for MS-DOS.
As in the 1980s and 1990s computer viruses for the MS-DOS operating system were doing the rounds, I stumbled over some reports regarding the Herbstlaub Virus, also known as Cascade Virus. As an effect of being infected by the Cascade Virus, different letters printed on a PC’s text screen would fall down from time to time, one after the other (as of this video ).
“Herbstlaub” is German for “autumn leaves” - the Cascade Virus is also called Herbstlaub Virus as it makes the letters drop down from the top of the screen to the bottom, similar to autumn, which makes the leaves of the trees drop down from the branches to the ground.
Yes, that would be the kind of program I wanted to submit! Don’t get me wrong,
I did not want to submit a computer virus, I just wanted to submit a program simulating
that Herbstlaub Virus’s
effect of letters falling down on a computer’s screen. Or what I thought that effect
was, as there neither was Youtube back then where I could
watch a video of that effect nor I ever saw
the Herbstlaub Virus in
action. So I implemented my interpretation of that effect as a TSR
program and presented it to my computer sciences teacher
As it now turns out now, my TSR’s “Herbstlaub” effect was like the Cascade Virus on speed.
I was lucky, my teacher liked the program, he was keen on understanding the assembly code and gave me an A grade! Below find some images before and after invoking “Herbstlaub” (and above an according video). The screenshots were taken from a DOSBox emulator software emulating MS-DOS on a modern operating system with “Herbstalub” up and running:
The screenshots above on the right hand side suggest that the Herbstlaub algorithm could also be used to create artificial worlds for side scroller games. Imagine a little space ship shooting holes into the pile of letters with the letters rearranging immediately as of the Herbstlaub algorithm, making the pile collapse accordingly…
The assembly code for “Herbstlaub” requires the Turbo Assembler for getting assembled to a running “Herbstlaub” executable:
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
TITLE HERBST.ASM version 3.2b
;NOCH MACHEN --> IN AL,60H: ...PUSH AX ...POP AX!!!!!
;=============================================================================
; HOTKEY --> FRAME für ASSEMBLER-HOTKEY-PROGRAMME
; (W) 1991 BY S.STEINER
;=============================================================================
MAXCHAR EQU 80 ;80 Zeichen pro Zeile!?!
KEYMASK EQU 00001001B ;ALT+RSHIFT ausmaskieren...
INVMASK EQU 11110110B ;Invertierte KEYMASK!!!
SCANKEY EQU 32 ;SCAN-Code des HOT-KEYs ("D")...
ID_WORD EQU "HK" ;Kenn-Word!
;-----------------------------------------------------------------------------
SAVEREGS MACRO ;Alle REGs auf dem STACK sichern
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH DI
PUSH SI
PUSH BP
ENDM
;=============================================================================
LOADREGS MACRO ;Alle REGs vom STACK zurückholen
POP BP
POP SI
POP DI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
POPF
ENDM
;=============================================================================
NEUSTACK MACRO
LOCAL NEUSCHL
MOV CS:[ALTSS],SS ;<SS> in ALTSS sichern
MOV CS:[ALTSP],SP ;<SP> in ALTSP sichern
PUSH CS ;Neuen STACK einrichten
POP SS
MOV SP,OFFSET STAPEL
PUSH CX ;REGS sichern
PUSH DS
PUSH SI
MOV CX,64 ;Schleifenzähler
MOV DS,CS:[ALTSS] ;<DS> mit DOS-SS laden
MOV SI,CS:[ALTSP] ;<SI> mit DOS-SI laden
NEUSCHL: PUSH WORD PTR DS:[SI] ;Word aus DOS-Stack auf MAIN-Stack
INC SI ;SI auf das nächste Word
INC SI
LOOP NEUSCHL ;alle 64 Words abarbeiten
POP SI ;REGS restaurieren
POP DS
POP CX
ENDM
;=============================================================================
ALTSTACK MACRO
LOCAL ALTSCHL
PUSH CX ;REGS sichern
PUSH DS
PUSH SI
MOV CX,64 ;Schleifenzähler
MOV DS,CS:[ALTSS] ;<DS> mit DOS-SS laden
MOV SI,CS:[ALTSP] ;<SI> MIT DOS-SP laden
ADD SI,128 ;SI auf den Anfang des DOS-Stack
ALTSCHL: DEC SI ;SI auf das vorhergehende Stack-Word
DEC SI
POP WORD PTR DS:[SI] ;Word vom MAIN-Stack auf DOS-Stack
LOOP ALTSCHL ;alle 64 Words abarbeiten
POP SI ;REGS restaurieren
POP DS
POP CX
MOV SP,CS:[ALTSP] ;<SP> und <SS> restaurieren
MOV SS,CS:[ALTSS]
ENDM
;=============================================================================
ASSUME CS:PRGM, DS:PRGM
PRGM SEGMENT
ORG 100H
START: JMP INSTALL
;=============================================================================
DB 192 DUP (0)
STAPEL EQU $ ;Neuer Stapel
ALTSS DW 0 ;<SS> und <SP> hier merken
ALTSP DW 0
ALT09 DD 0 ;Alte Vektoren der INTS 09H
ALT13 DD 0 ; 13H
ALT28 DD 0 ; 28H
ALT4A DD 0 ; 4AH
INDOS DD 0 ;ADR des INDOS-Flags
AKTIV DB 0 ;AKTIV-Flag (Hauptprog aktiv)
INBIOS DB 0 ;INBIOS-Flag (INT 13H aktiv)
;=============================================================================
;Speicher für das zu aktivierende Programm
;=============================================================================
XMAX DW ?
YMAX DW ?
MERK DB ?
;==============================================================================
NEU13 PROC FAR ;HD/DISK-INT (NICHT unterbrechen!)
MOV CS:[INBIOS],1 ;INT 13H ist aktiv
PUSHF ;INT-Aufruf simulieren
CALL CS:[ALT13]
MOV CS:[INBIOS],0 ;INT 13H nicht mehr aktiv
RET 2 ;INT beenden
NEU13 ENDP
;=============================================================================
NEU4A PROC FAR ;Schon installiert-INT
;(4A: Alarm INT...)
CMP AX,ID_WORD ;<AX> gleich ID_WORD?
JNZ END4A ;NEIN --> END4A
MOV AX,0FFH ;<AX> auf 0FFH
IRET ;INT beenden
END4A: PUSHF ;INT-Aufruf simulieren
CALL CS:[ALT4A]
IRET ;INT beenden
NEU4A ENDP
;==============================================================================
NEU09 PROC FAR ;Tastatur-INT abfangen
PUSHF ;INT-Aufruf simulieren
CALL CS:[ALT09]
CLI ;INTS sperren
PUSH BX ;Benutzten REGS sichern
PUSH DS
LDS BX,CS:[INDOS] ;INDOS-SEG in <CS>, INDOS-OFS in <BX>
CMP BYTE PTR [BX],0 ;DOS AKTIV?
POP DS ;REGS restaurieren
POP BX
JZ PRUEF ;NEIN --> PRUEF
IRET
NEU09 ENDP
;-----------------------------------------------------------------------------
NEU28 PROC FAR ;Wird vom DOS aufgerufen...
PUSHF ;INT-Aufruf simulieren
CALL CS:[ALT28]
CLI ;INTS sperren
;------------------------------------------------------------------------------
PRUEF: CMP BYTE PTR CS:[INBIOS],0 ;DISK/HD-INT aktiv?
JNZ ENDCHECK ;JA --> ENDCHECK
CMP BYTE PTR CS:[AKTIV],0 ;MAIN schon AKTIV?
JNZ ENDCHECK ;JA --> ENDCHECK
PUSH DS
PUSH AX
MOV AX,40H ;DS auf BIOS-VAR-SEG
MOV DS,AX
MOV AL,BYTE PTR DS:[17H] ;BIOS-Tastatur-Flag in <AL>
AND AL,KEYMASK ;Flag maskieren mit 'KEYMASK'
CMP AL,KEYMASK ;'KEYMASK'gedrückt?
POP AX
POP DS
JNZ ENDCHECK ;NEIN --> ENDCHECK
IN AL,60H ;Tastatur-PORT abfragen
CMP AL,32 ;'D' gedrückt?
JNZ ENDCHECK
JMP MAIN ;JA --> MAIN
ENDCHECK: IRET ;INT beenden
NEU28 ENDP
;------------------------------------------------------------------------------
; XYCALC: Aus XY die VIDMEM-ADR. berechnen
;------------------------------------------------------------------------------
XYCALC PROC NEAR
MOV AX,DI ;Y-Pos in <AX>
MUL CS:[XMAX] ;<AX>:=YPOS*XMAX
MOV BX,SI ;<BX> mit XPOS laden
SHL BX,1 ;<BX>:=XPOS*2
ADD BX,AX ;<BX>:=<AX>+<BX>
ADD BX,DS:[4EH] ;Offset der Bildschirmseite drauf
RET
XYCALC ENDP
;------------------------------------------------------------------------------
; READCH: Zeichen an <SI>/<DI> (X/Y) in <DX> einlesen
;------------------------------------------------------------------------------
READCH PROC NEAR
CALL XYCALC
MOV DX,ES:[BX] ;Adressierter VIDMEM in <BX>
RET
READCH ENDP
;------------------------------------------------------------------------------
; WRITECH: Zu schreibendes Zeichen in <SI>/<DI> (X/Y) in <CX> übergeben
;------------------------------------------------------------------------------
WRITECH PROC NEAR
PUSH DX ;<DX> merken
CALL XYCALC
POP DX ;<DX> restaurieren
MOV ES:[BX],CX ;<CX> in den VIDEOSPEICHER hauen
RET
WRITECH ENDP
;------------------------------------------------------------------------------
; PAUSE : Länge in <CX> übergeben
;------------------------------------------------------------------------------
PAUSE PROC NEAR
LAUBPAUS: PUSH CX
MOV CX,0FFFFH ;PAUSE ----->
REP NOP ;<----- PAUSE
POP CX
LOOP LAUBPAUS ;<----- PAUSE
RET
PAUSE ENDP
;------------------------------------------------------------------------------
; FALLDOWN
;------------------------------------------------------------------------------
FALLDOWN PROC NEAR
CALL READCH
CMP DL,32
JNZ CHECK0
RET
CHECK0: PUSH SI
PUSH DI
CHECK1: CMP DI,CS:[YMAX] ;Y < YMAX ?
JAE CHECK2 ;NEIN --> CHECK2
PUSH DX ;Zeichen merken!
PUSH DI ;Y merken
INC DI ;Y:=Y+1
CALL READCH ;Zeichen an neuer Y-Pos lesen
CMP DL,32 ;Leerzeichen?
POP DI ;Y zurückholen
POP DX ;Zeichen zurückholen
JNZ CHECK2 ;KEIN Leerzeichen --> CHECK2
MOV CX,0220H ;und SPACE in <AX>
CALL WRITECH ;Aktuelle Pos mit SPACE löschen
INC DI ;Y:=Y+1 (nächste Zeile)
MOV CX,DX ;Gelesenes CHAR in zu schreibendes
CALL WRITECH ;Zeichen verschieben
JMP CHECKEND
CHECK2: CMP DI,CS:[YMAX] ;Y < YMAX ?
JAE CHECK3 ;NEIN --> CHECK2
CMP SI,0 ;X > 0 ?
JZ CHECK3 ;NEIN --> CHECK3
PUSH DX ;Zeichen merken!
PUSH SI ;X merken
DEC SI ;X:=X-1
CALL READCH ;Zeichen an neuer X-Pos lesen
CMP DL,32 ;Leerzeichen?
POP SI ;X zurückholen
POP DX ;Zeichen zurückholen
JNZ CHECK3 ;KEIN Leerzeichen --> CHECK3
PUSH DX ;Zeichen merken!
PUSH SI ;X merken
PUSH DI ;Y merken
DEC SI ;X:=X-1
INC DI ;Y:=Y+1
CALL READCH ;Zeichen an neuer XY-Pos lesen
CMP DL,32 ;Leerzeichen?
POP DI ;Y zurückholen
POP SI ;X zurückholen
POP DX ;Zeichen zurückholen
JNZ CHECK3 ;KEIN Leerzeichen --> CHECK3
MOV CX,0220H ;und SPACE in <AX>
CALL WRITECH ;Aktuelle Pos mit SPACE löschen
DEC SI ;Y:=Y+1 (nächste Zeile)
MOV CX,DX ;Gelesenes CHAR in zu schreibendes
CALL WRITECH ;Zeichen verschieben
JMP CHECKEND ;Zeichen wurde verschoben
;Nochmal --> CHECK1
CHECK3: CMP DI,CS:[YMAX] ;Y < YMAX ?
JAE CHECKEND ;NEIN --> CHECK2
MOV AX,CS:[XMAX] ;<AX> mit XMAX laden
SHR AX,1 ;Durch 2 Teilen (Attr+Char!)
DEC AX ;Nochmal einen runter
CMP SI,AX ;<SI> gleich rechter Rand?
JZ CHECKEND ;NEIN --> CHECKEND
PUSH DX ;Zeichen merken!
PUSH SI ;X merken
INC SI ;X:=X+1
CALL READCH ;Zeichen an neuer Y-Pos lesen
CMP DL,32 ;Leerzeichen?
POP SI ;Y zurückholen
POP DX ;Zeichen zurückholen
JNZ CHECKEND ;KEIN Leerzeichen --> CHECKEND
PUSH DX ;Zeichen merken!
PUSH SI ;X merken
PUSH DI ;Y merken
INC SI ;X:=X-1
INC DI ;Y:=Y+1
CALL READCH ;Zeichen an neuer XY-Pos lesen
CMP DL,32 ;Leerzeichen?
POP DI ;Y zurückholen
POP SI ;X zurückholen
POP DX ;Zeichen zurückholen
JNZ CHECKEND ;KEIN Leerzeichen --> CHECKEND
MOV CX,0220H ;und SPACE in <AX>
CALL WRITECH ;Aktuelle Pos mit SPACE löschen
INC SI ;Y:=Y+1 (nächste Zeile)
MOV CX,DX ;Gelesenes CHAR in zu schreibendes
CALL WRITECH ;Zeichen verschieben
CHECKEND: POP DI ;Alte X-Pos und Y-Pos zur
POP SI ;weiternen Berechnung zurück-
;holen...
RET
FALLDOWN ENDP
;=============================================================================
MAIN PROC FAR
MOV CS:[AKTIV],1 ;MAIN ist momentan aktiv
NEUSTACK ;DOS-STACK sichern (sehr fraglich?!?!?)
SAVEREGS ;REGS sichern
sti
MOV AX,40H ;DS auf BIOS-VAR-SEG
MOV DS,AX
MOV AL,DS:[17H] ;BIOS-TAST-Flag auslesen
AND AL,INVMASK ;Invertierte KEYMASK!!!
MOV BYTE PTR DS:[17H],AL ;Flags zurücksetzen!!!
;=============================================================================
; Das war's wohl... Hier steht das zu aktivierende Programm... -->
;=============================================================================
MOV AH,0FH ;Auslesen des Videomodus...
INT 10H
CMP AH,MAXCHAR ;Min. 80 Zeichen Bildschirm?
Jae aber ;NEIN --> ENDMAIN
jmp endmain
aber: CMP AL,2 ;Grafik-Karten & Moduscheck
JZ MONO ;Modus 2 --> MONO
CMP AL,7
JZ MONO ; 7 --> MONO
CMP AL,3
JZ COLR ; 3 --> COLR
JMP ENDMAIN ;Grafik im Augenblick aktiv --> ENDMAIN
MONO: MOV CX,0B000H ;SEGADR des VIDEOMEM bei MONO
JMP WEITER ;COLR überspringen...
COLR: MOV CX,0B800H ;SEGADR des VIDEOMEM bei COLR
WEITER: MOV ES,CX ;In das EXTRA-SEGMENT schreiben <--
KEYCLEAR: IN AL,60H
CMP AL,128
JB KEYCLEAR
;=============================================================================
HERBST: MOV AX,40H
MOV DS,AX ;<DS> auf BIOS-VarSeg
MOV AX,DS:[4AH] ;XMAX errechnen...
SHL AX,1
MOV CS:[XMAX],AX
MOV AL,DS:[84H] ;YMAX errechnen...
XOR AH,AH
MOV CS:[YMAX],AX
XOR SI,SI ;X-Pos.
XOR DI,DI ;Y-Pos.
LOSCHFL: INC SI ;X erhöhen
CMP SI,DS:[4AH] ;Rechter Rand? (Anz. Zeich. pro Zeil.)
JZ LOZEIL ;JA --> LOZEIL
JMP LOSCHFL ;NEIN -->LÖSCHL_F(lag)
LOZEIL: XOR SI,SI ;X auf 0
INC DI ;Y erhöhen
CMP DI,CS:[YMAX] ;Zuweit?
JBE LOSCHFL ;Nochmal LOSCHFL
;------------------------------------------------------------------------------
; Buchstaben fallen lassen:
;------------------------------------------------------------------------------
HERBSTRT: XOR SI,SI
MOV DI,CS:[YMAX]
SETSCHL: CALL READCH
CMP DL,32
JZ SPRUNG
SPRUNG: INC SI ;X erhöhen
CMP SI,DS:[4AH] ;Rechter Rand? (Anz. Zeich. pro Zeil.)
JZ NEUZEIL ;JA --> NEUZEIL
JMP SETSCHL ;NEIN -->SETSCHL
NEUZEIL: XOR SI,SI ;X auf 0
DEC DI ;Y erniedrigen
CMP DI,0FFFFH ;Zuweit?
JNZ SETSCHL ;Nochmal SETSCHL
FUERDICH: XOR SI,SI
MOV DI,CS:[YMAX]
SETSCHX: INC CS:[MERK]
CMP CS:[MERK],7
JNE FUCKOFF
MOV CS:[MERK],0
CALL FALLDOWN
FUCKOFF: INC SI ;X erhöhen
CMP SI,DS:[4AH] ;Rechter Rand? (Anz. Zeich. pro Zeil.)
JZ NEUZEIX ;JA --> NEUZEIL
JMP SETSCHX ;NEIN -->SETSCHL
NEUZEIX: XOR SI,SI ;X auf 0
DEC DI ;Y erniedrigen
CMP DI,0FFFFH ;Zuweit?
JNZ SETSCHX ;Nochmal SETSCHL
in al,60h
cmp al,128
JAE FUERDICH
;=============================================================================
ENDMAIN: LOADREGS ;REGS restaurieren
ALTSTACK ;DOS-STACK restaurieren (Hmmm, s.oben!)
MOV CS:[AKTIV],0 ;MAIN ist NICHT mehr aktiv
IRET
MAIN ENDP
;=============================================================================
IDSTR DW ID_WORD ;ID_WORD als ID-STRing
;=============================================================================
INSTALL PROC NEAR
PUSH CS ;<DS> gleich <CS>
POP DS
MOV AX,ID_WORD ;Kenn-BYTE in <AX>
INT 4AH ;Prüf-INT aufrufen!
CMP AX,0FFH ;Schon installiert ?
JZ REINST ;JA --> REINST
;-----------------------------------------------------------------------------
MOV AX,3509H ;Vektor von INT 09 lesen
INT 21H
MOV WORD PTR [ALT09],BX ;Alten Vektor sichern
MOV WORD PTR [ALT09+2],ES
MOV AX,3513H ;Vektor von INT 13 lesen
INT 21H
MOV WORD PTR [ALT13],BX ;Alten Vektor sichern
MOV WORD PTR [ALT13+2],ES
MOV AX,3528H ;Vektor von INT 28 lesen
INT 21H
MOV WORD PTR [ALT28],BX ;Alten Vektor sichern
MOV WORD PTR [ALT28+2],ES
MOV AX,354AH ;Vektor von INT 4A lesen
INT 21H
MOV WORD PTR [ALT4A],BX ;Alten Vektor sichern
MOV WORD PTR [ALT4A+2],ES
;-----------------------------------------------------------------------------
MOV AX,2509H ;INT 09 neu setzen
MOV DX,OFFSET NEU09
INT 21H
MOV AX,2513H ;INT 13 neu setzen
MOV DX,OFFSET NEU13
INT 21H
MOV AX,2528H ;INT 28 neu setzen
MOV DX,OFFSET NEU28
INT 21H
MOV AX,254AH ;INT 4A neu setzen
MOV DX,OFFSET NEU4A
INT 21H
MOV AH,34H ;ADR des INDOS-Flags ermitteln
INT 21H
MOV WORD PTR [INDOS],BX ;In den Speicherstellen INDOS ablegen
MOV WORD PTR [INDOS+2],ES
MOV AH,09 ;Installationsmeldung ausgeben
MOV DX,OFFSET MSG0
INT 21H
MOV DX,OFFSET INSTALL ;Residenten Programmteil errechnen
ADD DX,15
MOV CL,4
SHR DX,CL
MOV AX,3100H ;Resident beenden
INT 21H
;=============================================================================
REINST: MOV AX,3509H ;Vektor von INT 09 lesen
INT 21H
CMP WORD PTR ES:[IDSTR],ID_WORD ;Gefunden?
JNZ ERROR ;NEIN --> ERROR
;-----------------------------------------------------------------------------
MOV AX,3513H ;Vektor von INT 13 lesen
INT 21H
CMP WORD PTR ES:[IDSTR],ID_WORD ;Gefunden?
JNZ ERROR ;NEIN --> ERROR
;-----------------------------------------------------------------------------
MOV AX,3528H ;Vektor von INT 28 lesen
INT 21H
CMP WORD PTR ES:[IDSTR],ID_WORD ;Gefunden?
JNZ ERROR ;NEIN --> ERROR
;-----------------------------------------------------------------------------
MOV AX,354AH ;Vektor von INT 4A lesen
INT 21H
CMP WORD PTR ES:[IDSTR],ID_WORD ;Gefunden?
JNZ ERROR ;NEIN --> ERROR
;-----------------------------------------------------------------------------
PUSH DS ;DS sichern
LDS DX,ES:[ALT09] ;INT 09 Vektor restaurieren
MOV AX,2509H
INT 21H
LDS DX,ES:[ALT13] ;INT 13 Vektor restaurieren
MOV AX,2513H
INT 21H
LDS DX,ES:[ALT28] ;INT 28 Vektor restaurieren
MOV AX,2528H
INT 21H
LDS DX,ES:[ALT4A] ;INT 4A Vektor restaurieren
MOV AX,254AH
INT 21H
POP DS ;DS restaurieren
PUSH ES ;ES sichern
MOV ES,ES:[02CH] ;SEG-ADR des Environment aus PSP lesen
MOV AH,49H ;Speicher freigeben
INT 21H
POP ES ;ES restaurieren
MOV AH,49H ;Restlichen Speicher freigeben
INT 21H
MOV AH,09H ;Reinstallationsmeldung ausgeben
MOV DX,OFFSET MSG1
INT 21H
MOV AX,4C00H ;Prog beenden
INT 21H
ERROR: MOV AH,09 ;Fehlermeldung ausgeben
MOV DX,OFFSET MSG3
INT 21H
MOV AX,4C01H ;Prog mit FEHLER-CODE 1 beenden
INT 21H
;-----------------------------------------------------------------------------
INSTALL ENDP
;=============================================================================
MSG0 DB 13,10
DB "[0m"
DB "ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸",13,10
DB "³[7;1;37m tsrtest... ([C] 1991 by S.STEINER) [0m³",13,10
DB "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´",13,10
DB "³ Das Programm <LAUBTSR-7-> wurde ³",13,10
DB "³ erfolgreich INSTALLIERT! ³",13,10
DB "³[1m >>> Aufruf mit ALT+RSHIFT+D <<< [0m³",13,10
db "³ Abbruch mit IRGENDEINER beliebigen Taste ³",13,10
db "³ (also auch ALT/SHIFT oder CONTROL...) ³",13,10
DB "ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;",13,10
DB "$"
MSG1 DB 13,10
DB "[0m"
DB "ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸",13,10
DB "³[7;1;37m tsrtest... ([C] 1991 by S.STEINER) [0m³",13,10
DB "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´",13,10
DB "³ Das Programm <HOTKEY.COM> wurde ³",13,10
DB "³[1m erfolgreich entfernt...! [0m³",13,10
DB "ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;",13,10
DB "$"
MSG3 DB 13,10,7
DB "[0m"
DB "ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸",13,10
DB "³[7;1;37m tsrtest... ([C] 1991 by S.STEINER) [0m³",13,10
DB "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´",13,10
DB "³ Das Programm <HOTKEY.COM> konnte leider ³",13,10
DB "³ NICHT entfernt werden! ³",13,10
DB "³ Nachträglich installierte TSR-Programme ³",13,10
DB "³ entferernen und nocheinmal versuchen... ³",13,10
DB "³[1m --> Sonst RESET drücken! [0m³",13,10
DB "ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;",13,10
DB "$"
PRGM ENDS
END START