home *** CD-ROM | disk | FTP | other *** search
- ; ----------------------------------------------------------
- ; Resident V1.1
- ; Copyright (C) 1990 by Torsten Priebe
- ; ----------------------------------------------------------
- ; (zu RESIDENT.COM assemblieren mit Macro Assembler oder
- ; Turbo Assembler: MASM/TASM, LINK/TLINK, EXE2BIN)
-
- cseg segment 'code'
- assume cs:cseg, ds:cseg
-
- ; ----------------------- Konstanten -----------------------
- cr equ 0dh
- lf equ 0ah
- eom equ '$' ; EndOfMessage
- eof equ 1ah
-
- mpxnum equ 0c0h ; Nummer für Multiplex-Intr.
- blinkkey equ 8300h ; Scan-Code von <Alt-'>
-
- maxentry equ 5 ; max. Anzahl an Einträgen
-
- col0color equ 07h ; Farben für Farbmodus
- col1color equ 17h
- col2color equ 1fh
- col0mono equ 07h ; Farben für Monochrome
- col1mono equ 0fh
- col2mono equ 07h
-
- bufsize equ 2048 ; Paragraphen pro Schreibpuffer
-
- intsize equ 512 ; Größe der Iterrupt-Tabelle
- stackln equ 256 ; Größe des Stacks
- mouseln equ 768 ; Größe des Maus-Puffers
-
- colseg equ 0b800h ; CGA/EGA Speicher-Segment
- monoseg equ 0b000h ; Hercules/MDA Speicher-Segment
- scrsize equ 16384 ; Größe des Bildschirmspeichers
-
- ; ------------------- Aufbau eines MCB's -------------------
- ; (ES = MCB-Segment)
- ; ID ('Z' bei letztem MCB)
- mcbid equ byte ptr es:[00h]
- ; PSP des zug. Programms
- mcbpsp equ word ptr es:[01h]
- ; MCB-Länge in Paragraphen
- mcblen equ word ptr es:[03h]
-
- ; -------------------- Beep (Signalton) --------------------
- beep macro
-
- push ax ; Register sichern
- push bx
-
- mov ax,0e07h ; Singnalton erzeugen
- xor bx,bx
- int 10h
-
- pop bx ; Register zurück
- pop ax
-
- endm
-
- ; ---------------------- Daten aus PSP ---------------------
- org 2ch ; Segment des Environments
- myenv dw ?
-
- org 80h ; Kommandoparameter
- parlen db ?
- param db ?
-
- ; -------------------- Programmeinsprung -------------------
- org 100h
- start: jmp main
-
- ; ---------------------- Datenbereich ----------------------
- data db 162*maxentry dup (0)
-
- ; ------------------ Fenster-Informationen -----------------
- wnd1 db '┌',24 dup ('─'),' Resident ',24 dup ('─')
- db '┐',0
- wnd2 db '│',58 dup (' '),'│',0
- wnd3 db '└',58 dup ('─'),'┘',0
-
- popup1 db '"',0
- popup2 db '" wird geladen ...',0
- backmsg db 'Status wird wiederhergestellt ...',0
-
- col0 db ? ; Farbe für Schatten
- col1 db ? ; Farbe für Rahmen
- col2 db ? ; Farbe für Fenstertext
-
- ; ---------------------- Warte-Meldung ---------------------
- crlf db cr,lf,eom ; Zeilenvorschub
- waitmsg db 'Bitte drücken Sie eine Taste, um im '
- db 'unterbrochenen Programm fortzufahren ...'
- db eom
-
- ; ------------------------ Variablen -----------------------
- progmsg db 32 dup (0) ; Programm-Titel
- progpath db 64 dup (0) ; Start-Verzeichnis
- prog db 64 dup (0) ; Programm-Datei
-
- memsize dw ? ; Hauptspeichergröße
- mouse db ? ; Maus-Flag (1=Maus vorhanden)
-
- indos dd ? ; Addrese des "In-DOS"-Flags
- oldi16 dd ? ; alte Interruptvektoren
- oldi21 dd ?
- oldi2f dd ?
-
- possible db 0 ; Flag für "Einsprung möglich"
- waiting db 0 ; Warte-Flag (bei DOS-Funktion)
- blink db 1 ; Intensity/Blink-Flag
-
- ; Puffer für Interrupt-Tabelle
- orgints db intsize dup (?)
- saveints db intsize dup (?)
-
- savess dw ? ; zum Speichern des Stacks
- savesp dw ?
-
- savepsp dw ? ; PSP des unterbr. Programms
- savedta dd ? ; DTA des unterbr. Programms
-
- crtmode db ? ; Video-Modus
- font8x8 db ? ; Flag für EGA/VGA 43/50 Zeilen
-
- scrseg dw ? ; Segment des Videospeichers
-
- savepage db ? ; Bildschirmseite
- savepos dw ? ; Cursorposition
- savecur dw ? ; Cursorform
-
- ; Puffer für Maus-Status
- savemouse db mouseln dup (0)
-
- saveevent dw ? ; User-Event-Handler (Maus)
- savehandl dd ?
-
- savepath db 0,':\' ; Puffer zum Sichern des ...
- buffer db 64 dup (0) ; ... Verzeichnisses
-
- fname db 'C:\' ; für die temporäre Datei
- fill db 13 dup (0) ; nimmt den Dateinamen auf
-
- fhandle dw ? ; Datei-Handle
-
- cmdline db 0,cr ; keine Parameter
-
- fcb1 db 0 ; 2 leere FCB's
- db 11 dup (0)
- db 25 dup (0)
-
- fcb2 db 0
- db 11 dup (0)
- db 25 dup (0)
-
- block equ this byte ; Parameterblock
- envseg dw ?
- fcb1p dd ?
- fcb2p dd ?
- cmdlnp dd ?
-
- ; neuer Stack
- mystack db stackln dup (0)
-
- ; --------------- NewI16 (Tastatur-Interrupt) --------------
- newi16 proc far
-
- cmp ah,00h ; Funktion 00h oder ...
- je getkey
- cmp ah,10h ; ... 10h (MF2-Tastatur)
- je getkey
-
- nochk1: jmp cs:oldi16 ; in alten Handler springen
-
- getkey: pushf ; Taste holen
- call cs:oldi16
-
- push ax ; Register sichern
- push bx
- push cx
- push es
-
- cmp ax,blinkkey ; Blink/Intensity-Umschalter
- jne checkhk
- mov al,0ffh ; Hotkey-Code FFh
- jmp hkfound
-
- checkhk: mov cl,1 ; Afangswert der Schleife
- mov bx,offset data
-
- ; Eintrag nicht belegt?
- nextentr: cmp word ptr cs:[bx],0
- je nothk
- ; Hotkey des Eintrags gedrückt?
- cmp ax,word ptr cs:[bx]
- jne nothk
- mov al,cl
- jmp hkfound
-
- nothk: inc cl ; nächster Eintrag
- add bx,162
- cmp cl,maxentry
- jbe nextentr
-
- jmp reti16
-
- hkfound: les bx,cs:indos ; gerade in einer DOS-Funktion?
- cmp byte ptr es:[bx],0
- jne notnow
-
- call runprog ; Programm aufrufen
-
- reti16: pop es ; Register zurück
- pop cx
- pop bx
- pop ax
-
- iret
-
- notnow: cmp cs:possible,1 ; Warten möglich?
- je setwait
-
- beep
-
- jmp reti16
-
- setwait: mov cs:waiting,al ; Warte-Flag setzen
- jmp reti16
-
- newi16 endp
-
- ; ----------------- NewI21 (DOS-Interrupt) -----------------
- newi21 proc far
-
- cmp ah,01h ; Warten bei Funktion 01h, ...
- je check
- cmp ah,06h ; ... 06h, ...
- jne chknext1
- cmp dl,0ffh
- je check
- chknext1: cmp ah,07h ; ... 07h, ...
- je check
- cmp ah,08h ; ... 08h, ...
- je check
-
- cmp ax,0c01h ; ... 0Ch (Unterf. 01h), ...
- je check
- cmp ax,0c06h ; ... 0Ch (Unterf. 06h), ...
- jne chknext2
- cmp dl,0ffh
- je check
- chknext2: cmp ax,0c07h ; ... 0Ch (Unterf. 07h), ...
- je check
- cmp ax,0c08h ; ... 0Ch (Unterf. 08h) möglich
- je check
-
- nochk2: jmp cs:oldi21 ; in alten Handler springen
-
- check: mov cs:possible,1
-
- pushf ; Interrupt ausführen
- call cs:oldi21
- pushf ; Flags sichern
-
- mov cs:possible,0 ; Flag zurück
-
- cmp cs:waiting,0 ; wurde der Hotkey betätigt?
- je reti21
-
- push ax ; Programmnummer in AL
- mov al,cs:waiting
- mov cs:waiting,0 ; Warte-Flag zurück
-
- call runprog ; Programm aufrufen
-
- pop ax
-
- reti21: popf ; Flags zurück
- ret 2 ; beenden, Flags beibehalten
-
- newi21 endp
-
- ; ---------------- RunProg (Programmaufruf) ----------------
- ; (AL = Programmnummer)
- runprog proc near
-
- push ax ; Register sichern
- push bx
- push cx
- push dx
- push bp
- push si
- push di
- push ds
- push es
-
- push cs ; Datensegment setzen
- pop ds
-
- push ax ; Programmnummer sichern
-
- mov ah,0fh ; Video-Modus testen
- int 10h
- and al,7fh
- cmp al,3 ; CGA/EGA-Textmodus?
- jbe textmode
- cmp al,7 ; Mono-Textmodus?
- je textmode
-
- pop ax ; Stack bereinigen
- beep
- jmp exit
-
- textmode: pop ax ; Programmnummer zurück
- cmp al,0ffh
- jne proghk
- mov al,blink ; Intensity/Blink-Flag setzen
- xor al,1
- mov blink,al
- call setblink ; Intensity/Blinken setzen
- jmp exit
-
- proghk: xor ah,ah ; Programm-Daten kopieren
- dec ax
- mov bx,162
- mul bx
- mov si,offset data+2
- add si,ax
- push ds
- pop es
- mov di,offset progmsg
- mov cx,80
- rep movsw
-
- mov savess,ss ; Stack sichern
- mov savesp,sp
-
- mov ax,ds ; neuen Stack setzen
- cli
- mov ss,ax
- mov sp,offset mystack+stackln
- sti
-
- call prepare ; Aufruf vorbereiten
-
- mov ah,19h ; aktives Laufwerk holen
- int 21h
- add al,65
- mov byte ptr savepath,al
- mov ah,47h ; Verzeichnis holen
- mov dl,0
- mov si,offset buffer
- int 21h
-
- mov ah,0eh ; Laufwerk wechseln
- mov dl,byte ptr progpath
- sub dl,65
- int 21h ; Verzeichnis wechseln
- jc error
- mov ah,3bh
- mov dx,offset progpath
- int 21h
- jc error
-
- mov ax,myenv ; Parameterblock setzen
- mov envseg,ax
- mov word ptr fcb1p,offset fcb1
- mov word ptr fcb1p+2,ds
- mov word ptr fcb2p,offset fcb2
- mov word ptr fcb2p+2,ds
- mov word ptr cmdlnp,offset cmdline
- mov word ptr cmdlnp+2,ds
-
- mov ax,4b00h ; Programm aufrufen
- mov dx,offset prog
- push ds
- pop es
- mov bx,offset block
- int 21h
-
- push cs ; Datensegment zurücksetzen
- pop ds
-
- mov ax,ds ; Stack wiederherstellen
- cli
- mov ss,ax
- mov sp,offset mystack+stackln
- sti
-
- jnc noerror
-
- error: beep
-
- noerror: mov ah,09h ; Zeilenvorschub
- mov dx,offset crlf
- int 21h
-
- mov ah,0fh ; an unteren Bildschirmrand
- int 10h
- push bx ; Seite sichern
- mov ax,1130h ; 8x8-Font gesetzt?
- mov bh,0
- mov dl,24 ; falls keine EGA/VGA
- int 10h
- pop bx
- mov ah,02h
- mov dh,dl
- mov dl,0
- int 10h
-
- mov ah,09h ; Meldung ausgeben und warten
- mov dx,offset waitmsg
- int 21h
- mov ah,00h
- int 16h
-
- mov ah,0eh ; Laufwerk zurücksetzen
- mov dl,byte ptr savepath
- sub dl,65
- int 21h
- mov ah,3bh ; Verzeichnis zurücksetzen
- mov dx,offset savepath
- int 21h
-
- call restore ; alten Status wiederherstellen
-
- cli ; Orginal-Stack setzen
- mov ss,savess
- mov sp,savesp
- sti
-
- exit: pop es ; Register zurück
- pop ds
- pop di
- pop si
- pop bp
- pop dx
- pop cx
- pop bx
- pop ax
-
- ret
-
- runprog endp
-
- ; --------- SetBlink (Setzen von Blinken/Intensity) --------
- ; (AL = 1 für Blinken, 0 für Intensity)
- setblink proc near
-
- push ax ; Flag sichern
- mov ah,0fh
- int 10h
- and al,7fh
- cmp al,7
- jne color ; CGA, EGA/VGA
- mov dx,3b8h ; Hercules/MDA
- jmp useport
-
- color: mov ah,12h
- mov bl,10h
- int 10h
- cmp bl,10h
- jne useint ; EGA/VGA
- mov dx,3d8h ; CGA
- jmp useport
-
- useint: pop bx ; Flag in BL
- mov ax,1003h ; via Intr. 10h setzen
- int 10h
- jmp retsetbl
-
- useport: pop ax ; Flag in AL
- mov cl,5 ; Bit 5 für Blinken/Intensity
- shl al,cl
- or al,09h ; Bits 0 und 3 immer setzen
- out dx,al ; via Port setzen
-
- retsetbl: ret
-
- setblink endp
-
- ; -------------- Prepare (Aufruf vorbereiten) --------------
- prepare proc near
-
- mov ah,62h ; PSP sichern
- int 21h
- mov savepsp,bx
-
- mov ah,50h ; PSP setzen
- mov bx,cs
- int 21h
-
- mov ah,2fh ; DTA sichern
- int 21h
- mov word ptr savedta,bx
- mov word ptr savedta+2,es
-
- push ds ; Interrupts sichern
- push ds
- pop es
- mov di,offset saveints
- xor ax,ax
- mov ds,ax
- mov si,ax
- mov cx,intsize/2
- cli
- rep movsw
- sti
- pop ds
-
- xor ax,ax ; Original-Interrupts zurück
- mov es,ax
- mov di,ax
- mov si,offset orgints
- mov cx,intsize/2
- cli
- rep movsw
- sti
-
- cmp mouse,1 ; Maus vorhanden?
- jne nomouse1
-
- mov ax,0016h ; Maus-Status sichern
- push ds
- pop es
- mov dx,offset savemouse
- int 33h
-
- mov ax,0014h ; Maus-Event-Handler holen
- xor cx,cx
- int 33h
- mov saveevent,cx
- mov word ptr savehandl,dx
- mov word ptr savehandl+2,es
-
- mov ax,0000h ; Maus zurücksetzen
- int 33h
-
- nomouse1: mov ah,0fh ; Video-Modus holen
- int 10h
- and al,7fh ; Bit 7 ausblenden
- mov crtmode,al
- mov savepage,bh
- mov scrseg,colseg
- cmp al,7 ; Mono- oder Hercules-Karte?
- jne segok
- mov scrseg,monoseg
-
- segok: mov font8x8,0
- mov ax,1130h ; Font-Informationen
- mov bh,00h
- mov dl,24 ; falls keine EGA/VGA
- int 10h
- cmp dl,24 ; 25 Zeilen?
- je normfont
- mov font8x8,1
-
- normfont: mov ah,03h ; Cursor-Position holen
- mov bh,savepage
- int 10h
- mov savepos,dx
- mov savecur,cx
-
- mov ah,5ah ; Temporäre Datei erzeugen
- mov cx,0
- mov dx,offset fname
- int 21h
- mov fhandle,ax
-
- push ds ; Bildschirm speichern
- mov ax,scrseg
- mov ds,ax
- mov ah,40h
- mov bx,cs:fhandle
- mov cx,scrsize
- xor dx,dx
- int 21h
- pop ds
-
- call window ; Fenster aufbauen
-
- mov ch,11 ; Meldung ausgeben
- mov cl,14
- mov bl,col2
- mov dx,offset popup1
- call outstr
- mov dx,offset progmsg
- call outstr
- mov dx,offset popup2
- call outstr
-
- mov ax,cs ; eigenen MCB bestimmen
- dec ax
- mov es,ax
-
- next1: mov ax,es ; nächster MCB
- inc ax
- add ax,mcblen
- mov es,ax
-
- mov ah,40h ; MCB speichern
- call saveload
-
- cmp mcbid,'Z' ; letzter MCB?
- jne next1
-
- mov ax,cs ; eigenen MCB bestimmen
- dec ax
- mov es,ax
-
- mov bx,cs ; belegter Speicher in BX
- add bx,mcblen
-
- inc ax ; nächster MCB
- add ax,mcblen
- mov es,ax
-
- mov mcbid,'Z' ; Freien Speicher vortäuschen
- mov mcbpsp,0 ; ID='Z', PSP=0
- mov ax,memsize ; Größe setzen
- sub ax,bx
- dec ax
- mov mcblen,ax
-
- mov ah,00h ; Video zurücksetzen
- mov al,crtmode
- cmp al,7
- je modeok1
- mov al,3
- modeok1: int 10h
-
- ret
-
- prepare endp
-
- ; ------------ Restore (Status wiederherstellen) -----------
- restore proc near
-
- call window ; Fenster aufbauen
-
- mov ch,11 ; Meldung ausgeben
- mov cl,14
- mov bl,col2
- mov dx,offset backmsg
- call outstr
-
- mov ax,4200h ; an den Anfang der Datei
- mov bx,fhandle
- xor cx,cx ; hinter Bildschirmspeicher
- mov dx,scrsize
- int 21h
-
- mov ax,cs ; eigenen MCB bestimmen
- dec ax
- mov es,ax
-
- next2: mov ax,es ; nächster MCB
- inc ax
- add ax,mcblen
- mov es,ax
-
- mov ah,3fh ; MCB laden
- call saveload
-
- cmp mcbid,'Z' ; letzter MCB?
- jne next2
-
- mov ax,4200h ; an den Anfang der Datei
- mov bx,fhandle
- xor cx,cx ; Position 0
- mov dx,cx
- int 21h
-
- mov ah,00h ; Video-Modus setzen
- mov al,crtmode
- int 10h
-
- mov blink,1 ; Blink-Flag normal gesetzt
-
- cmp font8x8,1 ; 43/50 Zeilen-Modus?
- jne fontok
- mov ax,1112h ; 8x8-Font setzen
- mov bl,00h
- int 10h
-
- fontok: push ds ; Bildschirm laden
- mov ax,scrseg
- mov ds,ax
- mov ah,3fh
- mov bx,cs:fhandle
- mov cx,scrsize
- xor dx,dx
- int 21h
- pop ds
-
- mov ah,05h ; Bildschirm-Seite setzen
- mov al,savepage
- int 10h
-
- mov ah,01h ; Cursor-Typ setzen
- mov cx,savecur
- int 10h
-
- mov ah,02h ; Cursor-Position setzen
- mov bh,savepage
- mov dx,savepos
- int 10h
-
- mov ah,3eh ; Datei schließen
- mov bx,fhandle
- int 21h
-
- mov ah,41h ; Datei löschen
- mov dx,offset fname
- int 21h
-
- push ds
- pop es
- ; Dateinamen entfernen
- mov di,offset fill
- xor al,al
- mov cx,13
- rep stosb
-
- cmp mouse,1 ; Maus vorhanden?
- jne noevent
-
- mov ax,0017h ; Maus-Status zurück
- push ds
- pop es
- mov dx,offset savemouse
- int 33h
-
- cmp saveevent,0 ; User-Event installiert?
- je noevent
- mov ax,000ch ; Handler zurück
- mov cx,saveevent
- les dx,savehandl
- int 33h
- push ds
- pop es
-
- noevent: xor ax,ax ; Interrupts zurück
- mov es,ax
- mov di,ax
- mov si,offset saveints
- mov cx,intsize/2
- cli
- rep movsw
- sti
- push ds
- pop es
-
- push ds ; DTA zurücksetzen
- mov dx,word ptr savedta
- mov ax,word ptr savedta+2
- mov ds,ax
- mov ah,1ah
- int 21h
- pop ds
-
- mov ah,50h ; PSP zurücksetzen
- mov bx,savepsp
- int 21h
-
- ret
-
- restore endp
-
- ; --------- SaveLoad (Speichern/Laden eines MCB's) ---------
- ; (AH = Funktionsnummer 3Fh oder 40h,
- ; ES = MCB-Segment)
- saveload proc near
-
- push es ; MCB-Segment sichern
-
- push ax ; Funktionsnummer sichern
- push ds
- mov bx,fhandle ; Vorspann speichern/laden
- mov cx,16
- xor dx,dx
- push es ; MCB-Segment nach DS
- pop ds
- int 21h
- pop ds
- pop ax
-
- cmp mcbpsp,0 ; freier Block?
- je free
-
- mov bx,mcblen ; Länge des MCB's
-
- push ax ; Funktionsnummer sichern
- mov ax,es ; hinter MCB-Vorspann
- inc ax
- mov es,ax
- pop ax
-
- loop1: mov cx,bx
- cmp cx,bufsize
- jbe bufok
- mov cx,bufsize
-
- bufok: push bx ; Schleifenwerte sichern
- push cx
-
- shl cx,1 ; in Bytes umrechnen
- shl cx,1 ; (= 4 mal nach links)
- shl cx,1
- shl cx,1
-
- push ax ; Funktionsnummer sichern
- push ds
- mov bx,fhandle ; Puffer speichern/laden
- xor dx,dx
- push es ; MCB-Segment nach DS
- pop ds
- int 21h
- pop ds
- pop ax
-
- pop cx ; Schleifenwerte zurück
- pop bx
-
- push ax ; Funktionsnummer sichern
- mov ax,es ; ES (über AX) erhöhen
- add ax,cx
- mov es,ax
- sub bx,cx ; BX verringern
- pop ax
-
- cmp bx,0 ; kein Rest mehr?
- jne loop1
-
- free: pop es ; Segment zurück
- ret
-
- saveload endp
-
- ; ---------------- Window (Fenster aufbauen) ---------------
- window proc near
-
- mov ah,0fh ; Video-Modus lesen
- int 10h
- and al,7fh ; Bit 7 ausblenden
- cmp al,2 ; 80-Zeichen-Modus?
- je modeok
- cmp al,3
- je modeok
- cmp al,7
- je modeok
- jmp setmode
-
- modeok: push ax ; Modus sichern
- push bx ; Seite sichern
- mov ax,1130h ; 8x8-Font gesetzt?
- mov bh,0
- mov dl,24 ; falls keine EGA/VGA
- int 10h
- pop bx ; Seite zurück
- pop ax ; Modus zurück
- cmp dl,24
- je linesok
-
- setmode: mov ah,00h ; Modus CO80 setzen
- mov al,3
- int 10h
- mov bh,0 ; Bildschirmseite in BH
-
- ; Farben, Segment setzen
- linesok: mov col0,col0color
- mov col1,col1color
- mov col2,col2color
- mov dx,colseg
- cmp al,7
- jne colorok
- mov col0,col0mono
- mov col1,col1mono
- mov col2,col2mono
- mov dx,monoseg
-
- colorok: mov es,dx
- mov ah,01h ; Cursor abschalten
- mov cx,2000h
- int 10h
-
- mov bl,col1 ; Rahmen schreiben
- mov ch,9
- mov cl,10
- mov dx,offset wnd1
- call outstr
-
- mov ch,10
- loopout: mov cl,10
- mov dx,offset wnd2
- call outstr
- cmp ch,12
- je exitout
- inc ch
- jmp loopout
-
- exitout: mov ch,13
- mov cl,10
- mov dx,offset wnd3
- call outstr
-
- mov bl,col0 ; Schatten erzeugen
- mov ch,10
- loopset: mov cl,70
- mov dl,2
- call setattr
- cmp ch,13
- je exitset
- inc ch
- jmp loopset
-
- exitset: mov ch,14
- mov cl,12
- mov dl,60
- call setattr
-
- ret
-
- window endp
-
- ; ----------------- OutStr (Text ausgeben) -----------------
- ; (CH = Y-Koordinate,
- ; CL = X-Koordinate,
- ; BH = Bildschirmseite,
- ; BL = Textattribut,
- ; DS:DX = Zeiger auf Text,
- ; ES = Bildschirmspeicher-Segment)
- outstr proc near
-
- mov si,dx ; Addresse des Textes
- call getaddr
- mov ah,bl ; Attribut in AH
-
- loopch: lodsb
- cmp al,0
- je exitch
-
- stosw ; Zeichen ausgeben
- inc cl
- jmp loopch
-
- exitch: ret
-
- outstr endp
-
- ; ------------- SetAttr (Textattribut setzen) --------------
- ; (CH = Y-Koordinate,
- ; CL = X-Koordinate,
- ; BH = Bildschirmseite,
- ; BL = Textattribut,
- ; DL = Anzahl der Zeichen,
- ; ES = Bildschirmspeicher-Segment)
- setattr proc near
-
- call getaddr
- mov al,bl ; Attribut in AL
-
- loopat: inc di ; Zeichen überspringen
- stosb ; Attribut setzen
- inc cl
- dec dl
- cmp dl,0
- ja loopat
-
- ret
-
- setattr endp
-
- ; --- GetAddr (Addresse im Bildschirmspeicher errechnen) ---
- ; (CH = Y-Koordinate,
- ; CL = X-Koordinate,
- ; BH = Bildschirmseite,
- ; => DI = Offset im Bildschirmspeicher)
- getaddr proc near
-
- push bx
- push dx
- mov al,bh ; Bildschirmseite
- mov bx,4096
- mul bx
- mov di,ax
- mov al,ch ; Zeile
- mov bl,160
- mul bl
- add di,ax
- mov al,cl ; Spalte
- xor ah,ah
- shl ax,1
- add di,ax
- pop dx
- pop bx
-
- ret
-
- getaddr endp
-
- ; -------------- NewI2F (Multiplex-Interrupt) --------------
- newi2f proc far
-
- cmp ah,mpxnum ; Funktion prüfen
- je myfunc
- jmp cs:oldi2f
-
- myfunc: mov al,0ffh ; Installation holen
- push cs
- pop es
- mov bx,offset data
-
- iret
-
- newi2f endp
-
- ; -------------------- Transienter Teil --------------------
- transient:
-
- titmsg db 'Resident V1.1',cr,lf
- db 'Copyright (C) 1990 by Torsten Priebe',cr,lf
- db eom
- noinst db 'RESIDENT: Programm ist bereits '
- db 'installiert',cr,lf,eom
- loadmsg db 'RESIDENT: Daten wurden aus Datei gelesen'
- db cr,lf,eom
- notfound db 'RESIDENT: Datei nicht gefunden',cr,lf,eom
- ext db '.SET'
-
- loadname db 64 dup (0)
- handle dw ?
-
- readbuf db 170*maxentry dup (0)
-
- ; ------------------ Main (Hauptprogramm) ------------------
- main proc near
-
- mov ah,mpxnum ; schon installiert?
- xor al,al
- int 2fh
- cmp al,0ffh
- jne install
-
- cmp parlen,2 ; Dateiname übergeben?
- jb noload1
-
- call loaddata ; Daten aus Datei laden
-
- mov ax,4c00h ; Programm beenden
- int 21h
-
- noload1: mov ah,09h ; Meldung ausgeben
- mov dx,offset noinst
- int 21h
-
- mov ax,4c00h ; Programm beenden
- int 21h
-
- install: mov ah,09h ; Titelmeldung ausgeben
- mov dx,offset titmsg
- int 21h
-
- int 12h ; Hauptspeichergröße
- mov cl,6
- shl ax,cl
- mov memsize,ax
-
- mov ax,0000h ; Maus vorhanden?
- int 33h
- mov mouse,0
- cmp ax,0ffffh
- jne nomouse
- mov mouse,1
-
- nomouse: mov ah,34h ; In-DOS-Flag holen
- int 21h
- mov word ptr indos,bx
- mov word ptr indos+2,es
-
- push ds ; Interrupttabelle sichern
- push ds
- pop es
- mov di,offset orgints
- xor ax,ax
- mov ds,ax
- mov si,ax
- mov cx,intsize/2
- cli
- rep movsw
- sti
- pop ds
-
- mov ax,3516h ; Interrupt-Vektoren holen
- int 21h
- mov word ptr oldi16,bx
- mov word ptr oldi16+2,es
- mov ax,3521h
- int 21h
- mov word ptr oldi21,bx
- mov word ptr oldi21+2,es
- mov ax,352fh
- int 21h
- mov word ptr oldi2f,bx
- mov word ptr oldi2f+2,es
-
- mov ax,2516h ; Interrupts setzen
- mov dx,offset newi16
- int 21h
- mov ax,2521h
- mov dx,offset newi21
- int 21h
- mov ax,252fh
- mov dx,offset newi2f
- int 21h
-
- cmp parlen,2 ; Dateiname übergeben?
- jb noload2
-
- mov ah,09h ; Zeilenvorschub
- mov dx,offset crlf
- int 21h
-
- push ds ; Daten aus Datei laden
- pop es
- mov bx,offset data
- call loaddata
-
- noload2: mov ax,3100h ; resident beenden
- mov dx,(transient-start+100h+15)/16
- int 21h
-
- main endp
-
- ; ---------------- LoadData (Daten einlesen) ---------------
- ; (ES:BX = Zeiger auf Datenbereich)
- loaddata proc near
-
- push es ; Adresse sichern
- push bx
-
- xor cx,cx ; Dateinamen holen
- mov cl,parlen
- dec cx
- mov si,offset param
- inc si ; Blank überspringen
- push ds
- pop es
- mov di,offset loadname
- rep movsb
- mov si,offset ext ; Erweiterung anfügen
- mov cx,4
- rep movsb
-
- mov ah,3dh ; Datei öffnen
- mov al,00h
- mov dx,offset loadname
- int 21h
- jnc ok
-
- mov ah,09h ; Fehlermeldung
- mov dx,offset notfound
- int 21h
-
- pop bx ; Stack bereinigen
- pop es
-
- jmp retload
-
- ok: mov handle,ax
-
- pop bx ; Adresse zurück
- pop es
-
- mov di,bx ; alte Daten löschen
- mov cx,162*maxentry/2
- xor ax,ax
- rep stosw
-
- push bx ; Puffer einlesen
- mov ah,3fh
- mov bx,handle
- mov cx,170*maxentry
- mov dx,offset readbuf
- int 21h
- pop bx
-
- ; Puffer durcharbeiten
- mov si,offset readbuf
- mov di,bx
- mov dl,1
-
- loopen:
- xor bx,bx ; Hotkey (Hex-Wert) holen
- mov cx,4
- loophk: xor ax,ax
- lodsb
-
- cmp al,'0' ; Ziffern 0-9?
- jb nonum
- cmp al,'9'
- ja nonum
- sub al,'0' ; num. Wert errechnen
- jmp addit
-
- nonum: cmp al,'a' ; Ziffern a-f (klein)?
- jb nosmall
- cmp al,'f'
- ja nosmall
- sub al,'a'-10 ; num. Wert errechnen
- jmp addit
-
- nosmall: ; Ziffern A-Z (groß)!
- sub al,'A'-10 ; num. Wert errechnen
-
- addit: push cx ; Zähler sichern
-
- dec cl ; CL vermindern,
- shl cl,1 ; mit 4 multiplizieren
- shl cl,1 ; (= 2 mal nach links)
-
- shl ax,cl ; Wert umrechnen und addieren
- add bx,ax
-
- pop cx ; Zähler zurück
-
- loop loophk
-
- inc si
- mov ax,bx
- stosw ; Tastencode wegschreiben
-
- mov cx,32 ; Namen holen
- loopna: lodsb
- cmp al,';' ; Name zuende?
- je nameok
- stosb
- dec cx
- jmp loopna
- nameok: add di,cx ; Dest.-Index auf Pfad
-
- mov cx,64 ; Pfad holen
- looppa: lodsb
- cmp al,';' ; Pfad zuende?
- je pathok
- stosb
- dec cx
- jmp looppa
- pathok: add di,cx ; Dest.-Index auf Programm
-
- mov cx,64 ; Programm holen
- looppr: lodsb
-
- cmp al,cr ; Zeilenende?
- jne nocrlf
- inc si
- mov al,[si]
- cmp al,0 ; Dateiende ohne EOF?
- jne progok
- mov al,eof ; EOF setzen
- jmp progok
-
- nocrlf: cmp al,eof ; Dateiende mit EOF?
- je progok
- cmp al,0 ; Dateiende ohne EOF?
- jne noeof
- mov al,eof ; EOF setzen
- jmp progok
-
- noeof: stosb
- dec cx
- jmp looppr
-
- progok: add di,cx ; DI auf nächsten Eintrag
-
- cmp al,eof ; Ende der Datei?
- je readok
-
- inc dl ; noch Einträge möglich?
- cmp dl,5
- ja readok
-
- jmp loopen
-
- readok: mov ah,3eh ; Datei schließen
- mov bx,handle
- int 21h
-
- mov ah,09h ; Meldung ausgeben
- mov dx,offset loadmsg
- int 21h
-
- retload: ret
-
- loaddata endp
-
- cseg ends
- end start