home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / lib4a86 / demo / mstack.dem < prev    next >
Text File  |  1992-02-16  |  15KB  |  497 lines

  1. ; ----------------------------
  2. ; MSTACK.DEM   - Demoprogramm für die Routinen aus MSTACK.LIB
  3. ;                (für den A86)
  4. ;
  5. ;                (c) Bernd Schemmer 1992
  6. ;                Letzter Update: 15.02.1992
  7. ;
  8. ; Übersetzen:
  9. ;  A86 MSTACK.DEM DEMOS.INC TO MSTACK.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 'MSTACK.DEM - Demoprogramm für die Routinen aus MSTACK.LIB' ,CR,LF
  23.       db '---------------------------------------------------------' ,CR,LF
  24.       db 'Das Programm erstellt eine neue Datei in der die Zeilen '  ,CR,LF
  25.       db 'der Eingabe-Datei in umgekehrter Reihenfolge stehen.'      ,CR,LF
  26.       db CR,LF
  27.       db 'Das Demo muß folgendermaßen aufgerufen werden:'           ,CR,LF
  28.       db '      MSTACK.COM eingabedatei ausgabedatei'                ,CR,LF
  29.       db CR,LF
  30.       db CR,LF,CR,LF
  31.       db 'Bitte eine Taste drücken (ESC = Programm-Abbruch) ...'     ,CR,LF
  32.       db CR,LF
  33. GETLENGTH logo
  34.  
  35.                               ; Fehlermeldungen
  36. MakeMsg ParamError,     '*** Fehlerhaften Parameter oder zuwenig Parameter angegeben.'
  37. MakeMsg MemoryError,    '*** Zuwenig freier Speicher.'
  38. MakeMsg OFileError,     '*** Fehler beim Öffnen der Ausgabe-Datei'
  39. MakeMsg IFileError,     '*** Fehler beim Lesen der Eingabe-Datei'
  40. MakeMsg IFileError1,    '*** Eingabe-Datei ist zu groß'
  41.  
  42.                               ; Meldungen
  43. MakeMsg ReadMsg,        '--- Lese die Eingabe-Datei ...'
  44. MakeMsg InitMsg,        '--- Richte den Stack ein ...'
  45. MakeMsg ProceedMsg,     '--- Bearbeite die Eingabe-Datei ...'
  46. MakeMsg WriteMsg,       '--- Schreibe die Zeilen in die Ausgabe-Datei ...'
  47. MakeMsg Lines1Msg,      '_____ Elemente auf dem Stack.'
  48.  
  49.                               ; Variablen
  50.  
  51.                               ; Puffer zum Lesen der Zeilen der Eingabe-Datei
  52. LineBuffer         db 0,260xD dup 20h
  53.  
  54. OutputFileHandle   dw 0       ; Handle der Ausgabe-Datei
  55. InputFileHandle    dw 0       ; Handle der Eingabe-Datei
  56. InputFileLength    dw 0       ; Größe der Eingabe-Datei
  57.  
  58. InputFileOff       dw 0       ; Pufferzeiger für die Eingabe-Datei
  59. InputFileSeg       dw 0       ; Segment des Speicherblocks zum Lesen der
  60.                               ; Eingabe-Datei
  61.  
  62. ; ----------------------------
  63. start:
  64.          call ShowLogoAndAsk  ; Logo ausgeben, Speicherblock verkleinern
  65.                               ; und Taste lesen
  66. ; ----------------------------
  67.  
  68.          Write_String ReadMsg ; Ein- und Ausgabe-Dateien eröffnen
  69.          call OpenInAndOutputFiles
  70.          if c jmp ErrorEnde1
  71.  
  72. ; ----------------------------
  73.          Write_String InitMsg ; Stack einrichten
  74.  
  75.                               ; Speicher für den Stack anfordern
  76.          mov bx,1000h         ; 1 Segment
  77.          mov ah,048h
  78.          int 021h
  79.          jnc >l1              ; 1 Segment kriegen wir nicht,
  80.          mov ah,048h          ; nehmen wir was wir kriegen können
  81.          int 021h
  82.          call CheckMStackError
  83.          if c jmp ErrorEnde1
  84. l1:
  85.          mov es,ax            ; ES = Segment des Speicherblocks
  86.          mov cx,bx
  87.          shl cx,1
  88.          shl cx,1
  89.          shl cx,1
  90.          shl cx,1
  91.          or cx,cx
  92.          if z mov cx,0FFFFh   ; CX = Größe für den Stack in Byte
  93.  
  94.          call InitMStack      ; Stack einrichten
  95.          call CheckMStackError
  96.          if c jmp ErrorEnde1
  97.  
  98. ; ----------------------------
  99.                               ; Zeilen auf den Stack schreiben
  100.          Write_String ProceedMsg
  101.          call ProceedLines
  102.          if c jmp ErrorEnde1
  103.  
  104.          call GetMStackStatistik_A
  105.          call CheckMStackError
  106.          if c jmp ErrorEnde1
  107.          call ZeigeAnzahl
  108.  
  109. ; ----------------------------
  110.                               ; und Zeilen in die Ausgabe-Datei schreiben
  111.          Write_String WriteMsg
  112.          call WriteLines
  113.          if c jmp ErrorEnde1
  114.  
  115.          mov al,0
  116.          jmp SHORT Ende
  117. ; ----------------------------
  118.                               ; DX = Offset einer Fehlermeldung
  119.                               ; CX = Länge der Fehlermeldung
  120. ErrorEnde1:
  121.          call ShowCR_LF
  122.          call OutputMsg       ; Fehlermeldung ausgeben
  123.          call ShowCR_LF
  124.  
  125. ErrorEnde:
  126.          mov al,0FFh
  127. Ende:
  128.          call CloseFiles      ; Dateien schliessen
  129.          EndProcess
  130.  
  131. ; ----------------------------
  132. ; ProceedLines
  133. ;
  134. ; Funktion: Sichert die Zeilen auf den Stack
  135. ;
  136. ; Ausgabe:  CF = 1 ->> okay
  137. ;           CF = 1 ->> Fehler
  138. ;                      DX -> Fehlermeldung
  139. ;                      CX = Länge der Fehlermeldung
  140. ;
  141. ProceedLines:
  142.  
  143. ProceedLineLoop:
  144.          call GetNextLine     ; nächste Zeile ermitteln
  145.          jc ProceedLineLoopEnd          ; Dateiende erreicht
  146.  
  147.          mov si,offset LineBuffer
  148.          mov cl,[si]
  149.          xor ch,ch            ; CX = Länge der Meldung
  150.          inc si               ; DS:SI -> Meldung
  151.  
  152.          call WriteMStack_A   ; Zeile auf den Stack sichern
  153.          call CheckMStackError
  154.          jc ret
  155.          jmp ProceedLineLoop
  156.  
  157. ProceedLineLoopEnd:
  158.          clc
  159.          ret
  160.  
  161. ; ----------------------------
  162. ; WriteLines
  163. ;
  164. ; Funktion: Schreibt die Zeilen vom Stack in die Ausgabe-Datei
  165. ;
  166. ; Ausgabe:  CF = 1 ->> okay
  167. ;           CF = 1 ->> Fehler
  168. ;                      DX -> Fehlermeldung
  169. ;                      CX = Länge der Fehlermeldung
  170. ;
  171. WriteLines:
  172.  
  173. WriteLineLoop:
  174.          mov si,offset LineBuffer
  175.          mov cx,255xD
  176.                               ; DS:SI -> Puffer
  177.                               ; CX = Länge des Puffers
  178.          call ReadMStack_A
  179.          call CheckMStackError
  180.          jnc >l1
  181.                               ; Fehler aufgetreten
  182.          cmp ax,MStackIsEmpty ; erwarteter Fehler?
  183.          je WriteLineLoopEnd  ; ja, Stack ist leer
  184.          jmp >l8              ; nein, raus
  185. l1:
  186.          mov dx,si            ; DX -> Zeile
  187.                               ; CR und LF anhängen
  188.          add si,cx
  189.          mov w[si],LF by CR
  190.          inc cx
  191.          inc cx
  192.                               ; Zeile schreiben
  193.          mov bx,OutputFileHandle
  194.          mov ah,040h
  195.          int 021h
  196. l0:
  197.          call CheckMStackError
  198.          jnc WriteLineLoop
  199.          cmp ax,cx
  200.          je WriteLineLoop
  201.          mov ax,0FFFFh        ; Disk voll, Fehler 0FFFFh simulieren
  202.          stc
  203.          jmp l0
  204.                               ; Fehler beim Schreiben
  205. l8:
  206.          stc
  207.          ret
  208.  
  209. WriteLineLoopEnd:
  210.          clc
  211.          ret
  212.  
  213. ; ----------------------------
  214. ; Zeigeanzahl
  215. ;
  216. ; Funktion: Ausgabe der Anzahl Elemente auf dem Stack
  217. ;
  218. ; Eingabe:  AX = Anzahl Elemente auf dem Stack
  219. ;
  220. ZeigeAnzahl:
  221.          push es
  222.          push ds
  223.          pop es
  224.          mov di,offset Lines1Msg
  225.          call Konvert_AX_To_Dezstring
  226.          pop es
  227.  
  228.          Write_String Lines1Msg
  229.  
  230.          ret
  231.  
  232. ; ----------------------------
  233. ; CheckMStackError
  234. ;
  235. ; Funktion: Ermitteln der zu einer Fehlernummer der Routinen für die
  236. ;           Verwaltung des Stacks gehörenden Fehlermeldung
  237. ;
  238. ; Eingabe:  AX = Fehlernummer der Routine
  239. ;           CF = CF der Routine
  240. ;
  241. ; Ausgabe:  CF = 0 ->> kein Fehler
  242. ;                      kein Register verändert
  243. ;           CF = 1 ->> Fehler
  244. ;                      DX = Offset der Fehlermeldung
  245. ;                      CX = Länge der Fehlermeldung
  246. ;                      AX unverändert
  247. ;
  248.  
  249. ; Fehlermeldungen
  250. ; ---------------
  251. ErrorMsg1 db '*** Keine weitere Meldung auf dem Stack!'
  252. ErrorMsg2 db '*** Nicht mehr genug freier Speicher auf dem Stack!'
  253. ErrorMsg3 db '*** Falsche Größe für den Stack angegeben!'
  254. ErrorMsg4 db '*** Der Puffer ist für die nächste Meldung zu klein!'
  255. ErrorMsg5 db '*** Die Meldung ist zu lang!'
  256. ErrorMsg6 db '*** Gleichzeitiger Zugriff von mehreren Routinen auf den Stack nicht möglich!'
  257. ErrorMsgU db '*** Unbekannte Fehlernummer: ____h!'
  258. ErrorMsgL db 0       ; Dummy-Eintrag
  259.  
  260.                               ; Offset für die Ausgabe der Fehlernummer bei
  261.                               ; unbekannten Fehlercodes
  262. ErrorNrMsg EQU (Offset ErrorMsgU + 29)
  263.  
  264. ; Tabelle der Fehlernummern und Fehlermeldungen
  265. ; ---------------------------------------------
  266.  
  267.             ; Fehlernummern         Offset der Fehlermeldung
  268.             ; -----------------------------------------------
  269. ErrorTable dw MStackIsEmpty       , Offset ErrorMsg1
  270.            dw MStackIsFull        , Offset ErrorMsg2
  271.            dw MStackLengthError   , Offset ErrorMsg3
  272.            dw MStackBufferError   , Offset ErrorMsg4
  273.            dw MStackMessageError  , Offset ErrorMsg5
  274.            dw MStackAktivError    , Offset ErrorMsg6
  275.                      ; Eintrag für unbekannte Fehlernummern
  276. UnknownErr dw 0                   , Offset ErrorMsgU
  277.                      ; Eintrag für die Ermittlung der Länge
  278.                      ; der letzten Fehlermeldung
  279.            dw 0                   , Offset ErrorMsgL
  280.  
  281. CheckMStackError:
  282.          jnc ret              ; CF = 0 ->> kein Fehler aufgetreten
  283.  
  284.          push si,ds,ax        ; CF = 1 ->> Fehler aufgetreten,
  285.                               ;            Offset der Fehlermeldung ermitteln
  286.          mov ds,cs            ; DS = CS
  287.          mov si,offset ErrorTable
  288.                               ; DS:SI -> Fehlertabelle
  289.  
  290.          mov UnknownErr,ax    ; Eintrag für unbekannte Fehlernummern korrigieren
  291.  
  292.          push ax,di,es
  293.          mov es,cs
  294.          mov di,ErrorNrMsg
  295.          call Konvert_AX_To_Hexstring
  296.          pop es,di,ax
  297.  
  298.          mov dx,ax            ; Fehlernummer nach DX
  299. l0:
  300.          lodsw
  301.          cmp ax,dx
  302.          lodsw
  303.          jne l0
  304.  
  305.          mov dx,ax            ; DX = Offset der Fehlermeldung
  306.          mov cx,[si+2]        ; CX = Offset der nächsten Fehlermeldung
  307.          sub cx,dx            ; CX = Länge der Fehlermeldung
  308.          stc
  309.          pop ax,ds,si
  310.          ret
  311.  
  312. ; ----------------------------
  313. ; OpenInAndOutputFiles
  314. ;
  315. ; Funktion: Öffnet die Ein- und Ausgabe-Dateien und liest die Eingabe-Datei
  316. ;
  317. ; Ausgabe:  CF = 0 ->> okay
  318. ;           CF = 1 ->> Fehler
  319. ;                      DX = Offset der Fehlermeldung
  320. ;                      CX = Länge der Fehlermeldung
  321. ;
  322. OpenInAndOutputFiles:
  323.          mov bx,1000h         ; Speicher zum Lesen der Eingabe-Datei anfordern
  324.          mov ah,048h          ; 1 Segment
  325.          int 021h
  326.          jnc >l1
  327.                               ; Fehler, nicht genügend Speicher vorhanden
  328.          mov dx,offset MemoryError
  329.          mov cx,MemoryError_LENGTH
  330.          stc
  331.          ret
  332.  
  333. ; ------------------
  334. l1:
  335.          mov InputFileSeg,ax  ; Segment sichern
  336.  
  337.          mov si,080h          ; Parameter bearbeiten
  338.          lodsb
  339.          or al,al
  340.          jnz >l1
  341.                               ; Fehler: Keine Parameter angegeben
  342. ParameterError:
  343.          mov dx,offset ParamError
  344.          mov cx,ParamError_LENGTH
  345.          stc
  346.          ret
  347.  
  348. ; ------------------
  349. l1:
  350.          call GetFileName     ; Anfang des ersten Dateinamens suchen
  351.          jc ParameterError
  352.                               ; DS:DX -> erster Dateiname als ASCIIZ-String
  353. ; ------------------
  354.          mov ax,03D02h        ; Eingabe-Datei öffnen
  355.          int 021h
  356.          jnc >l1
  357. ; ------------------
  358. InputFileError:
  359.          mov dx,offset IFileError
  360.          mov cx,IFileError_LENGTH
  361.          stc
  362.          ret
  363. ; ------------------
  364. l1:
  365.          mov InputFileHandle,ax         ; Handle der Eingabe-Datei sichern
  366. ; ------------------
  367.          call GetFileName     ; Name der Ausgabe-Datei ermitteln
  368.          jc ParameterError
  369. ; ------------------
  370.                               ; Ausgabe-Datei anlegen
  371.          mov cx,0             ; CX = Standard-Attribte
  372.          mov ah,03Ch          ; Datei erstellen
  373.          int 021h
  374.          jnc >l1
  375. ; ------------------
  376. OutputFileError:
  377.          mov dx,offset OFileError
  378.          mov cx,OFileError_LENGTH
  379.          stc
  380.          ret
  381. ; ------------------
  382. l1:
  383.          mov OutputFileHandle,ax        ; Handle der Ausgabe-Datei sichern
  384. ; ------------------
  385.          mov ah,03Fh          ; und Eingabe-Datei lesen
  386.          mov cx,0FFF5h
  387.          mov bx,InputFileHandle
  388.          lds dx,InputFileOff  ; DS <> CS
  389.          int 021h
  390.          mov ds,cs            ; DS = CS
  391.          jc InputFileError
  392.          cmp ax,cx
  393.          jb >l1
  394. ; ------------------
  395. InputFileError1:
  396.          mov dx,offset IFileError1
  397.          mov cx,IFileError1_LENGTH
  398.          stc
  399.          ret
  400. ; ------------------
  401. l1:
  402.          mov InputFileLength,ax         ; Länge der Datei sichern
  403.          clc
  404.          ret
  405.  
  406. ; ----------------------------
  407. ; GetFileName
  408. ;
  409. ; Funktion: Ermittelt den nächsten Parameter und konvertiert ihn in
  410. ;           einen ASCIIZ-String
  411. ;
  412. ; Eingabe:  SI -> Ende des letzte Parameters
  413. ;
  414. ; Ausgabe:  CF = 0 ->> okay, DX -> Anfang des Parameters
  415. ;           CF = 1 ->> Fehler
  416. ;
  417. GetFileName:
  418. l0:                           ; Anfang des Parameters suchen
  419.          lodsb
  420.          cmp al,BLANK
  421.          je l0
  422.          cmp al,TAB
  423.          je l0
  424.          cmp al,CR
  425.          je >l8
  426. ; ------------------
  427.          lea dx,[si-1]        ; Anfang des Parameters gefunden
  428.  
  429. l1:                           ; Ende des Parameters suchen
  430.          lodsb
  431.          cmp al,BLANK
  432.          je >l2
  433.          cmp al,TAB
  434.          je >l2
  435.          cmp al,CR
  436.          je >l2
  437.          jmp l1
  438. l2:
  439.          mov b[si-1],0        ; Nullbyte eintragen
  440.          clc
  441.          ret
  442.  
  443. ; ------------------
  444. l8:
  445.          stc
  446.          ret
  447.  
  448. ; ----------------------------
  449. ; GetNextLine
  450. ;
  451. ; Funktion: Ermittelt die nächste Zeile der Eingabe-Datei aus dem Puffer
  452. ;
  453. ; Eingabe:  DS = CS
  454. ;
  455. ; Ausgabe:  CF = 0 ->> LineBuffer ist gefüllt
  456. ;           CF = 1 ->> EOF erreicht
  457. ;
  458. GetNextLine:
  459.          mov ax,InputFileOff
  460.          cmp ax,InputFileLength
  461.          jb >l1
  462.          stc                  ; EOF erreicht
  463.          ret
  464. l1:
  465.          push ds,es,si,di,cx
  466.  
  467.          mov es,cs            ; ES = CS
  468.          mov di,offset LineBuffer
  469.                                         ; ES:DI -> Längenzähler des Zeilenpuffers
  470.          xor cx,cx                      ; CX = Längenzähler
  471.          lds si,cs:InputFileOff         ; DS:SI -> akt. Position im Puffer
  472.  
  473.          push di
  474.          inc di               ; ES:DI -> Zeilenpuffer
  475. l0:
  476.          cmp cl,255xD         ; max. Zeilenlänge erreicht?
  477.          je >l1               ; ja
  478.  
  479.          lodsb
  480.          cmp al,CR
  481.          je >l1               ; Zeilenende erreicht
  482.          stosb                ; Zeichen übernehmen
  483.          inc cx               ; Zähler korrigieren
  484.          jmp l0
  485. l1:
  486.          cmp b[si],LF
  487.          if e inc si          ; LF am Zeilenende überlesen
  488.          pop di
  489.          mov es:[di],cl       ; Länge der Zeile eintragen
  490.  
  491.          mov cs:InputFileOff,si         ; und Pufferzeiger sichern
  492. l9:
  493.          clc
  494.          pop cx,di,si,es,ds
  495.          ret
  496.  
  497.