home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1990 / 12 / ldm / resident.asm < prev    next >
Encoding:
Assembly Source File  |  1990-10-24  |  33.5 KB  |  1,301 lines

  1. ; ----------------------------------------------------------
  2. ;                      Resident V1.1
  3. ;           Copyright (C) 1990 by Torsten Priebe
  4. ; ----------------------------------------------------------
  5. ; (zu RESIDENT.COM assemblieren mit Macro Assembler oder
  6. ;  Turbo Assembler: MASM/TASM, LINK/TLINK, EXE2BIN)
  7.  
  8. cseg      segment 'code'
  9.           assume cs:cseg, ds:cseg
  10.  
  11. ; ----------------------- Konstanten -----------------------
  12. cr        equ  0dh
  13. lf        equ  0ah
  14. eom       equ  '$'           ; EndOfMessage
  15. eof       equ  1ah
  16.  
  17. mpxnum    equ  0c0h          ; Nummer für Multiplex-Intr.
  18. blinkkey  equ  8300h         ; Scan-Code von <Alt-'>
  19.  
  20. maxentry  equ  5             ; max. Anzahl an Einträgen
  21.  
  22. col0color equ  07h           ; Farben für Farbmodus
  23. col1color equ  17h
  24. col2color equ  1fh
  25. col0mono  equ  07h           ; Farben für Monochrome
  26. col1mono  equ  0fh
  27. col2mono  equ  07h
  28.  
  29. bufsize   equ  2048          ; Paragraphen pro Schreibpuffer
  30.  
  31. intsize   equ  512           ; Größe der Iterrupt-Tabelle
  32. stackln   equ  256           ; Größe des Stacks
  33. mouseln   equ  768           ; Größe des Maus-Puffers
  34.  
  35. colseg    equ  0b800h        ; CGA/EGA Speicher-Segment
  36. monoseg   equ  0b000h        ; Hercules/MDA Speicher-Segment
  37. scrsize   equ  16384         ; Größe des Bildschirmspeichers
  38.  
  39. ; ------------------- Aufbau eines MCB's -------------------
  40. ; (ES = MCB-Segment)
  41.                              ; ID ('Z' bei letztem MCB)
  42. mcbid     equ  byte ptr es:[00h]
  43.                              ; PSP des zug. Programms
  44. mcbpsp    equ  word ptr es:[01h]
  45.                              ; MCB-Länge in Paragraphen
  46. mcblen    equ  word ptr es:[03h]
  47.  
  48. ; -------------------- Beep (Signalton) --------------------
  49. beep      macro
  50.  
  51.           push ax            ; Register sichern
  52.           push bx
  53.  
  54.           mov  ax,0e07h      ; Singnalton erzeugen
  55.           xor  bx,bx
  56.           int  10h
  57.  
  58.           pop  bx            ; Register zurück
  59.           pop  ax
  60.  
  61.           endm
  62.  
  63. ; ---------------------- Daten aus PSP ---------------------
  64. org       2ch                ; Segment des Environments
  65. myenv     dw   ?
  66.  
  67. org       80h                ; Kommandoparameter
  68. parlen    db   ?
  69. param     db   ?
  70.  
  71. ; -------------------- Programmeinsprung -------------------
  72. org       100h
  73. start:    jmp  main
  74.  
  75. ; ---------------------- Datenbereich ----------------------
  76. data      db   162*maxentry dup (0)
  77.  
  78. ; ------------------ Fenster-Informationen -----------------
  79. wnd1      db   '┌',24 dup ('─'),' Resident ',24 dup ('─')
  80.           db   '┐',0
  81. wnd2      db   '│',58 dup (' '),'│',0
  82. wnd3      db   '└',58 dup ('─'),'┘',0
  83.  
  84. popup1    db   '"',0
  85. popup2    db   '" wird geladen ...',0
  86. backmsg   db   'Status wird wiederhergestellt ...',0
  87.  
  88. col0      db   ?             ; Farbe für Schatten
  89. col1      db   ?             ; Farbe für Rahmen
  90. col2      db   ?             ; Farbe für Fenstertext
  91.  
  92. ; ---------------------- Warte-Meldung ---------------------
  93. crlf      db   cr,lf,eom     ; Zeilenvorschub
  94. waitmsg   db   'Bitte drücken Sie eine Taste, um im '
  95.           db   'unterbrochenen Programm fortzufahren ...'
  96.           db   eom
  97.  
  98. ; ------------------------ Variablen -----------------------
  99. progmsg   db   32 dup (0)    ; Programm-Titel
  100. progpath  db   64 dup (0)    ; Start-Verzeichnis
  101. prog      db   64 dup (0)    ; Programm-Datei
  102.  
  103. memsize   dw   ?             ; Hauptspeichergröße
  104. mouse     db   ?             ; Maus-Flag (1=Maus vorhanden)
  105.  
  106. indos     dd   ?             ; Addrese des "In-DOS"-Flags
  107. oldi16    dd   ?             ; alte Interruptvektoren
  108. oldi21    dd   ?
  109. oldi2f    dd   ?
  110.  
  111. possible  db   0             ; Flag für "Einsprung möglich"
  112. waiting   db   0             ; Warte-Flag (bei DOS-Funktion)
  113. blink     db   1             ; Intensity/Blink-Flag
  114.  
  115.                              ; Puffer für Interrupt-Tabelle
  116. orgints   db   intsize dup (?)
  117. saveints  db   intsize dup (?)
  118.  
  119. savess    dw   ?             ; zum Speichern des Stacks
  120. savesp    dw   ?
  121.  
  122. savepsp   dw   ?             ; PSP des unterbr. Programms
  123. savedta   dd   ?             ; DTA des unterbr. Programms
  124.  
  125. crtmode   db   ?             ; Video-Modus
  126. font8x8   db   ?             ; Flag für EGA/VGA 43/50 Zeilen
  127.  
  128. scrseg    dw   ?             ; Segment des Videospeichers
  129.  
  130. savepage  db   ?             ; Bildschirmseite
  131. savepos   dw   ?             ; Cursorposition
  132. savecur   dw   ?             ; Cursorform
  133.  
  134.                              ; Puffer für Maus-Status
  135. savemouse db   mouseln dup (0)
  136.  
  137. saveevent dw   ?             ; User-Event-Handler (Maus)
  138. savehandl dd   ?
  139.  
  140. savepath  db   0,':\'        ; Puffer zum Sichern des ...
  141. buffer    db   64 dup (0)    ; ... Verzeichnisses
  142.  
  143. fname     db   'C:\'         ; für die temporäre Datei
  144. fill      db   13 dup (0)    ; nimmt den Dateinamen auf
  145.  
  146. fhandle   dw   ?             ; Datei-Handle
  147.  
  148. cmdline   db   0,cr          ; keine Parameter
  149.  
  150. fcb1      db   0             ; 2 leere FCB's
  151.           db   11 dup (0)
  152.           db   25 dup (0)
  153.  
  154. fcb2      db   0
  155.           db   11 dup (0)
  156.           db   25 dup (0)
  157.  
  158. block     equ  this byte     ; Parameterblock
  159. envseg    dw   ?
  160. fcb1p     dd   ?
  161. fcb2p     dd   ?
  162. cmdlnp    dd   ?
  163.  
  164.                              ; neuer Stack
  165. mystack   db   stackln dup (0)
  166.  
  167. ; --------------- NewI16 (Tastatur-Interrupt) --------------
  168. newi16    proc far
  169.  
  170.           cmp  ah,00h        ; Funktion 00h oder ...
  171.           je   getkey
  172.           cmp  ah,10h        ; ... 10h (MF2-Tastatur)
  173.           je   getkey
  174.  
  175. nochk1:   jmp  cs:oldi16     ; in alten Handler springen
  176.  
  177. getkey:   pushf              ; Taste holen
  178.           call cs:oldi16
  179.  
  180.           push ax            ; Register sichern
  181.           push bx
  182.           push cx
  183.           push es
  184.  
  185.           cmp  ax,blinkkey   ; Blink/Intensity-Umschalter
  186.           jne  checkhk
  187.           mov  al,0ffh       ; Hotkey-Code FFh
  188.           jmp  hkfound
  189.  
  190. checkhk:  mov  cl,1          ; Afangswert der Schleife
  191.           mov  bx,offset data
  192.  
  193.                              ; Eintrag nicht belegt?
  194. nextentr: cmp  word ptr cs:[bx],0
  195.           je   nothk
  196.                              ; Hotkey des Eintrags gedrückt?
  197.           cmp  ax,word ptr cs:[bx]
  198.           jne  nothk
  199.           mov  al,cl
  200.           jmp  hkfound
  201.  
  202. nothk:    inc  cl            ; nächster Eintrag
  203.           add  bx,162
  204.           cmp  cl,maxentry
  205.           jbe  nextentr
  206.  
  207.           jmp  reti16
  208.  
  209. hkfound:  les  bx,cs:indos   ; gerade in einer DOS-Funktion?
  210.           cmp  byte ptr es:[bx],0
  211.           jne  notnow
  212.  
  213.           call runprog       ; Programm aufrufen
  214.  
  215. reti16:   pop  es            ; Register zurück
  216.           pop  cx
  217.           pop  bx
  218.           pop  ax
  219.  
  220.           iret
  221.  
  222. notnow:   cmp  cs:possible,1 ; Warten möglich?
  223.           je   setwait
  224.  
  225.           beep
  226.  
  227.           jmp  reti16
  228.  
  229. setwait:  mov  cs:waiting,al ; Warte-Flag setzen
  230.           jmp  reti16
  231.  
  232. newi16    endp
  233.  
  234. ; ----------------- NewI21 (DOS-Interrupt) -----------------
  235. newi21    proc far
  236.  
  237.           cmp  ah,01h        ; Warten bei Funktion 01h, ...
  238.           je   check
  239.           cmp  ah,06h        ; ... 06h, ...
  240.           jne  chknext1
  241.           cmp  dl,0ffh
  242.           je   check
  243. chknext1: cmp  ah,07h        ; ... 07h, ...
  244.           je   check
  245.           cmp  ah,08h        ; ... 08h, ...
  246.           je   check
  247.  
  248.           cmp  ax,0c01h      ; ... 0Ch (Unterf. 01h), ...
  249.           je   check
  250.           cmp  ax,0c06h      ; ... 0Ch (Unterf. 06h), ...
  251.           jne  chknext2
  252.           cmp  dl,0ffh
  253.           je   check
  254. chknext2: cmp  ax,0c07h      ; ... 0Ch (Unterf. 07h), ...
  255.           je   check
  256.           cmp  ax,0c08h      ; ... 0Ch (Unterf. 08h) möglich
  257.           je   check
  258.  
  259. nochk2:   jmp  cs:oldi21     ; in alten Handler springen
  260.  
  261. check:    mov  cs:possible,1
  262.  
  263.           pushf              ; Interrupt ausführen
  264.           call cs:oldi21
  265.           pushf              ; Flags sichern
  266.  
  267.           mov  cs:possible,0 ; Flag zurück
  268.  
  269.           cmp  cs:waiting,0  ; wurde der Hotkey betätigt?
  270.           je   reti21
  271.  
  272.           push ax            ; Programmnummer in AL
  273.           mov  al,cs:waiting
  274.           mov  cs:waiting,0  ; Warte-Flag zurück
  275.  
  276.           call runprog       ; Programm aufrufen
  277.  
  278.           pop  ax
  279.  
  280. reti21:   popf               ; Flags zurück
  281.           ret  2             ; beenden, Flags beibehalten
  282.  
  283. newi21    endp
  284.  
  285. ; ---------------- RunProg (Programmaufruf) ----------------
  286. ; (AL = Programmnummer)
  287. runprog   proc near
  288.  
  289.           push ax            ; Register sichern
  290.           push bx
  291.           push cx
  292.           push dx
  293.           push bp
  294.           push si
  295.           push di
  296.           push ds
  297.           push es
  298.  
  299.           push cs            ; Datensegment setzen
  300.           pop  ds
  301.  
  302.           push ax            ; Programmnummer sichern
  303.  
  304.           mov  ah,0fh        ; Video-Modus testen
  305.           int  10h
  306.           and  al,7fh
  307.           cmp  al,3          ; CGA/EGA-Textmodus?
  308.           jbe  textmode
  309.           cmp  al,7          ; Mono-Textmodus?
  310.           je   textmode
  311.  
  312.           pop  ax            ; Stack bereinigen
  313.           beep
  314.           jmp  exit
  315.  
  316. textmode: pop  ax            ; Programmnummer zurück
  317.           cmp  al,0ffh
  318.           jne  proghk
  319.           mov  al,blink      ; Intensity/Blink-Flag setzen
  320.           xor  al,1
  321.           mov  blink,al
  322.           call setblink      ; Intensity/Blinken setzen
  323.           jmp  exit
  324.  
  325. proghk:   xor  ah,ah         ; Programm-Daten kopieren
  326.           dec  ax
  327.           mov  bx,162
  328.           mul  bx
  329.           mov  si,offset data+2
  330.           add  si,ax
  331.           push ds
  332.           pop  es
  333.           mov  di,offset progmsg
  334.           mov  cx,80
  335.           rep movsw
  336.  
  337.           mov  savess,ss     ; Stack sichern
  338.           mov  savesp,sp
  339.  
  340.           mov  ax,ds         ; neuen Stack setzen
  341.           cli
  342.           mov  ss,ax
  343.           mov  sp,offset mystack+stackln
  344.           sti
  345.  
  346.           call prepare       ; Aufruf vorbereiten
  347.  
  348.           mov  ah,19h        ; aktives Laufwerk holen
  349.           int  21h
  350.           add  al,65
  351.           mov  byte ptr savepath,al
  352.           mov  ah,47h        ; Verzeichnis holen
  353.           mov  dl,0
  354.           mov  si,offset buffer
  355.           int  21h
  356.  
  357.           mov  ah,0eh        ; Laufwerk wechseln
  358.           mov  dl,byte ptr progpath
  359.           sub  dl,65
  360.           int  21h           ; Verzeichnis wechseln
  361.           jc   error
  362.           mov  ah,3bh
  363.           mov  dx,offset progpath
  364.           int  21h
  365.           jc   error
  366.  
  367.           mov  ax,myenv      ; Parameterblock setzen
  368.           mov  envseg,ax
  369.           mov  word ptr fcb1p,offset fcb1
  370.           mov  word ptr fcb1p+2,ds
  371.           mov  word ptr fcb2p,offset fcb2
  372.           mov  word ptr fcb2p+2,ds
  373.           mov  word ptr cmdlnp,offset cmdline
  374.           mov  word ptr cmdlnp+2,ds
  375.  
  376.           mov  ax,4b00h      ; Programm aufrufen
  377.           mov  dx,offset prog
  378.           push ds
  379.           pop  es
  380.           mov  bx,offset block
  381.           int  21h
  382.  
  383.           push cs            ; Datensegment zurücksetzen
  384.           pop  ds
  385.  
  386.           mov  ax,ds         ; Stack wiederherstellen
  387.           cli
  388.           mov  ss,ax
  389.           mov  sp,offset mystack+stackln
  390.           sti
  391.  
  392.           jnc  noerror
  393.  
  394. error:    beep
  395.  
  396. noerror:  mov  ah,09h        ; Zeilenvorschub
  397.           mov  dx,offset crlf
  398.           int  21h
  399.  
  400.           mov  ah,0fh        ; an unteren Bildschirmrand
  401.           int  10h
  402.           push bx            ; Seite sichern
  403.           mov  ax,1130h      ; 8x8-Font gesetzt?
  404.           mov  bh,0
  405.           mov  dl,24         ; falls keine EGA/VGA
  406.           int  10h
  407.           pop  bx
  408.           mov  ah,02h
  409.           mov  dh,dl
  410.           mov  dl,0
  411.           int  10h
  412.  
  413.           mov  ah,09h        ; Meldung ausgeben und warten
  414.           mov  dx,offset waitmsg
  415.           int  21h
  416.           mov  ah,00h
  417.           int  16h
  418.  
  419.           mov  ah,0eh        ; Laufwerk zurücksetzen
  420.           mov  dl,byte ptr savepath
  421.           sub  dl,65
  422.           int  21h
  423.           mov  ah,3bh        ; Verzeichnis zurücksetzen
  424.           mov  dx,offset savepath
  425.           int  21h
  426.  
  427.           call restore       ; alten Status wiederherstellen
  428.  
  429.           cli                ; Orginal-Stack setzen
  430.           mov  ss,savess
  431.           mov  sp,savesp
  432.           sti
  433.  
  434. exit:     pop  es            ; Register zurück
  435.           pop  ds
  436.           pop  di
  437.           pop  si
  438.           pop  bp
  439.           pop  dx
  440.           pop  cx
  441.           pop  bx
  442.           pop  ax
  443.  
  444.           ret
  445.  
  446. runprog   endp
  447.  
  448. ; --------- SetBlink (Setzen von Blinken/Intensity) --------
  449. ; (AL = 1 für Blinken, 0 für Intensity)
  450. setblink  proc near
  451.  
  452.           push ax            ; Flag sichern
  453.           mov  ah,0fh
  454.           int  10h
  455.           and  al,7fh
  456.           cmp  al,7
  457.           jne  color         ; CGA, EGA/VGA
  458.           mov  dx,3b8h       ; Hercules/MDA
  459.           jmp  useport
  460.  
  461. color:    mov  ah,12h
  462.           mov  bl,10h
  463.           int  10h
  464.           cmp  bl,10h
  465.           jne  useint        ; EGA/VGA
  466.           mov  dx,3d8h       ; CGA
  467.           jmp  useport
  468.  
  469. useint:   pop  bx            ; Flag in BL
  470.           mov  ax,1003h      ; via Intr. 10h setzen
  471.           int  10h
  472.           jmp  retsetbl
  473.  
  474. useport:  pop  ax            ; Flag in AL
  475.           mov  cl,5          ; Bit 5 für Blinken/Intensity
  476.           shl  al,cl
  477.           or   al,09h        ; Bits 0 und 3 immer setzen
  478.           out  dx,al         ; via Port setzen
  479.  
  480. retsetbl: ret
  481.  
  482. setblink  endp
  483.  
  484. ; -------------- Prepare (Aufruf vorbereiten) --------------
  485. prepare   proc near
  486.  
  487.           mov  ah,62h        ; PSP sichern
  488.           int  21h
  489.           mov  savepsp,bx
  490.  
  491.           mov  ah,50h        ; PSP setzen
  492.           mov  bx,cs
  493.           int  21h
  494.  
  495.           mov  ah,2fh        ; DTA sichern
  496.           int  21h
  497.           mov  word ptr savedta,bx
  498.           mov  word ptr savedta+2,es
  499.  
  500.           push ds            ; Interrupts sichern
  501.           push ds
  502.           pop  es
  503.           mov  di,offset saveints
  504.           xor  ax,ax
  505.           mov  ds,ax
  506.           mov  si,ax
  507.           mov  cx,intsize/2
  508.           cli
  509.           rep movsw
  510.           sti
  511.           pop  ds
  512.  
  513.           xor  ax,ax         ; Original-Interrupts zurück
  514.           mov  es,ax
  515.           mov  di,ax
  516.           mov  si,offset orgints
  517.           mov  cx,intsize/2
  518.           cli
  519.           rep movsw
  520.           sti
  521.  
  522.           cmp  mouse,1       ; Maus vorhanden?
  523.           jne  nomouse1
  524.  
  525.           mov  ax,0016h      ; Maus-Status sichern
  526.           push ds
  527.           pop  es
  528.           mov  dx,offset savemouse
  529.           int  33h
  530.  
  531.           mov  ax,0014h      ; Maus-Event-Handler holen
  532.           xor  cx,cx
  533.           int  33h
  534.           mov  saveevent,cx
  535.           mov  word ptr savehandl,dx
  536.           mov  word ptr savehandl+2,es
  537.  
  538.           mov  ax,0000h      ; Maus zurücksetzen
  539.           int  33h
  540.  
  541. nomouse1: mov  ah,0fh        ; Video-Modus holen
  542.           int  10h
  543.           and  al,7fh        ; Bit 7 ausblenden
  544.           mov  crtmode,al
  545.           mov  savepage,bh
  546.           mov  scrseg,colseg
  547.           cmp  al,7          ; Mono- oder Hercules-Karte?
  548.           jne  segok
  549.           mov  scrseg,monoseg
  550.  
  551. segok:    mov  font8x8,0
  552.           mov  ax,1130h      ; Font-Informationen
  553.           mov  bh,00h
  554.           mov  dl,24         ; falls keine EGA/VGA
  555.           int  10h
  556.           cmp  dl,24         ; 25 Zeilen?
  557.           je   normfont
  558.           mov  font8x8,1
  559.  
  560. normfont: mov  ah,03h        ; Cursor-Position holen
  561.           mov  bh,savepage
  562.           int  10h
  563.           mov  savepos,dx
  564.           mov  savecur,cx
  565.  
  566.           mov  ah,5ah        ; Temporäre Datei erzeugen
  567.           mov  cx,0
  568.           mov  dx,offset fname
  569.           int  21h
  570.           mov  fhandle,ax
  571.  
  572.           push ds            ; Bildschirm speichern
  573.           mov  ax,scrseg
  574.           mov  ds,ax
  575.           mov  ah,40h
  576.           mov  bx,cs:fhandle
  577.           mov  cx,scrsize
  578.           xor  dx,dx
  579.           int  21h
  580.           pop  ds
  581.  
  582.           call window        ; Fenster aufbauen
  583.  
  584.           mov  ch,11         ; Meldung ausgeben
  585.           mov  cl,14
  586.           mov  bl,col2
  587.           mov  dx,offset popup1
  588.           call outstr
  589.           mov  dx,offset progmsg
  590.           call outstr
  591.           mov  dx,offset popup2
  592.           call outstr
  593.  
  594.           mov  ax,cs         ; eigenen MCB bestimmen
  595.           dec  ax
  596.           mov  es,ax
  597.  
  598. next1:    mov  ax,es         ; nächster MCB
  599.           inc  ax
  600.           add  ax,mcblen
  601.           mov  es,ax
  602.  
  603.           mov  ah,40h        ; MCB speichern
  604.           call saveload
  605.  
  606.           cmp  mcbid,'Z'     ; letzter MCB?
  607.           jne  next1
  608.  
  609.           mov  ax,cs         ; eigenen MCB bestimmen
  610.           dec  ax
  611.           mov  es,ax
  612.  
  613.           mov  bx,cs         ; belegter Speicher in BX
  614.           add  bx,mcblen
  615.  
  616.           inc  ax            ; nächster MCB
  617.           add  ax,mcblen
  618.           mov  es,ax
  619.  
  620.           mov  mcbid,'Z'     ; Freien Speicher vortäuschen
  621.           mov  mcbpsp,0      ; ID='Z', PSP=0
  622.           mov  ax,memsize    ; Größe setzen
  623.           sub  ax,bx
  624.           dec  ax
  625.           mov  mcblen,ax
  626.  
  627.           mov  ah,00h        ; Video zurücksetzen
  628.           mov  al,crtmode
  629.           cmp  al,7
  630.           je   modeok1
  631.           mov  al,3
  632. modeok1:  int  10h
  633.  
  634.           ret
  635.  
  636. prepare   endp
  637.  
  638. ; ------------ Restore (Status wiederherstellen) -----------
  639. restore   proc near
  640.  
  641.           call window        ; Fenster aufbauen
  642.  
  643.           mov  ch,11         ; Meldung ausgeben
  644.           mov  cl,14
  645.           mov  bl,col2
  646.           mov  dx,offset backmsg
  647.           call outstr
  648.  
  649.           mov  ax,4200h      ; an den Anfang der Datei
  650.           mov  bx,fhandle
  651.           xor  cx,cx         ; hinter Bildschirmspeicher
  652.           mov  dx,scrsize
  653.           int  21h
  654.  
  655.           mov  ax,cs         ; eigenen MCB bestimmen
  656.           dec  ax
  657.           mov  es,ax
  658.  
  659. next2:    mov  ax,es         ; nächster MCB
  660.           inc  ax
  661.           add  ax,mcblen
  662.           mov  es,ax
  663.  
  664.           mov  ah,3fh        ; MCB laden
  665.           call saveload
  666.  
  667.           cmp  mcbid,'Z'     ; letzter MCB?
  668.           jne  next2
  669.  
  670.           mov  ax,4200h      ; an den Anfang der Datei
  671.           mov  bx,fhandle
  672.           xor  cx,cx         ; Position 0
  673.           mov  dx,cx
  674.           int  21h
  675.  
  676.           mov  ah,00h        ; Video-Modus setzen
  677.           mov  al,crtmode
  678.           int  10h
  679.  
  680.           mov  blink,1       ; Blink-Flag normal gesetzt
  681.  
  682.           cmp  font8x8,1     ; 43/50 Zeilen-Modus?
  683.           jne  fontok
  684.           mov  ax,1112h      ; 8x8-Font setzen
  685.           mov  bl,00h
  686.           int  10h
  687.  
  688. fontok:   push ds            ; Bildschirm laden
  689.           mov  ax,scrseg
  690.           mov  ds,ax
  691.           mov  ah,3fh
  692.           mov  bx,cs:fhandle
  693.           mov  cx,scrsize
  694.           xor  dx,dx
  695.           int  21h
  696.           pop  ds
  697.  
  698.           mov  ah,05h        ; Bildschirm-Seite setzen
  699.           mov  al,savepage
  700.           int  10h
  701.  
  702.           mov  ah,01h        ; Cursor-Typ setzen
  703.           mov  cx,savecur
  704.           int  10h
  705.  
  706.           mov  ah,02h        ; Cursor-Position setzen
  707.           mov  bh,savepage
  708.           mov  dx,savepos
  709.           int  10h
  710.  
  711.           mov  ah,3eh        ; Datei schließen
  712.           mov  bx,fhandle
  713.           int  21h
  714.  
  715.           mov  ah,41h        ; Datei löschen
  716.           mov  dx,offset fname
  717.           int  21h
  718.  
  719.           push ds
  720.           pop  es
  721.                              ; Dateinamen entfernen
  722.           mov  di,offset fill
  723.           xor  al,al
  724.           mov  cx,13
  725.           rep stosb
  726.  
  727.           cmp  mouse,1       ; Maus vorhanden?
  728.           jne  noevent
  729.  
  730.           mov  ax,0017h      ; Maus-Status zurück
  731.           push ds
  732.           pop  es
  733.           mov  dx,offset savemouse
  734.           int  33h
  735.  
  736.           cmp  saveevent,0   ; User-Event installiert?
  737.           je   noevent
  738.           mov  ax,000ch      ; Handler zurück
  739.           mov  cx,saveevent
  740.           les  dx,savehandl
  741.           int  33h
  742.           push ds
  743.           pop  es
  744.  
  745. noevent:  xor  ax,ax         ; Interrupts zurück
  746.           mov  es,ax
  747.           mov  di,ax
  748.           mov  si,offset saveints
  749.           mov  cx,intsize/2
  750.           cli
  751.           rep  movsw
  752.           sti
  753.           push ds
  754.           pop  es
  755.  
  756.           push ds            ; DTA zurücksetzen
  757.           mov  dx,word ptr savedta
  758.           mov  ax,word ptr savedta+2
  759.           mov  ds,ax
  760.           mov  ah,1ah
  761.           int  21h
  762.           pop  ds
  763.  
  764.           mov  ah,50h        ; PSP zurücksetzen
  765.           mov  bx,savepsp
  766.           int  21h
  767.  
  768.           ret
  769.  
  770. restore   endp
  771.  
  772. ; --------- SaveLoad (Speichern/Laden eines MCB's) ---------
  773. ; (AH = Funktionsnummer 3Fh oder 40h,
  774. ;  ES = MCB-Segment)
  775. saveload  proc near
  776.  
  777.           push es            ; MCB-Segment sichern
  778.  
  779.           push ax            ; Funktionsnummer sichern
  780.           push ds
  781.           mov  bx,fhandle    ; Vorspann speichern/laden
  782.           mov  cx,16
  783.           xor  dx,dx
  784.           push es            ; MCB-Segment nach DS
  785.           pop  ds
  786.           int  21h
  787.           pop  ds
  788.           pop  ax
  789.  
  790.           cmp  mcbpsp,0      ; freier Block?
  791.           je   free
  792.  
  793.           mov  bx,mcblen     ; Länge des MCB's
  794.  
  795.           push ax            ; Funktionsnummer sichern
  796.           mov  ax,es         ; hinter MCB-Vorspann
  797.           inc  ax
  798.           mov  es,ax
  799.           pop  ax
  800.  
  801. loop1:    mov  cx,bx
  802.           cmp  cx,bufsize
  803.           jbe  bufok
  804.           mov  cx,bufsize
  805.  
  806. bufok:    push bx            ; Schleifenwerte sichern
  807.           push cx
  808.  
  809.           shl  cx,1          ; in Bytes umrechnen
  810.           shl  cx,1          ; (= 4 mal nach links)
  811.           shl  cx,1
  812.           shl  cx,1
  813.  
  814.           push ax            ; Funktionsnummer sichern
  815.           push ds
  816.           mov  bx,fhandle    ; Puffer speichern/laden
  817.           xor  dx,dx
  818.           push es            ; MCB-Segment nach DS
  819.           pop  ds
  820.           int  21h
  821.           pop  ds
  822.           pop  ax
  823.  
  824.           pop  cx            ; Schleifenwerte zurück
  825.           pop  bx
  826.  
  827.           push ax            ; Funktionsnummer sichern
  828.           mov  ax,es         ; ES (über AX) erhöhen
  829.           add  ax,cx
  830.           mov  es,ax
  831.           sub  bx,cx         ; BX verringern
  832.           pop  ax
  833.  
  834.           cmp  bx,0          ; kein Rest mehr?
  835.           jne  loop1
  836.  
  837. free:     pop  es            ; Segment zurück
  838.           ret
  839.  
  840. saveload  endp
  841.  
  842. ; ---------------- Window (Fenster aufbauen) ---------------
  843. window    proc near
  844.  
  845.           mov  ah,0fh        ; Video-Modus lesen
  846.           int  10h
  847.           and  al,7fh        ; Bit 7 ausblenden
  848.           cmp  al,2          ; 80-Zeichen-Modus?
  849.           je   modeok
  850.           cmp  al,3
  851.           je   modeok
  852.           cmp  al,7
  853.           je   modeok
  854.           jmp  setmode
  855.  
  856. modeok:   push ax            ; Modus sichern
  857.           push bx            ; Seite sichern
  858.           mov  ax,1130h      ; 8x8-Font gesetzt?
  859.           mov  bh,0
  860.           mov  dl,24         ; falls keine EGA/VGA
  861.           int  10h
  862.           pop  bx            ; Seite zurück
  863.           pop  ax            ; Modus zurück
  864.           cmp  dl,24
  865.           je   linesok
  866.  
  867. setmode:  mov  ah,00h        ; Modus CO80 setzen
  868.           mov  al,3
  869.           int  10h
  870.           mov  bh,0          ; Bildschirmseite in BH
  871.  
  872.                              ; Farben, Segment setzen
  873. linesok:  mov  col0,col0color
  874.           mov  col1,col1color
  875.           mov  col2,col2color
  876.           mov  dx,colseg
  877.           cmp  al,7
  878.           jne  colorok
  879.           mov  col0,col0mono
  880.           mov  col1,col1mono
  881.           mov  col2,col2mono
  882.           mov  dx,monoseg
  883.  
  884. colorok:  mov  es,dx
  885.           mov  ah,01h        ; Cursor abschalten
  886.           mov  cx,2000h
  887.           int  10h
  888.  
  889.           mov  bl,col1       ; Rahmen schreiben
  890.           mov  ch,9
  891.           mov  cl,10
  892.           mov  dx,offset wnd1
  893.           call outstr
  894.  
  895.           mov  ch,10
  896. loopout:  mov  cl,10
  897.           mov  dx,offset wnd2
  898.           call outstr
  899.           cmp  ch,12
  900.           je   exitout
  901.           inc  ch
  902.           jmp  loopout
  903.  
  904. exitout:  mov  ch,13
  905.           mov  cl,10
  906.           mov  dx,offset wnd3
  907.           call outstr
  908.  
  909.           mov  bl,col0       ; Schatten erzeugen
  910.           mov  ch,10
  911. loopset:  mov  cl,70
  912.           mov  dl,2
  913.           call setattr
  914.           cmp  ch,13
  915.           je   exitset
  916.           inc  ch
  917.           jmp  loopset
  918.  
  919. exitset:  mov  ch,14
  920.           mov  cl,12
  921.           mov  dl,60
  922.           call setattr
  923.  
  924.           ret
  925.  
  926. window    endp
  927.  
  928. ; ----------------- OutStr (Text ausgeben) -----------------
  929. ; (CH = Y-Koordinate,
  930. ;  CL = X-Koordinate,
  931. ;  BH = Bildschirmseite,
  932. ;  BL = Textattribut,
  933. ;  DS:DX = Zeiger auf Text,
  934. ;  ES = Bildschirmspeicher-Segment)
  935. outstr    proc near
  936.  
  937.           mov  si,dx         ; Addresse des Textes
  938.           call getaddr
  939.           mov  ah,bl         ; Attribut in AH
  940.  
  941. loopch:   lodsb
  942.           cmp  al,0
  943.           je   exitch
  944.  
  945.           stosw              ; Zeichen ausgeben
  946.           inc  cl
  947.           jmp  loopch
  948.  
  949. exitch:   ret
  950.  
  951. outstr    endp
  952.  
  953. ; ------------- SetAttr (Textattribut setzen) --------------
  954. ; (CH = Y-Koordinate,
  955. ;  CL = X-Koordinate,
  956. ;  BH = Bildschirmseite,
  957. ;  BL = Textattribut,
  958. ;  DL = Anzahl der Zeichen,
  959. ;  ES = Bildschirmspeicher-Segment)
  960. setattr   proc near
  961.  
  962.           call getaddr
  963.           mov  al,bl         ; Attribut in AL
  964.  
  965. loopat:   inc  di            ; Zeichen überspringen
  966.           stosb              ; Attribut setzen
  967.           inc  cl
  968.           dec  dl
  969.           cmp  dl,0
  970.           ja   loopat
  971.  
  972.           ret
  973.  
  974. setattr   endp
  975.  
  976. ; --- GetAddr (Addresse im Bildschirmspeicher errechnen) ---
  977. ; (CH = Y-Koordinate,
  978. ;  CL = X-Koordinate,
  979. ;  BH = Bildschirmseite,
  980. ;  => DI = Offset im Bildschirmspeicher)
  981. getaddr   proc near
  982.  
  983.           push bx
  984.           push dx
  985.           mov  al,bh         ; Bildschirmseite
  986.           mov  bx,4096
  987.           mul  bx
  988.           mov  di,ax
  989.           mov  al,ch         ; Zeile
  990.           mov  bl,160
  991.           mul  bl
  992.           add  di,ax
  993.           mov  al,cl         ; Spalte
  994.           xor  ah,ah
  995.           shl  ax,1
  996.           add  di,ax
  997.           pop  dx
  998.           pop  bx
  999.  
  1000.           ret
  1001.  
  1002. getaddr   endp
  1003.  
  1004. ; -------------- NewI2F (Multiplex-Interrupt) --------------
  1005. newi2f    proc far
  1006.  
  1007.           cmp  ah,mpxnum     ; Funktion prüfen
  1008.           je   myfunc
  1009.           jmp  cs:oldi2f
  1010.  
  1011. myfunc:   mov  al,0ffh       ; Installation holen
  1012.           push cs
  1013.           pop  es
  1014.           mov  bx,offset data
  1015.  
  1016.           iret
  1017.  
  1018. newi2f    endp
  1019.  
  1020. ; -------------------- Transienter Teil --------------------
  1021. transient:
  1022.  
  1023. titmsg    db   'Resident V1.1',cr,lf
  1024.           db   'Copyright (C) 1990 by Torsten Priebe',cr,lf
  1025.           db   eom
  1026. noinst    db   'RESIDENT: Programm ist bereits '
  1027.           db   'installiert',cr,lf,eom
  1028. loadmsg   db   'RESIDENT: Daten wurden aus Datei gelesen'
  1029.           db   cr,lf,eom
  1030. notfound  db   'RESIDENT: Datei nicht gefunden',cr,lf,eom
  1031. ext       db   '.SET'
  1032.  
  1033. loadname  db   64 dup (0)
  1034. handle    dw   ?
  1035.  
  1036. readbuf   db   170*maxentry dup (0)
  1037.  
  1038. ; ------------------ Main (Hauptprogramm) ------------------
  1039. main      proc near
  1040.  
  1041.           mov  ah,mpxnum     ; schon installiert?
  1042.           xor  al,al
  1043.           int  2fh
  1044.           cmp  al,0ffh
  1045.           jne  install
  1046.  
  1047.           cmp  parlen,2      ; Dateiname übergeben?
  1048.           jb   noload1
  1049.  
  1050.           call loaddata      ; Daten aus Datei laden
  1051.  
  1052.           mov  ax,4c00h      ; Programm beenden
  1053.           int  21h
  1054.  
  1055. noload1:  mov  ah,09h        ; Meldung ausgeben
  1056.           mov  dx,offset noinst
  1057.           int  21h
  1058.  
  1059.           mov  ax,4c00h      ; Programm beenden
  1060.           int  21h
  1061.  
  1062. install:  mov  ah,09h        ; Titelmeldung ausgeben
  1063.           mov  dx,offset titmsg
  1064.           int  21h
  1065.  
  1066.           int  12h           ; Hauptspeichergröße
  1067.           mov  cl,6
  1068.           shl  ax,cl
  1069.           mov  memsize,ax
  1070.  
  1071.           mov  ax,0000h      ; Maus vorhanden?
  1072.           int  33h
  1073.           mov  mouse,0
  1074.           cmp  ax,0ffffh
  1075.           jne  nomouse
  1076.           mov  mouse,1
  1077.  
  1078. nomouse:  mov  ah,34h        ; In-DOS-Flag holen
  1079.           int  21h
  1080.           mov  word ptr indos,bx
  1081.           mov  word ptr indos+2,es
  1082.  
  1083.           push ds            ; Interrupttabelle sichern
  1084.           push ds
  1085.           pop  es
  1086.           mov  di,offset orgints
  1087.           xor  ax,ax
  1088.           mov  ds,ax
  1089.           mov  si,ax
  1090.           mov  cx,intsize/2
  1091.           cli
  1092.           rep movsw
  1093.           sti
  1094.           pop  ds
  1095.  
  1096.           mov  ax,3516h      ; Interrupt-Vektoren holen
  1097.           int  21h
  1098.           mov  word ptr oldi16,bx
  1099.           mov  word ptr oldi16+2,es
  1100.           mov  ax,3521h
  1101.           int  21h
  1102.           mov  word ptr oldi21,bx
  1103.           mov  word ptr oldi21+2,es
  1104.           mov  ax,352fh
  1105.           int  21h
  1106.           mov  word ptr oldi2f,bx
  1107.           mov  word ptr oldi2f+2,es
  1108.  
  1109.           mov  ax,2516h      ; Interrupts setzen
  1110.           mov  dx,offset newi16
  1111.           int  21h
  1112.           mov  ax,2521h
  1113.           mov  dx,offset newi21
  1114.           int  21h
  1115.           mov  ax,252fh
  1116.           mov  dx,offset newi2f
  1117.           int  21h
  1118.  
  1119.           cmp  parlen,2      ; Dateiname übergeben?
  1120.           jb   noload2
  1121.  
  1122.           mov  ah,09h        ; Zeilenvorschub
  1123.           mov  dx,offset crlf
  1124.           int  21h
  1125.  
  1126.           push ds            ; Daten aus Datei laden
  1127.           pop  es
  1128.           mov  bx,offset data
  1129.           call loaddata
  1130.  
  1131. noload2:  mov  ax,3100h      ; resident beenden
  1132.           mov  dx,(transient-start+100h+15)/16
  1133.           int  21h
  1134.  
  1135. main      endp
  1136.  
  1137. ; ---------------- LoadData (Daten einlesen) ---------------
  1138. ; (ES:BX = Zeiger auf Datenbereich)
  1139. loaddata  proc near
  1140.  
  1141.           push es            ; Adresse sichern
  1142.           push bx
  1143.  
  1144.           xor  cx,cx         ; Dateinamen holen
  1145.           mov  cl,parlen
  1146.           dec  cx
  1147.           mov  si,offset param
  1148.           inc  si            ; Blank überspringen
  1149.           push ds
  1150.           pop  es
  1151.           mov  di,offset loadname
  1152.           rep  movsb
  1153.           mov  si,offset ext ; Erweiterung anfügen
  1154.           mov  cx,4
  1155.           rep  movsb
  1156.  
  1157.           mov  ah,3dh        ; Datei öffnen
  1158.           mov  al,00h
  1159.           mov  dx,offset loadname
  1160.           int  21h
  1161.           jnc  ok
  1162.  
  1163.           mov  ah,09h        ; Fehlermeldung
  1164.           mov  dx,offset notfound
  1165.           int  21h
  1166.  
  1167.           pop  bx            ; Stack bereinigen
  1168.           pop  es
  1169.  
  1170.           jmp  retload
  1171.  
  1172. ok:       mov  handle,ax
  1173.  
  1174.           pop  bx            ; Adresse zurück
  1175.           pop  es
  1176.  
  1177.           mov  di,bx         ; alte Daten löschen
  1178.           mov  cx,162*maxentry/2
  1179.           xor  ax,ax
  1180.           rep stosw
  1181.  
  1182.           push bx            ; Puffer einlesen
  1183.           mov  ah,3fh
  1184.           mov  bx,handle
  1185.           mov  cx,170*maxentry
  1186.           mov  dx,offset readbuf
  1187.           int  21h
  1188.           pop  bx
  1189.  
  1190.                              ; Puffer durcharbeiten
  1191.           mov  si,offset readbuf
  1192.           mov  di,bx
  1193.           mov  dl,1
  1194.  
  1195. loopen:
  1196.           xor  bx,bx         ; Hotkey (Hex-Wert) holen
  1197.           mov  cx,4
  1198. loophk:   xor  ax,ax
  1199.           lodsb
  1200.  
  1201.           cmp  al,'0'        ; Ziffern 0-9?
  1202.           jb   nonum
  1203.           cmp  al,'9'
  1204.           ja   nonum
  1205.           sub  al,'0'        ; num. Wert errechnen
  1206.           jmp  addit
  1207.  
  1208. nonum:    cmp  al,'a'        ; Ziffern a-f (klein)?
  1209.           jb   nosmall
  1210.           cmp  al,'f'
  1211.           ja   nosmall
  1212.           sub  al,'a'-10     ; num. Wert errechnen
  1213.           jmp  addit
  1214.  
  1215. nosmall:                     ; Ziffern A-Z (groß)!
  1216.           sub  al,'A'-10     ; num. Wert errechnen
  1217.  
  1218. addit:    push cx            ; Zähler sichern
  1219.  
  1220.           dec  cl            ; CL vermindern,
  1221.           shl  cl,1          ; mit 4 multiplizieren
  1222.           shl  cl,1          ; (= 2 mal nach links)
  1223.  
  1224.           shl  ax,cl         ; Wert umrechnen und addieren
  1225.           add  bx,ax
  1226.  
  1227.           pop  cx            ; Zähler zurück
  1228.  
  1229.           loop loophk
  1230.  
  1231.           inc  si
  1232.           mov  ax,bx
  1233.           stosw              ; Tastencode wegschreiben
  1234.  
  1235.           mov  cx,32         ; Namen holen
  1236. loopna:   lodsb
  1237.           cmp  al,';'        ; Name zuende?
  1238.           je   nameok
  1239.           stosb
  1240.           dec  cx
  1241.           jmp  loopna
  1242. nameok:   add  di,cx         ; Dest.-Index auf Pfad
  1243.  
  1244.           mov  cx,64         ; Pfad holen
  1245. looppa:   lodsb
  1246.           cmp  al,';'        ; Pfad zuende?
  1247.           je   pathok
  1248.           stosb
  1249.           dec  cx
  1250.           jmp  looppa
  1251. pathok:   add  di,cx         ; Dest.-Index auf Programm
  1252.  
  1253.           mov  cx,64         ; Programm holen
  1254. looppr:   lodsb
  1255.  
  1256.           cmp  al,cr         ; Zeilenende?
  1257.           jne  nocrlf
  1258.           inc  si
  1259.           mov  al,[si]
  1260.           cmp  al,0          ; Dateiende ohne EOF?
  1261.           jne  progok
  1262.           mov  al,eof        ; EOF setzen
  1263.           jmp  progok
  1264.  
  1265. nocrlf:   cmp  al,eof        ; Dateiende mit EOF?
  1266.           je   progok
  1267.           cmp  al,0          ; Dateiende ohne EOF?
  1268.           jne  noeof
  1269.           mov  al,eof        ; EOF setzen
  1270.           jmp  progok
  1271.  
  1272. noeof:    stosb
  1273.           dec  cx
  1274.           jmp  looppr
  1275.  
  1276. progok:   add  di,cx         ; DI auf nächsten Eintrag
  1277.  
  1278.           cmp  al,eof        ; Ende der Datei?
  1279.           je   readok
  1280.  
  1281.           inc  dl            ; noch Einträge möglich?
  1282.           cmp  dl,5
  1283.           ja   readok
  1284.  
  1285.           jmp  loopen
  1286.  
  1287. readok:   mov  ah,3eh        ; Datei schließen
  1288.           mov  bx,handle
  1289.           int  21h
  1290.  
  1291.           mov  ah,09h        ; Meldung ausgeben
  1292.           mov  dx,offset loadmsg
  1293.           int  21h
  1294.  
  1295. retload:  ret
  1296.  
  1297. loaddata  endp
  1298.  
  1299. cseg      ends
  1300.           end  start
  1301.