home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / lib4a86 / demo / bheap.dem next >
Text File  |  1992-02-16  |  43KB  |  1,342 lines

  1. ; ----------------------------
  2. ; BHEAP.DEM    - Demoprogramm für die Routinen aus BHEAP.LIB
  3. ;                (für den A86)
  4. ;
  5. ;                (c) Bernd Schemmer 1992
  6. ;                Letzter Update: 15.02.1992
  7. ;
  8. ; Übersetzen:
  9. ;  A86 BHEAP.DEM DEMOS.INC TO BHEAP.COM
  10. ;
  11. ; Hinweis: Die Environment-Variable 'A86' muß den Dateinamen 'MACROS.MAC'
  12. ;          enthalten und die .LIB-Dateien müssen über die Datei A86.LIB
  13. ;          erreichbar sein.
  14. ;
  15. ; ---------------------------
  16.  
  17.          jmp start
  18.  
  19. ; ----------------------------
  20.                               ; Meldungen und Fehlermeldungen
  21. logo  db CR,LF
  22.       db 'BHEAP.DEM  - Demoprogramm für die Routinen aus BHEAP.LIB' ,CR,LF
  23.       db '--------------------------------------------------------' ,CR,LF
  24.       db 'Das Programm führt folgende Arbeitsschritte aus:'         ,CR,LF
  25.       db '1. Einlesen der Eingabe-Datei auf den BasedHeap'          ,CR,LF
  26.       db '2. Entfernen aller Zeilen, die mit einem Semikolon'       ,CR,LF
  27.       db '   beginnen und Ersetzen aller Leerzeilen durch '';;'''   ,CR,LF
  28.       db '3. Verkleinern des BasedHeaps auf die kleinst mögliche'   ,CR,LF
  29.       db '   Größe und Sichern des BasedHeaps in die Datei DEMO.BHP',CR,LF
  30.       db '4. Löschen des BasedHeaps'                                ,CR,LF
  31.       db '5. Neuanlage des BasedHeaps in einem anderen Segment'     ,CR,LF
  32.       db '6. Lesen des BasedHeaps aus der Datei DEMO.BHP und ver-'  ,CR,LF
  33.       db '   größern des BasedHeaps auf die maximal mögliche Größe.',CR,LF
  34.       db '7. Ausgeben des BasedHeaps in die Ausgabe-Datei'          ,CR,LF
  35.       db CR,LF
  36.       db 'Das Demo muß folgendermaßen aufgerufen werden:'           ,CR,LF
  37.       db '      BHEAP.COM eingabedatei ausgabedatei'                ,CR,LF
  38.       db CR,LF,CR,LF
  39.       db 'Bitte eine Taste drücken (ESC = Programm-Abbruch) ...'    ,CR,LF
  40.       db CR,LF
  41. GETLENGTH logo
  42.  
  43.                               ; Fehlermeldungen
  44.                               ; ------------------------------------------
  45. MakeMsg ParamError,     '*** Fehlerhaften Parameter oder zuwenig Parameter angegeben.'
  46. MakeMsg MemoryError,    '*** Zuwenig freier Speicher.'
  47. MakeMsg OFileError,     '*** Fehler beim Öffnen der Ausgabe-Datei'
  48. MakeMsg IFileError,     '*** Fehler beim Lesen der Eingabe-Datei'
  49. MakeMsg IFileError1,    '*** Eingabe-Datei ist zu groß'
  50. MakeMsg WriteFileError, '*** Fehler beim Schreiben der Datei mit dem BasedHeap.'
  51. MakeMsg ReadFileError,  '*** Fehler beim Lesen der Datei mit dem BasedHeap.'
  52. MakeMsg OutputError,    '*** Fehler beim Schreiben in die Ausgabe-Datei.'
  53.  
  54.                               ; Meldungen
  55.                               ; ------------------------------------------
  56. MakeMsg HeapInitMsg,    '--- Richte den BasedHeap ein ...'
  57. MakeMsg MakeDummys,     '--- Erstelle die Dummy-Blöcke ...'
  58. MakeMsg ReadLinesMsg,   '--- Lese die Eingabe-Datei ...'
  59. MakeMsg CollectMsg,     '--- Reorganisiere die freien Blöcke auf dem BasedHeap ...'
  60. MakeMsg ProceedMsg,     '--- Bearbeite die Zeilen ... '
  61. MakeMsg ShrinkMsg,      '--- Verkleinere den BasedHeap ...'
  62. MakeMsg WriteFileMsg,   '--- Sichere den BasedHeap in die Datei DEMO.BHP ... '
  63. MakeMsg DeleteMsg,      '--- Lösche den BasedHeap ...'
  64. MakeMsg NewInitMsg,     '--- Richte den BasedHeap neu ein ...'
  65. MakeMsg ReadFileMsg,    '--- Lese den BasedHeap aus der Datei DEMO.BHP ...'
  66. MakeMsg ExpandMsg,      '--- Vergrößere den BasedHeap ...'
  67. MakeMsg ShowHeapMsg,    '--- Schreibe die Zeilen in die Ausgabe-Datei ...'
  68. MakeMsg DeleteMsg1,     '--- Lösche den BasedHeap ...'
  69.  
  70. MakeMsg Lines1Msg,      '_____ Elemente auf dem BasedHeap.'
  71. MakeMsg Lines2Msg,      '_____ Zeilen werden geschrieben.'
  72.  
  73.                               ; Variablen
  74.                               ; ------------------------------------------
  75.  
  76.                               ; Puffer zum Lesen der Zeilen der Eingabe-Datei
  77. LineBuffer         db 0,255 dup 20h
  78.  
  79.                               ; Variablen zum Verwalten der Ein- und Ausgabe-
  80.                               ; Dateien
  81. OutputFileHandle   dw 0       ; Handle der Ausgabe-Datei
  82. InputFileHandle    dw 0       ; Handle der Eingabe-Datei
  83. InputFileLength    dw 0       ; Größe der Eingabe-Datei
  84.  
  85.                               ; Zum Lesen und Schreiben wird der gleiche
  86.                               ; Puffer verwendet!
  87. OutputFileOff      LABEL WORD ; Pufferzeiger für die Ausgabe-Datei
  88. InputFileOff       dw 0       ; Pufferzeiger für die Eingabe-Datei
  89. InOutFileSeg       dw 0       ; Segment des Speicherblocks zum Lesen der
  90.                               ; Eingabe-Datei und Schreiben der Ausgabe-Datei
  91.  
  92. ; ------------------
  93.                               ; Name der Datei zum Sichern des BasedHeaps
  94. BHeapFileName      db 'DEMO.BHP',0
  95. BHeapFileHandle    dw 0       ; Handle der Datei zum Sichern des BasedHeaps
  96. BHeapFileLength    dw 0       ; Länge der Datei zum Sichern des BasedHeaps
  97.  
  98. BasedheapLength    dw 01000h  ; Länge des Speicherblocks für den BasedHeap
  99.                               ; in Paragraphen, Voreinstellung: 1 Segment
  100.  
  101. ; ------------------
  102.                               ; Aufbau der Blöcke auf dem BasedHeap
  103.                               ; ------------------------------------------
  104. HeapBlock STRUC
  105.          Previous dw ?        ; Zeiger auf den Vorgänger
  106.          Next     dw ?        ; Zeiger auf den Nachfolger
  107.       LineLength  db ?        ; Länge der Zeile
  108.          Line     db ?        ; Zeileninhalt (variabel!)
  109.           ENDS
  110.  
  111. ; ----------------------------
  112. start:
  113.          call ShowLogoAndAsk  ; Logo ausgeben, Speicherblock verkleinern
  114.                               ; und Taste lesen
  115. ; ----------------------------
  116.                               ; Ein- und Ausgabe-Dateien eröffnen
  117.          call OpenInAndOutputFiles
  118.          IF c jmp ErrorEnde1  ; Fehler!
  119.  
  120. ; ----------------------------
  121. l1:
  122.                               ; 1. Teil: BasedHeap anlegen und Zeilen lesen
  123.                               ; -------------------------------------------
  124.          Write_String HeapInitMsg
  125.  
  126.          call BuildBasedHeap  ; BasedHeap einrichten
  127.          IF c jmp ErrorEnde1  ; Fehler!
  128.  
  129.                               ; Größe des Speicherblocks für den BasedHeap
  130.                               ; sichern
  131.          mov BasedHeapLength,cx
  132.  
  133.          call ShowBasedHeapData
  134.          IF c jmp ErrorEnde1
  135.                               ; ES = BasedHeap-Segment
  136.  
  137.          Write_String MakeDummys
  138.                               ; Kette für die Zeilen initialisieren
  139.          call InitBasedHeapKette
  140.          IF c jmp ErrorEnde1  ; Fehler!
  141.  
  142.          call ShowBasedHeapData
  143.          IF c jmp ErrorEnde1
  144.                               ; SI -> 1. DummyBlock
  145.                               ; DI -> 2. DummyBlock
  146.                               ; alle weiteren Blöcke werden zwischen diesen
  147.                               ; beiden Blöcken in die Kette eingefügt
  148.  
  149. ; ------------------
  150.          Write_String ReadLinesMsg
  151.                               ; Such-Strategie ändern
  152.          or b es:BHeapFlags,TryLastPtrFirst
  153.          and b es:BHeapFlags,FreePtrFirst
  154.  
  155.                               ; nun alle Zeilen aus der Eingabe-Datei
  156.                               ; bearbeiten
  157.          mov B PunktZaehler,0
  158.  
  159. ReadLineLoop:
  160.          call LaufZeitAnzeige
  161.                               ; Zeile lesen
  162.          call GetNextLine
  163.          jc >l1               ; EOF erreicht
  164.  
  165.          call GetNewHeapBlock ; neuen Block erstellen
  166.          call CheckBasedHeapError
  167.          jnc ReadLineLoop
  168.  
  169.          push ax,bx,cx,dx
  170.          call ShowCR_LF
  171.          call ZeigeAnzahl
  172.  
  173.          call ShowBasedHeapData
  174.          pop dx,cx,bx,ax
  175.          jmp ErrorEnde1
  176.  
  177.  
  178. ; ------------------
  179. l1:
  180.          mov B PunktZaehler,0
  181.                               ; Dateiende erreicht
  182.          call ShowCR_LF
  183.          call ZeigeAnzahl
  184.  
  185.          call ShowBasedHeapData
  186.          IF c jmp ErrorEnde1
  187. ; ----------------------------
  188.                               ; 2. Zeilen Bearbeiten
  189.                               ; --------------------
  190.          Write_String ProceedMsg
  191.  
  192.          call ProceedLines
  193.          IF c jmp ErrorEnde1  ; Fehler!
  194.  
  195.          call ZeigeAnzahl
  196.  
  197.          call ShowBasedHeapData
  198.          IF c jmp ErrorEnde1
  199.  
  200.          Write_String CollectMsg
  201.  
  202.          call ChainFreeBHeapBlocks      ; freie Blöcke zusammenfassen
  203.          call CheckBasedHeapError
  204.          if c jmp ErrorEnde1
  205.  
  206.          call ShowBasedHeapData
  207.          if c jmp ErrorEnde1
  208.  
  209. ; ----------------------------
  210.                               ; 3. BasedHeap sichern
  211.                               ; --------------------
  212.          Write_String ShrinkMsg
  213.          call ShrinkBasedHeap ; BasedHeap verkleinern
  214.  
  215.          call ShowBasedHeapData
  216.          IF c jmp ErrorEnde1
  217.  
  218.          Write_String WriteFileMsg
  219.  
  220.          call SaveBasedHeap   ; BasedHeap sichern
  221.          if c jmp ErrorEnde1
  222.  
  223.  
  224. ; ----------------------------
  225.                               ; 4. BasedHeap löschen
  226.                               ; ---------------------
  227.          Write_String DeleteMsg
  228.  
  229.          mov es,W BHeapSeg    ; BasedHeap-Segment freigeben
  230.          mov ah,049h
  231.          int 021h
  232.  
  233.          mov es,cs            ; ES = CS
  234.  
  235.          mov ah,048h          ; ein Dummy-Segment belegen, damit sich
  236.          mov bx,010h          ; das Segment des BasedHeaps verschiebt
  237.          int 021h
  238.          jnc >l1
  239. l2:
  240.                               ; Speicherfehler!
  241.          mov dx,offset MemoryError
  242.          mov cx,MemoryError_LENGTH
  243.          jmp ErrorEnde1
  244. l1:
  245. ; ----------------------------
  246.                               ; 5. BasedHeap neu einrichten
  247.                               ; ---------------------------
  248.          Write_String NewInitMsg
  249.  
  250.                               ; ein neues Segment für den BasedHeap belegen
  251.          call BuildBasedHeap
  252.          IF c jmp ErrorEnde1
  253.                               ; CX = Länge des neu eingerichteten BasedHeaps
  254.          cmp cx,BasedHeapLength
  255.          jb l2                ; Fehler: Basedheap muß mindestens genauso
  256.                               ;         groß sein wie beim erstenmal
  257.  
  258.          call ShowBasedHeapData
  259.          IF c jmp ErrorEnde1
  260.  
  261. ; ----------------------------
  262.                               ; 6. BasedHeap aus der Datei lesen
  263.                               ; --------------------------------
  264.          Write_String ReadFileMsg
  265.  
  266.                               ; BasedHeap lesen
  267.          call ReadSavedBaseHeap
  268.          IF c jmp ErrorEnde1
  269.  
  270.          call ShowBasedHeapData
  271.          IF c jmp ErrorEnde1
  272.  
  273.          Write_String ExpandMsg
  274.          call ExpandBasedHeap ; BasedHeap vergrößeren
  275.  
  276.          call ShowBasedHeapData
  277.          IF c jmp ErrorEnde1
  278.  
  279. ; ----------------------------
  280.                               ; 7. Zeilen in die Ausgabedatei schreiben
  281.                               ; ---------------------------------------
  282.          Write_String ShowHeapMsg
  283.  
  284.          mov es,W BHeapSeg    ; ES = Segment des BasedHeaps
  285.          call ZeigeAnzahl     ; Anzahl der Elemente auf dem BasedHeap ausgeben
  286.  
  287.          call WriteHeapElements
  288.          mov ds,cs            ; DS = CS
  289.          jc ErrorEnde1
  290.  
  291.          Write_String DeleteMsg1   ; BasedHeap löschen
  292.  
  293.          call GetFirstBHeapBlock
  294.          call CheckBasedHeapError
  295.          jc ret               ; Fehler!
  296.                               ; ES:BX -> 1. Block auf dem BasedHeap
  297.          call ReleaseBHeapMem ; alle Blöcke ab dem 1. Block löschen
  298.                               ; ->> gesamten BasedHeap löschen
  299.                               ; (geht auch durch den erneuten Aufruf
  300.                               ;  von InitBHeap)
  301.          call CheckBasedHeapError
  302.          jc ret               ; Fehler!
  303.  
  304.          call ShowBasedHeapData
  305.          IF c jmp ErrorEnde1
  306.  
  307.          mov al,0
  308.          jmp SHORT Ende
  309.  
  310. ; ----------------------------
  311.                               ; DX = Offset einer Fehlermeldung
  312.                               ; CX = Länge der Fehlermeldung
  313. ErrorEnde1:
  314.          call ShowCR_LF
  315.          call OutputMsg       ; Fehlermeldung ausgeben
  316.          call ShowCR_LF
  317.  
  318. ErrorEnde:
  319.          mov al,0FFh
  320. Ende:
  321.          push ax
  322.          call CloseFiles      ; Dateien schliessen
  323.          pop ax
  324.  
  325.          EndProcess
  326.  
  327. ; ----------------------------
  328. ; ShrinkBasedHeap
  329. ;
  330. ; Funktion: Verkleinert den BasedHeap
  331. ;
  332. ; Ausgabe:  CF = 0 ->> okay
  333. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  334. ;                              DX = Offset der Fehlermeldung
  335. ;                              CX = Länge der Fehlermeldung
  336. ;
  337. ShrinkBasedHeap:
  338.          mov es,BheapSeg
  339.                               ; 1. Mindestgröße des BasedHeaps ermitteln
  340.                               ;    (= Länge des belegten Teils)
  341.          call GetMaxBHeapPointer
  342.          call CheckBasedHeapError
  343.          jc ret               ; Fehler!
  344.  
  345.          mov cx,ax            ; CX = Länge des belegten Teils
  346.                               ;
  347.          call ChangeBHeapSize ; 2. BasedHeap verkleinern
  348.          call CheckBasedHeapError
  349.          jc ret
  350.                               ; 3. Speichersegment verkleinern
  351.  
  352.          mov bx,cx            ; BX = neue Größe des BasedHeaps
  353.                               ; in Bytes
  354.          test bx,0Fh
  355.          pushf
  356.          shr bx,1
  357.          shr bx,1
  358.          shr bx,1
  359.          shr bx,1
  360.          popf
  361.          if nz inc bx         ; BX = neue Größe des BasedHeaps
  362.                               ; in Paragraphen
  363.          mov BasedHeapLength,bx
  364.  
  365.          mov ah,04Ah
  366.          int 021h             ; Speicherblock verkleinern
  367.          jnc ret
  368. l8:
  369.          mov dx,offset MemoryError
  370.          mov cx,MemoryError_LENGTH
  371.          ret
  372.  
  373. ; ----------------------------
  374. ; ExpandBasedHeap
  375. ;
  376. ; Funktion: Vergrößert den BasedHeap
  377. ;
  378. ; Ausgabe:  CF = 0 ->> okay
  379. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  380. ;                              DX = Offset der Fehlermeldung
  381. ;                              CX = Länge der Fehlermeldung
  382. ;
  383. ExpandBasedHeap:
  384.                               ; 1. Speichersegment vergrößern
  385.          mov es,BHeapSeg
  386.          mov bx,1000h
  387.          mov ah,04Ah          ; Größe des Speicherblocks ändern
  388.          int 021h
  389.          jnc >l1              ; okay
  390.                               ; Fehler
  391.          cmp ax,08            ; Fehler 8?
  392.          jne >l8              ; nein, raus
  393.  
  394.          mov ah,04Ah          ; ja, versuchen wir es nochmal
  395.          int 021h
  396.          jnc >l1
  397. l8:
  398.          mov dx,offset MemoryError
  399.          mov cx,MemoryError_LENGTH
  400.          stc
  401.          ret
  402. l1:
  403.          cmp BasedHeapLength,bx
  404.          ja l8                ; zuwenig Speicher
  405.  
  406.          mov BasedHeapLength,bx
  407.  
  408.          mov cx,bx            ; CX = neue Größe des Speicherblocks
  409.          shl cx,1             ; in Paragraphen
  410.          shl cx,1
  411.          shl cx,1
  412.          shl cx,1
  413.          or cx,cx
  414.          if z dec cx          ; CX = neue Größe des Speicherblocks
  415.                               ; in Bytes
  416.  
  417.          call ChangeBHeapSize ; 2. BasedHeap vergrößern
  418.          call CheckBasedHeapError
  419.          ret
  420.  
  421. ; ----------------------------
  422. ; SaveBasedHeap
  423. ;
  424. ; Funktion: Sichert den BasedHeap
  425. ;
  426. ; Ausgabe:  CF = 0 ->> okay
  427. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  428. ;                              DX = Offset der Fehlermeldung
  429. ;                              CX = Länge der Fehlermeldung
  430. ;
  431. SaveBasedHeap:
  432.          mov cx,0             ; Datei zum Sichern des BasedHeaps
  433.          mov ah,03Ch          ; anlegen und öffnen
  434.          mov dx,offset BHeapFileName
  435.          int 021h
  436.          jc >l2               ; Fehler beim Öffnen der Datei
  437.  
  438.                               ; FileHandle sichern
  439.          mov BHeapFileHandle,ax
  440.  
  441.                               ; Größe des zu sichernden Teils ermitteln
  442.          call GetMaxBHeapPointer
  443.          call CheckBasedHeapError
  444.          jc ret               ; Fehler!
  445.  
  446.                               ; AX = Größe des zu sichernden BasedHeaps
  447.          mov BHeapFileLength,ax
  448.  
  449.          mov cx,ax            ; CX = Größe des zu sichernden BasedHeaps
  450.          mov bx,BHeapFileHandle
  451.          mov dx,0
  452.          mov ds,W BHeapSeg    ; DS <> CS
  453.          mov ah,040h
  454.          int 021h
  455.          mov ds,cs            ; DS = CS
  456.          jc >l2               ; Fehler beim Schreiben der Datei
  457.  
  458.          cmp ax,cx
  459.          jne >l2              ; Fehler beim Schreiben der Datei
  460.  
  461.          mov ah,03Eh
  462.          int 021h             ; Datei schließen
  463.          jnc >l1
  464.                               ; Fehler beim Schliessen der Datei
  465. l2:
  466.          mov dx,Offset WriteFileError
  467.          mov cx,WriteFileError_LENGTH
  468.          stc
  469. l1:
  470.          ret
  471.  
  472. ; ----------------------------
  473. ; ReadSavedBaseHeap
  474. ;
  475. ; Funktion: Liest den BasedHeap aus einer Datei
  476. ;
  477. ; Ausgabe:  CF = 0 ->> okay
  478. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  479. ;                              DX = Offset der Fehlermeldung
  480. ;                              CX = Länge der Fehlermeldung
  481. ;
  482. ReadSavedBaseHeap:
  483.          mov ax,03D00h        ; Datei zum Lesen öffnen
  484.          mov dx,offset BHeapFileName
  485.          int 021h
  486.          jc >l2               ; Fehler beim Öffnen der Datei
  487.  
  488.          mov BHeapFileHandle,ax         ; FileHandle sichern
  489.          mov cx,BHeapFileLength         ; CX = Größe des zu lesenden BasedHeaps
  490.          mov bx,BHeapFileHandle
  491.          mov ds,W BHeapSeg    ; DS <> CS
  492.          mov dx,0
  493.          mov ah,03Fh
  494.          int 021h
  495.          mov ds,cs            ; DS = CS
  496.          jc >l2
  497.  
  498.          cmp ax,cx
  499.          jnz >l2              ; Fehler beim Lesen
  500.  
  501.          mov ah,03Eh
  502.          int 021h             ; Datei schließen
  503.          jnc >l1
  504.                               ; Fehler beim Schliessen der Datei
  505. l2:
  506.          mov dx,offset ReadFileError
  507.          mov cx,ReadFileError_LENGTH
  508.          stc
  509. l1:
  510.          ret
  511.  
  512. ; ----------------------------
  513. ; BuildBasedHeap
  514. ;
  515. ; Funktion: Richtet den BasedHeap ein
  516. ;
  517. ; Ausgabe:  CF = 0 ->> okay,   ES = Segment des BasedHeaps
  518. ;                              CX = Länge des Speicherblocks des
  519. ;                                   BasedHeaps in Paragraphen
  520. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  521. ;                              DX = Offset der Fehlermeldung
  522. ;                              CX = Länge der Fehlermeldung
  523. ;
  524. BuildBasedHeap:
  525.          mov ah,048h          ; Neues Segment für den BasedHeap anfordern
  526.          mov bx,BasedHeaplength
  527.          int 021h
  528.          jnc >l1
  529.          cmp ax,8
  530.          jne >l2              ; Fehler!
  531.  
  532.          mov ah,048h          ; nehmen wir was wir kriegen können
  533.          int 021h
  534.          jnc >l1
  535. l2:
  536.                               ; Speicherfehler!
  537.          mov dx,offset MemoryError
  538.          mov cx,MemoryError_LENGTH
  539.          stc
  540.          jmp ret
  541. l1:
  542.                               ; AX = Segment für den BasedHeap
  543.          mov cx,bx
  544.          push cx
  545.  
  546.          mov cl,4             ; Größe des BasedHeaps in Bytes berechnen
  547.          shl bx,cl
  548.          or bx,bx
  549.          if z mov bx,0FFFFh   ; BX = Größe des BasedHeaps in Byte
  550.  
  551.                               ; BasedHeap einrichten
  552.          mov cx,bx            ; CX = Größe des BasedHeaps in Byte
  553.          mov es,ax            ; ES = Segment des BasedHeaps
  554.          call InitBHeap
  555.          pop cx
  556.  
  557.          call CheckBasedHeapError ; auf Fehler testen
  558.          jc ret               ; Fehler beim Einrichten des BasedHeaps
  559.  
  560.                               ; Das Benutzerfeld am Offset BHeapUserData1
  561.                               ; wird vom Demo als Zähler für die belegten
  562.                               ; Blöcke benutzt
  563.          mov w es:BHeapUserData1,0
  564.                               ; Das Benutzerfeld am Offset BHeapUserData2
  565.                               ; wird vom Demo als Zähler für die Anzahl
  566.                               ; der Zeilen der Ausgabe-Datei benutzt
  567.          mov w es:BHeapUserData2,0
  568.          ret
  569.  
  570. ; ----------------------------
  571. ; InitBasedHeapKette
  572. ;
  573. ; Funktion: Initialisiert die Kette auf dem BasedHeap
  574. ;
  575. ; Eingabe:  ES = Segment des BasedHeaps
  576. ;
  577. ; Ausgabe:  CF = 0 ->> okay,   ES = Segment des BasedHeaps
  578. ;                              SI = erster Block
  579. ;                              DI = letzter Block
  580. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  581. ;                              DX = Offset der Fehlermeldung
  582. ;                              CX = Länge der Fehlermeldung
  583. ;
  584. InitBasedHeapKette:
  585.                               ; Dummyblöcke einrichten (vereinfacht die
  586.                               ; Kettenbearbeitung)
  587.          mov cx, TYPE (HeapBlock) + 255
  588.          call GetBHeapMem
  589.          call CheckBasedHeapError
  590.          jc ret
  591.          mov si,bx            ; ES:SI -> erster Dummyblock
  592.          mov cx, TYPE (HeapBlock) + 255
  593.          call GetBHeapMem
  594.          call CheckBasedHeapError
  595.          jc ret
  596.          mov di,bx            ; ES:DI -> zweiter Dummyblock
  597.  
  598.                               ; 1. Dummyblock füllen
  599.          mov es:Previous[si],0
  600.          mov es:Next[si],di
  601.          mov es:LineLength[si],255
  602.          push di
  603.          mov di,si
  604.          add di,offset Line
  605.          mov cx,255
  606.          mov al,0
  607.          rep stosb
  608.          pop di
  609.                               ; 2. Dummyblock füllen
  610.          mov es:Previous[di],si
  611.          mov es:Next[di],0FFFFh
  612.          mov es:LineLength[di],255
  613.          push di
  614.          add di,offset Line
  615.          mov cx,255
  616.          mov al,0FFh
  617.          rep stosb
  618.          pop di
  619.  
  620.          clc
  621.          ret
  622.  
  623. ; ----------------------------
  624. ; ProceedLines
  625. ;
  626. ; Funktion: Bearbeitet die Zeilen nach folgendem Schema:
  627. ;           Zeilen, die mit einem Semikolon beginnen werden entfernt
  628. ;           und leere Zeilen werden durch die Zeile ';;' ersetzt
  629. ;
  630. ; Ausgabe:  CF = 0 ->> okay
  631. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  632. ;                              DX = Offset der Fehlermeldung
  633. ;                              CX = Länge der Fehlermeldung
  634. ;
  635. ProceedLines:
  636.          mov es,w BHeapSeg    ; ES = BasedHeap-Segment
  637.  
  638.                               ; Zu Demo-Zwecken die Zusammenfassung von
  639.                               ; freien Blöcken unterbinden
  640.          or b es:BHeapFlags,NoBigFreeBlocks
  641.  
  642.  
  643.          call GetFirstBHeapBlock
  644.          call CheckBasedHeapError
  645.          jc ret               ; Fehler!
  646.  
  647.                               ; ES:BX -> 1. Block
  648.          mov ds,es            ; DS = BasedHeap-Segment
  649.          mov si,bx            ; DS:SI -> erstes Element = Dummy
  650.          mov si,Next[si]      ; DS:SI -> erstes reales Element der Kette
  651.  
  652. ; ------------------
  653. ProceedLineLoop:
  654.          cmp si,0FFFFh        ; auf Ende testen
  655.          IF e jmp ProceedLineEnd
  656. ; ------------------
  657.          cmp LineLength[si],0
  658.          jne >l1
  659. ; ------------------
  660.                               ; leere Zeilen durch die Zeile ';;' ersetzen
  661.                               ; neuen Block anfordern
  662.          mov cx,4+4+1+4
  663.          call GetNewBHeapBlock
  664.          jc ProceedLineEnd    ; Fehler!
  665.  
  666.                               ; BX -> neuer Block
  667.  
  668.                               ; Inhalt füllen
  669.          mov LineLength[bx],2
  670.          mov w Line[bx],';;'
  671.  
  672.  
  673.          xchg bx,si           ; BX -> alter Block
  674.                               ; SI -> neuer Block
  675.          push w Previous[bx]
  676.          push w Next[bx]      ; Zeiger des alten Blocks sichern
  677.                               ; alten Block löschen
  678.  
  679.          call FreeBHeapMem    ; und Block freigeben
  680.          call CheckBasedHeapError
  681.  
  682.          pop w Next[si]       ; Zeiger des neuen Blocks setzen
  683.          pop w Previous[si]
  684.          jc ProceedLineEnd    ; Fehler
  685.  
  686.          inc w BHeapUserData2 ; Zähler erhöhen
  687.  
  688.          mov bx,Previous[si]
  689.          mov Next[bx],si      ; Vorgänger korrigieren
  690.  
  691.          mov bx,Next[si]
  692.          mov Previous[bx],si  ; Nachfolger korrigieren
  693.  
  694.          mov si,Next[si]      ; SI -> nächster Block
  695.          jmp SHORT ProceedLineLoopEnd
  696.  
  697. ; ------------------
  698. l1:
  699.          cmp Line[si],';'
  700.          jne >l1
  701. ; ------------------
  702.                               ; Kommentar-Zeilen löschen
  703.          mov bx,si
  704.          mov si,Next[bx]      ; SI -> nächster Block
  705.          call DeleteBlock
  706.          jc ProceedLineEnd
  707.          jmp SHORT ProceedLineLoopEnd
  708. ; ------------------
  709. l1:
  710.                               ; alle anderen Zeilen so übernehmen
  711.          inc w BHeapUserData2
  712.          mov si,Next[si]      ; SI -> nächster Block
  713. ; ------------------
  714. ProceedLineLoopEnd:
  715.          call LaufZeitAnzeige
  716.          jmp ProceedLineLoop
  717. ; ------------------
  718. ProceedLineEnd:
  719.          mov ds,cs            ; DS = CS
  720.          pushf
  721.          call ShowCR_LF
  722.          popf
  723.          ret
  724.  
  725. ; ----------------------------
  726. ; GetNewBHeapBlock
  727. ;
  728. ; Funktion: Belegt einen neuen Block auf dem BasedHeap
  729. ;
  730. ; Eingabe:  DS = ES = Segment des BasedHeaps
  731. ;           CX = Länge für den neuen Block
  732. ;
  733. ; Ausgabe:  CF = 0 ->> okay
  734. ;                      DS:BX -> neuer Block
  735. ;           CF = 1 ->> Fehler
  736. ;                      DX -> Fehlermeldung
  737. ;                      CX -> Länge der Fehlermeldung
  738. ;
  739. GetNewBHeapBlock:
  740.          push ds
  741.          push bp
  742.          mov bp,sp
  743.  
  744.          mov ds,cs
  745.  
  746. l0:
  747.          push cx
  748.  
  749.          call GetBHeapMem     ; Speicher anfordern
  750.          jnc >l10
  751.  
  752.                               ; Fehler
  753.          cmp ax,BHeapMemoryError
  754.          jne >l1
  755.  
  756.                               ; Fehler 'Kein freier Block mehr vorhanden'
  757.          test b es:BHeapFlags,NoBigFreeBlocks
  758.          jz >l1               ; nichts mehr zu machen
  759.  
  760.          call ShowBasedHeapData
  761.          jc >l10
  762.  
  763.          Write_String CollectMsg
  764.  
  765.          call ChainFreeBHeapBlocks      ; freie Blöcke zusammenfassen
  766.          jc >l1
  767.  
  768.          call ShowBasedHeapData
  769.          jc >l10
  770.  
  771.          and b es:BHeapFlags,BigFreeBlocks
  772.          pop cx
  773.          jmp l0               ; und neuer Versuch
  774.  
  775. l1:
  776.          call CheckBasedHeapError
  777.  
  778. l10:
  779.          mov sp,bp
  780.          pop bp
  781.          pop ds
  782.          ret
  783.  
  784. ; ----------------------------
  785. ; DeleteBlock
  786. ;
  787. ; Funktion: Löscht einen Block vom BasedHeap
  788. ;
  789. ; Eingabe:  DS:BX -> zu löschender Block
  790. ;
  791. ; Ausgabe:  CF = 0 ->> okay
  792. ;           CF = 1 ->> Fehler
  793. ;                      DX -> Fehlermeldung
  794. ;                      CX -> Länge der Fehlermeldung
  795. ;
  796. DeleteBlock:
  797.          push di,si,bx
  798.          dec w BHeapUserData1 ; Zähler korrigieren
  799.  
  800.          mov si,Previous[bx]  ; SI = Vorgänger
  801.                               ; BX = Block
  802.          mov di,Next[bx]      ; DI = Nachfolger
  803.  
  804.                               ; Zeiger korrigieren
  805.          mov Next[si],di
  806.          mov Previous[di],si
  807.  
  808.          call FreeBHeapMem    ; und Block freigeben
  809.          call CheckBasedHeapError
  810.  
  811. DeleteBlockEnd:
  812.          pop bx,si,di
  813.          ret
  814.  
  815. ; ----------------------------
  816. ; WriteHeapElements
  817. ;
  818. ; Funktion: Ausgabe der Elemente auf dem BasedHeap
  819. ;           in die Ausgabe-Datei
  820. ;
  821. ; Ausgabe:  CF = 0 ->> okay
  822. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  823. ;                              DX = Offset der Fehlermeldung
  824. ;                              CX = Länge der Fehlermeldung
  825. ;           DS = BasedHeap-Segment
  826. ;
  827. WriteHeapElements:
  828.          mov OutPutFileOff,0  ; Pufferzeiger zurücksetzen
  829.  
  830.          mov es,w BHeapSeg    ; ES = BasedHeap-Segment
  831.                               ; Anzahl der Elemente auf dem BasedHeap ausgeben
  832.          mov di,offset Lines2Msg
  833.          mov ax,es:[BHeapUserData2]
  834.          dec ax
  835.          push es
  836.          mov es,cs            ; ES = CS
  837.          call Konvert_AX_To_Dezstring
  838.          Write_String Lines2Msg
  839.          pop es
  840.  
  841.          call GetFirstBHeapBlock
  842.          call CheckBasedHeapError
  843.          jc ret               ; Fehler!
  844.  
  845.                               ; ES:BX -> akt. Element
  846.          mov ds,es            ; DS = BasedHeap-Segment
  847.          mov si,bx            ; DS:SI -> erstes Element = Dummy
  848.          mov si,Next[si]      ; DS:SI -> erstes reales Element der Kette
  849.  
  850.          xor cx,cx
  851. l00:
  852.          cmp Next[si],0FFFFh
  853.          je >l9               ; Ende erreicht
  854.  
  855.          lea dx,Line[si]      ; DX -> Inhalt
  856.          mov cl,LineLength[si]          ; CX -> L(Inhalt)
  857.          call PutNextLine     ; Zeile in den Ausgabe-Puffer übernehmen
  858.          mov si,Next[si]      ; und nächstes Element
  859.          jmp l00
  860.  
  861. l9:                           ; und Puffer schreiben
  862.          call WriteOutPutFileBuffer
  863.          jnc >l1
  864.                               ; Fehler beim Schreiben
  865.          mov dx,offset OutputError
  866.          mov cx,OutputError_LENGTH
  867.          push ax
  868.          call OutputMsg
  869.          pop ax
  870.          stc
  871. l1:
  872.          ret
  873.  
  874. ; ----------------------------
  875. ; GetNewHeapBlock
  876. ;
  877. ; Funktion: Belegt einen neuen Block auf dem BasedHeap
  878. ;
  879. ; Eingabe:  Die Zeile steht in LineBuffer
  880. ;           SI -> Vorgänger
  881. ;           DI -> Nachfolger
  882. ;           DS = CS
  883. ;
  884. ; Ausgabe:  CF = 0 ->> okay, SI und DI enthalten die Vorgänger
  885. ;                      und Nachfolger für den nächsten Block
  886. ;           CF = 1 ->> Fehler, AX = Fehlernummer
  887. ;                              DX = Offset der Fehlermeldung
  888. ;                              CX = Länge der Fehlermeldung
  889. ;
  890. GetNewHeapBlock:
  891.                               ; Länge des neuen Blocks berechnen
  892.          mov cl,LineBuffer    ; CL = Länge der Zeile
  893.          xor ch,ch
  894.          inc cx
  895.          add cx,TYPE (HeapBlock)
  896.          cmp cx,5
  897.          if b mov cx,5        ; CX = Länge des neuen Blocks
  898.  
  899. l0:
  900.          call GetBHeapMem     ; neuen Block anfordern
  901.          jc ret
  902.                               ; Zähler für die BasedHeap-Elemente erhöhen
  903.          inc w es:[BHeapUserData1]
  904.                               ; Zeiger des Blocks belegen
  905.                               ; SI -> Vorgänger
  906.                               ; BX -> neuer Block
  907.                               ; DI -> Nachfolger
  908.          mov ax,es:Next[si]   ; AX = Nachfolger des Vorgängers
  909.          mov es:Next[bx],ax
  910.  
  911.          mov ax,es:Previous[di]         ; AX = Vorgänger des Nachfolgers
  912.          mov es:Previous[bx],ax
  913.  
  914.          mov es:Next[si],bx             ; Nachfolger des Vorgängers korrigieren
  915.          mov es:Previous[di],bx         ; Vorgänger des Nachfolgers korrigieren
  916.  
  917.          mov si,bx            ; neuen Vorgänger nach SI
  918.          mov di,es:Next[bx]   ; neuer Nachfolger nach DI
  919.  
  920.          mov cl,LineBuffer    ; Blockinhalt belegen
  921.          xor ch,ch
  922.          inc cx               ; CX = Länge der Zeile für den Block
  923.                               ; (incl. Längenzähler)
  924.          push di,si
  925.          lea di,LineLength[bx]
  926.          mov si,offset LineBuffer
  927.          rep movsb
  928.          pop si,di
  929.          clc
  930.          ret
  931.  
  932. ; ----------------------------
  933. ; OpenInAndOutputFiles
  934. ;
  935. ; Funktion: Öffnet die Ein- und Ausgabe-Dateien und liest die Eingabe-Datei
  936. ;
  937. ; Ausgabe:  CF = 0 ->> okay
  938. ;           CF = 1 ->> Fehler
  939. ;                      DX = Offset der Fehlermeldung
  940. ;                      CX = Länge der Fehlermeldung
  941. ;
  942. OpenInAndOutputFiles:
  943.          mov bx,1000h         ; Speicher zum Lesen der Eingabe-Datei anfordern
  944.          mov ah,048h          ; 1 Segment
  945.          int 021h
  946.          jnc >l1
  947.                               ; Fehler, nicht genügend Speicher vorhanden
  948.          mov dx,offset MemoryError
  949.          mov cx,MemoryError_LENGTH
  950.          stc
  951.          ret
  952.  
  953. ; ------------------
  954. l1:
  955.          mov InOutFileSeg,ax  ; Segment sichern
  956.  
  957.          mov si,080h          ; Parameter bearbeiten
  958.          lodsb
  959.          or al,al
  960.          jnz >l1
  961.                               ; Fehler: Keine Parameter angegeben
  962. ParameterError:
  963.          mov dx,offset ParamError
  964.          mov cx,ParamError_LENGTH
  965.          stc
  966.          ret
  967.  
  968. ; ------------------
  969. l1:
  970.          call GetFileName     ; Anfang des ersten Dateinamens suchen
  971.          jc ParameterError
  972.                               ; DS:DX -> erster Dateiname als ASCIIZ-String
  973. ; ------------------
  974.          mov ax,03D02h        ; Eingabe-Datei öffnen
  975.          int 021h
  976.          jnc >l1
  977. ; ------------------
  978. InputFileError:
  979.          mov dx,offset IFileError
  980.          mov cx,IFileError_LENGTH
  981.          stc
  982.          ret
  983. ; ------------------
  984. l1:
  985.          mov InputFileHandle,ax         ; Handle der Eingabe-Datei sichern
  986. ; ------------------
  987.          call GetFileName     ; Name der Ausgabe-Datei ermitteln
  988.          jc ParameterError
  989. ; ------------------
  990.                               ; Ausgabe-Datei anlegen
  991.          mov cx,0             ; CX = Standard-Attribte
  992.          mov ah,03Ch          ; Datei erstellen
  993.          int 021h
  994.          jnc >l1
  995. ; ------------------
  996. OutputFileError:
  997.          mov dx,offset OFileError
  998.          mov cx,OFileError_LENGTH
  999.          stc
  1000.          ret
  1001. ; ------------------
  1002. l1:
  1003.          mov OutputFileHandle,ax        ; Handle der Ausgabe-Datei sichern
  1004. ; ------------------
  1005.          mov ah,03Fh          ; und Eingabe-Datei lesen
  1006.          mov cx,0FFF5h
  1007.          mov bx,InputFileHandle
  1008.          lds dx,InputFileOff  ; DS <> CS
  1009.          int 021h
  1010.          mov ds,cs            ; DS = CS
  1011.          jc InputFileError
  1012.          cmp ax,cx
  1013.          jb >l1
  1014. ; ------------------
  1015. InputFileError1:
  1016.          mov dx,offset IFileError1
  1017.          mov cx,IFileError1_LENGTH
  1018.          stc
  1019.          ret
  1020. ; ------------------
  1021. l1:
  1022.          mov InputFileLength,ax         ; Länge der Datei sichern
  1023.          clc
  1024.          ret
  1025.  
  1026. ; ----------------------------
  1027. ; GetFileName
  1028. ;
  1029. ; Funktion: Ermittelt den nächsten Parameter und konvertiert ihn in
  1030. ;           einen ASCIIZ-String
  1031. ;
  1032. ; Eingabe:  SI -> Ende des letzte Parameters
  1033. ;
  1034. ; Ausgabe:  CF = 0 ->> okay, DX -> Anfang des Parameters
  1035. ;           CF = 1 ->> Fehler
  1036. ;
  1037. GetFileName:
  1038. l0:                           ; Anfang des Parameters suchen
  1039.          lodsb
  1040.          cmp al,BLANK
  1041.          je l0
  1042.          cmp al,TAB
  1043.          je l0
  1044.          cmp al,CR
  1045.          je >l8
  1046. ; ------------------
  1047.          lea dx,[si-1]        ; Anfang des Parameters gefunden
  1048.  
  1049. l1:                           ; Ende des Parameters suchen
  1050.          lodsb
  1051.          cmp al,BLANK
  1052.          je >l2
  1053.          cmp al,TAB
  1054.          je >l2
  1055.          cmp al,CR
  1056.          je >l2
  1057.          jmp l1
  1058. l2:
  1059.          mov b[si-1],0        ; Nullbyte eintragen
  1060.          clc
  1061.          ret
  1062.  
  1063. ; ------------------
  1064. l8:
  1065.          stc
  1066.          ret
  1067.  
  1068. ; ----------------------------
  1069. ; GetNextLine
  1070. ;
  1071. ; Funktion: Ermittelt die nächste Zeile der Eingabe-Datei aus dem Puffer
  1072. ;
  1073. ; Eingabe:  DS = CS
  1074. ;
  1075. ; Ausgabe:  CF = 0 ->> LineBuffer ist gefüllt
  1076. ;           CF = 1 ->> EOF erreicht
  1077. ;
  1078. GetNextLine:
  1079.          mov ax,InputFileOff
  1080.          cmp ax,InputFileLength
  1081.          jb >l1
  1082.          stc                  ; EOF erreicht
  1083.          ret
  1084. l1:
  1085.          push ds,es,si,di,cx
  1086.  
  1087.          mov es,cs            ; ES = CS
  1088.          mov di,offset LineBuffer
  1089.                                         ; ES:DI -> Längenzähler des Zeilenpuffers
  1090.          xor cx,cx                      ; CX = Längenzähler
  1091.          lds si,cs:InputFileOff         ; DS:SI -> akt. Position im Puffer
  1092.  
  1093.          push di
  1094.          inc di               ; ES:DI -> Zeilenpuffer
  1095. l0:
  1096.          cmp cl,255xD         ; max. Zeilenlänge erreicht?
  1097.          je >l1               ; ja
  1098.  
  1099.          lodsb
  1100.          cmp al,CR
  1101.          je >l1               ; Zeilenende erreicht
  1102.          stosb                ; Zeichen übernehmen
  1103.          inc cx               ; Zähler korrigieren
  1104.          jmp l0
  1105. l1:
  1106.          cmp b[si],LF
  1107.          if e inc si          ; LF am Zeilenende überlesen
  1108.          pop di
  1109.          mov es:[di],cl       ; Länge der Zeile eintragen
  1110.  
  1111.          mov cs:InputFileOff,si         ; und Pufferzeiger sichern
  1112. l9:
  1113.          clc
  1114.          pop cx,di,si,es,ds
  1115.          ret
  1116.  
  1117. ; ----------------------------
  1118. ; PutNextLine
  1119. ;
  1120. ; Funktion: Übernimmt die nächste Zeile in den Puffer für die Ausgabe-Datei
  1121. ;
  1122. ; Eingabe:  DS:DX = Zeile
  1123. ;           CX = Länge der Zeile
  1124. ;
  1125. PutNextLine:
  1126.          push es,si,di,cx
  1127.  
  1128.          les di,cs:OutputFileOff
  1129.                               ; ES:DI -> akt. Stelle im Puffer
  1130.                               ; (Test auf Überlauf kann im Demo entfallen)
  1131.  
  1132.          mov si,dx            ; SI -> Zeile
  1133.                               ; CX = Anzahl Zeichen
  1134.          cld
  1135.          rep movsb
  1136.          mov ax,0A0Dh         ; CR und LF anhängen
  1137.          stosw
  1138.          mov cs:OutputFileOff,di
  1139.  
  1140.          pop cx,di,si,es
  1141.          ret
  1142.  
  1143. ; ----------------------------
  1144. ; WriteOutputFileBuffer
  1145. ;
  1146. ; Funktion: Schreibt den Puffer in die Ausgabe-Datei
  1147. ;
  1148. ; Ausgabe:  CF = 0 ->> okay
  1149. ;           CF = 1 ->> Fehler
  1150. ;                      AX = Fehlernummer
  1151. ;
  1152. WriteOutputFileBuffer:
  1153.          push ds,dx,bx
  1154.  
  1155.          lds cx,cs:OutputFileOff
  1156.          xor dx,dx
  1157.                               ; DS:DX -> Puffer
  1158.                               ; CX = Anzahl Zeichen im Puffer
  1159.          mov bx,cs:OutputFileHandle
  1160.          mov ah,040h
  1161.          int 021h
  1162.  
  1163.          pop bx,dx,ds
  1164.          ret
  1165.  
  1166. ; ----------------------------
  1167. ; Zeigeanzahl
  1168. ;
  1169. ; Funktion: Ausgabe der Anzahl Elemente auf dem BasedHeap
  1170. ;
  1171. ; Eingabe:  ES = BasedHeap-Segment
  1172. ;
  1173. ZeigeAnzahl:
  1174.          mov di,offset Lines1Msg
  1175.          mov ax,es:[BHeapUserData1]
  1176.  
  1177.          push es
  1178.          push ds
  1179.          pop es
  1180.          call Konvert_AX_To_Dezstring
  1181.          pop es
  1182.  
  1183.          Write_String Lines1Msg
  1184.  
  1185.          ret
  1186.  
  1187. ; ----------------------------
  1188. ; ShowBasedHeapData
  1189. ;
  1190. ; Funktion: Ausgabe der Daten des BasedHeaps
  1191. ;
  1192. ; Bes.:     Falls ein Fehler auftritt, wird das Programm beendet.
  1193. ;
  1194. ;
  1195. DataMsg  db 'Daten des BasedHeaps: '
  1196.          db CR,LF
  1197.          db 'freier Speicher: '
  1198. m2       db                  '_____, größter freier Block: '
  1199. m3       db                                               '_____, ('
  1200. m4       db                                                       '_____ freie Blöcke)'
  1201.          db CR,LF
  1202.          db 'Länge des belegten Teils: '
  1203. m5       db                           '_____'
  1204.          db CR,LF
  1205.          db '(Segment: '
  1206. m6       db           '____h, Länge in Paragraphen: '
  1207. m7       db                                        '____h)'
  1208.          db CR,LF
  1209.          db CR,LF
  1210. GETLENGTH DataMsg
  1211.  
  1212. ShowBasedHeapData:
  1213.          push es,di,ax
  1214.  
  1215.          mov es,BHeapSeg
  1216.          mov ax,es
  1217.          dec ax
  1218.          mov es,ax
  1219.          mov ax,es:[03h]       ; AX = L(Speicherblock des BasedHeaps)
  1220.  
  1221.          mov es,cs
  1222.          mov di,offset m7
  1223.          call Konvert_AX_To_Hexstring
  1224.  
  1225.          mov ax,BHeapSeg      ; AX = Segment des BasedHeaps
  1226.          mov di,offset m6
  1227.          call Konvert_AX_To_Hexstring
  1228.  
  1229.          mov es,BHeapSeg
  1230.          call GetBHeapMemAvail
  1231.          call CheckBasedHeapError
  1232.          jc >l8
  1233.  
  1234.          mov es,cs
  1235.  
  1236.          mov di,offset m4     ; AX = Anzahl freier Blöcke
  1237.          call Konvert_AX_TO_Dezstring
  1238.  
  1239.          mov ax,cx            ; AX = größter freier Block
  1240.          mov di,offset m3
  1241.          call Konvert_AX_To_Dezstring
  1242.  
  1243.          mov ax,dx            ; AX = max. freier Speicher
  1244.          mov di,offset m2
  1245.          call Konvert_AX_To_Dezstring
  1246.  
  1247.          mov es,BHeapSeg
  1248.          call GetMaxBheapPointer
  1249.          call CheckBasedHeapError
  1250.          jc >l8
  1251.  
  1252.          mov es,cs            ; AX = Länge des belegten Teils
  1253.          mov di,offset m5
  1254.          call Konvert_AX_To_Dezstring
  1255.  
  1256.          Write_String DataMsg
  1257.          clc
  1258. l8:
  1259.          pop ax,di,es
  1260.          ret
  1261.  
  1262. ; ----------------------------
  1263. ; CheckBasedHeapError
  1264. ;
  1265. ; Funktion: Ermitteln der zu einer Fehlernummer
  1266. ;           gehörenden Fehlermeldung
  1267. ;
  1268. ; Eingabe:  AX = Fehlercode der Routine
  1269. ;           CF = CF der Routine
  1270. ;
  1271. ; Bes.:     Im falle eines Fehler springt die Routine direkt zum
  1272. ;           Label ErrorEnde1
  1273. ;           (mit: DX = Offset der Fehlermeldung
  1274. ;                 CX = Länge der Fehlermeldung)
  1275. ;
  1276.  
  1277. ; Fehlermeldungen
  1278. ; ---------------
  1279. BasedHeapErrorMsg1 db '*** Verwaltungsstrukturen des BasedHeaps sind defekt!'
  1280. BasedHeapErrorMsg2 db '*** Falscher Zeiger angegeben!'
  1281. BasedHeapErrorMsg3 db '*** Falscher Zeiger für einen freien Block angegeben!'
  1282. BasedHeapErrorMsg4 db '*** Falsche Größe für den BasedHeap angegeben!'
  1283. BasedHeapErrorMsg5 db '*** Keine weiteren Blocks vorhanden!'
  1284. BasedHeapErrorMsg6 db '*** Freizugebender Block ist schon frei!'
  1285. BasedHeapErrorMsg7 db '*** Kein freier Block in der angegebenen Größe mehr vorhanden!'
  1286. BasedHeapErrorMsg8 db '*** Reparatur des BasedHeaps gelungen!'
  1287. BasedHeapErrorMsgU db '*** DOS-Fehler, Fehlernummer: '
  1288. UErrorNumber       db                             '____h'
  1289.  
  1290. BasedHeapErrorMsgL db 0       ; Dummy-Eintrag
  1291.  
  1292. ; Tabelle der Fehlernummern und Fehlermeldungen
  1293. ; ---------------------------------------------
  1294.  
  1295.                      ; Fehlernummern         Offset der Fehlermeldung
  1296.                      ; -----------------------------------------------
  1297. BasedHeapErrorTable dw BHeapFatalError     , Offset BasedHeapErrorMsg1
  1298.                     dw BHeapPointerError   , Offset BasedHeapErrorMsg2
  1299.                     dw BHeapFPointerError  , Offset BasedHeapErrorMsg3
  1300.                     dw BHeapLengthError    , Offset BasedHeapErrorMsg4
  1301.                     dw BHeapNoMoreBlocks   , Offset BasedHeapErrorMsg5
  1302.                     dw BHeapFreeBlError    , Offset BasedHeapErrorMsg6
  1303.                     dw BHeapMemoryError    , Offset BasedHeapErrorMsg7
  1304.                     dw BHeapRepaired       , Offset BasedHeapErrorMsg8
  1305.                               ; Eintrag für unbekannte Fehlercodes
  1306. BasedHeapUnknownErr dw 0                   , Offset BasedHeapErrorMsgU
  1307.                               ; Eintrag für die Ermittlung der Länge
  1308.                               ; der letzten Fehlermeldung
  1309.                     dw 0                   , Offset BasedHeapErrorMsgL
  1310.  
  1311. CheckBasedHeapError:
  1312.          jnc ret              ; CF = 0 ->> kein Fehler aufgetreten
  1313.  
  1314.          push si,ds,ax        ; CF = 1 ->> Fehler aufgetreten,
  1315.                               ;            Offset der Fehlermeldung ermitteln
  1316.          mov ds,cs            ; DS = CS
  1317.          mov si,offset BasedHeapErrorTable
  1318.                               ; DS:SI -> Fehlertabelle
  1319.  
  1320.                               ; Eintrag für unbekannte Fehlercodes korrigieren
  1321.          mov BasedHeapUnknownErr,ax
  1322.          push es,di,ax
  1323.          mov di,offset UErrorNumber
  1324.          mov es,cs
  1325.          call Konvert_AX_To_Hexstring
  1326.          pop ax,di,es
  1327.  
  1328.          mov dx,ax            ; Fehlernummer nach DX
  1329. l0:
  1330.          lodsw
  1331.          cmp ax,dx
  1332.          lodsw
  1333.          jne l0
  1334.  
  1335.          mov dx,ax            ; DX = Offset der Fehlermeldung
  1336.          mov cx,[si+2]        ; CX = Offset der nächsten Fehlermeldung
  1337.          sub cx,dx            ; CX = Länge der Fehlermeldung
  1338.          stc
  1339.          pop ax,ds,si
  1340.          ret
  1341.  
  1342.