home *** CD-ROM | disk | FTP | other *** search
- ; ----------------------------
- ; QUEUES.DEM - Demoprogramm für die Routinen aus QUEUES.BIB
- ; (und implizit: MQUEUE.LIB, SQUEUE.LIB und MEMORY.LIB)
- ; (für den A86)
- ;
- ; (c) Bernd Schemmer 1992
- ; Letzter Update: 15.02.1992
- ;
- ; Übersetzen:
- ; A86 MQUEUE.DEM DEMOS.INC TO MQUEUE.COM
- ;
- ; Hinweis: Die Environment-Variable 'A86' muß den Dateinamen 'MACROS.MAC'
- ; enthalten und die .LIB-Dateien müssen über die Datei A86.LIB
- ; erreichbar sein.
- ;
- ; ---------------------------
-
- jmp start
-
- ; ----------------------------
- ; Meldungen und Fehlermeldungen
- logo db CR,LF
- db 'QUEUES.DEM - Demoprogramm für die Routinen aus QUEUES.BIB' ,CR,LF
- db '----------------------------------------------------------',CR,LF
- db 'Das Programm führt folgende Arbeitsschritte durch: ',CR,LF
- db '1. Lesen der Eingabe-Datei ',CR,LF
- db '2. Einrichten von 2 meldungsorientierten Queuen und ',CR,LF
- db ' 1 streamorientierten Queue ',CR,LF
- db '3. Verteilen der Zeilen der Eingabe-Datei auf die 3 Queuen',CR,lF
- db ' nach folgenden Algorithmus: ',CR,LF
- db ' Alle Zeilen, die mit einem Semikolon beginnen kommen ',CR,LF
- db ' in die erste Queue, alle weiteren Zeilen, die ein Semi-',CR,LF
- db ' kolon enthalten kommen in die zweite Queue und alle ',CR,LF
- db ' restlichen Zeilen kommen in die dritte Queue. ',CR,LF
- db '4. Schreiben der 3 Queuen in die Ausgabe-Datei ',CR,LF
- db CR,LF
- db 'Das Demo muß folgendermaßen aufgerufen werden:' ,CR,LF
- db ' QUEUES.COM eingabedatei ausgabedatei' ,CR,LF
- db CR,LF,CR,LF
- db 'Bitte eine Taste drücken (ESC = Programm-Abbruch) ...' ,CR,LF
- db CR,LF
- GETLENGTH logo
- ; Meldungen
- MakeMsg ReadMsg, '--- Lese die Eingabe-Datei ...'
- MakeMsg Open1Msg, '--- Öffne die 1. Queue ...'
- MakeMsg Open2Msg, '--- Öffne die 2. Queue ...'
- MakeMsg Open3Msg, '--- Öffne die 3. Queue ...'
- MakeMsg ProceedMsg, '--- Verteile die Zeilen auf die Queuen ...'
- MakeMsg Write1Msg, '--- Schreibe die 1. Queue in die Ausgabe-Datei ...'
- MakeMsg Write2Msg, '--- Schreibe die 2. Queue in die Ausgabe-Datei ...'
- MakeMsg Write3Msg, '--- Schreibe die 3. Queue in die Ausgabe-Datei ...'
- MakeMsg Close1Msg, '--- Schliesse die Queue 1 ...'
- MakeMsg Close2Msg, '--- Schliesse die Queue 2 ...'
- MakeMsg Close3Msg, '--- Schliesse die Queue 3 ...'
-
- ; Fehlermeldungen
- MakeMsg ParamError, '*** Fehlerhaften Parameter oder zuwenig Parameter angegeben.'
- MakeMsg MemoryError, '*** Zuwenig freier Speicher.'
- MakeMsg OFileError, '*** Fehler beim Öffnen der Ausgabe-Datei'
- MakeMsg IFileError, '*** Fehler beim Lesen der Eingabe-Datei'
- MakeMsg IFileError1, '*** Eingabe-Datei ist zu groß'
- MakeMsg WriteFileError, '*** Fehler beim Schreiben der Ausgabe-Datei.'
- MakeMsg ReadFileError, '*** Fehler beim Lesen der Datei.'
- MakeMsg OutputError, '*** Fehler beim Schreiben in die Ausgabe-Datei.'
-
-
- OutputFileHandle dw 0 ; Handle der Ausgabe-Datei
- InputFileHandle dw 0 ; Handle der Eingabe-Datei
- InputFileLength dw 0 ; Größe der Eingabe-Datei
-
- InputFileOff dw 0 ; Pufferzeiger für die Eingabe-Datei
- InputFileSeg dw 0 ; Segment des Speicherblocks zum Lesen der
- ; Eingabe-Datei
-
- Queue1Handle dw 0 ; Handles für die Queuen
- Queue2Handle dw 0
- Queue3Handle dw 0
-
- ; Puffer für die Zeilen
- LineBuffer db 0,257 dup 20h
-
- MaxQueueHandles EQU 05h ; das Demo benötigt max. 3 Queuen
-
- ; ----------------------------
- start:
- call ShowLogoAndAsk ; Logo ausgeben, Speicherblock verkleinern
- ; und Taste lesen
- ; ----------------------------
- l2:
- Write_String ReadMsg
-
- ; Ein- und Ausgabe-Dateien eröffnen
- call OpenInAndOutputFiles
- IF c jmp ErrorEnde1 ; Fehler!
-
- ; ----------------------------
- ; Größe für die 3 Queuen berechnen
- mov bx,0FFFFh
- call GetMemoryBlock
- cmp ax,08
- je >l1
- stc
- call CheckQueueError
- if c jmp ErrorEnde1
- l1:
- mov ax,bx ; AX = freier Speicher in Paragraphen
- mov cx,0FFFFh ; CX = 1 Segment in Byte
- cmp ax,3000h
- jae >l1 ; 1 Segment pro Queue ist möglich
- shl ax,1
- shl ax,1 ; AX = (freier Speicher in Byte) / 4
- mov cx,ax ; CX = Größe für eine Queue in Byte
- l1:
-
- ; ----------------------------
- push cx
- Write_String Open1Msg
- ; Öffnen der ersten Queue (meldungsorientiert)
- mov ax,01h
- call OpenQueue
- call CheckQueueError
- if c jmp ErrorEnde1
- mov Queue1Handle,bx ; Handle der Queue sichern
- pop cx
- ; ----------------------------
- push cx
- Write_String Open2Msg
- ; Öffnen der zweiten Queue (meldungsorientiert)
- mov ax,01h
- call OpenQueue
- call CheckQueueError
- if c jmp ErrorEnde1
- mov Queue2Handle,bx ; Handle der Queue sichern
- pop cx
-
- ; ----------------------------
- Write_String Open3Msg
- ; Öffnen der dritten Queue (streamorientiert)
- mov ax,0h
- call OpenQueue
- call CheckQueueError
- if c jmp ErrorEnde1
- mov Queue3Handle,bx ; Handle der Queue sichern
-
- ; ----------------------------
-
- call ShowQueueData
- if c jmp ErrorEnde1
-
- ; ----------------------------
- Write_string ProceedMsg
-
- mov B PunktZaehler,0
-
- ReadLineLoop:
- call LaufzeitAnzeige
-
- call GetNextLine ; Zeile lesen
- jc ReadLineLoopEnd ; EOF erreicht
-
- mov cl,LineBuffer
- xor ch,ch ; CX = Länge der Zeile
- lea si,LineBuffer+1 ; DS:SI -> Zeile
- jcxz WriteQueue3 ; leere Zeilen kommen in die Queue3
-
- mov al,';'
- cmp b[si],al
- je WriteQueue1 ; Zeilen, die mit ';' beginnen kommen in
- ; die Queue1
- mov es,cs
- mov di,si
- push cx
- repne scasb
- pop cx
- je WriteQueue2 ; Zeilen, die nicht mit einem ';' beginnen,
- ; aber ein ';' enthalten kommen in
- ; die Queue2
-
- ; und alle anderen Zeilen kommen in Queue3
- WriteQueue3:
- mov bx,Queue3Handle
- ; CR und LF an die Zeile anhängen (falls möglich)
- cmp cx,255 ; CX = Zeilenlänge
- je >l1 ; nicht möglich
- push bx
- mov bx,cx
- mov w[si+bx],LF by CR
- pop bx
- inc cx,2 ; und Zeilenlänge erhöhen
- jmp >l1
-
- WriteQueue2:
- mov bx,Queue2Handle
- jmp >l1
-
- WriteQueue1:
- mov bx,Queue1Handle
- l1:
- ; DS:SI -> Meldung oder Byte für die Queue
- ; CX = Länge der Meldung oder Anzahl der Bytes
- ; BX = Handle der Queue
- call WriteQueue ; WriteQueue entscheidet selbst, ob es sich
- ; um eine meldungs- oder streamorientierte
- ; Queue handelt.
- call CheckQueueError
- jnc ReadLineLoop
- jmp ErrorEnde1
-
- ; ------------------
- ReadLineLoopEnd:
-
- mov B PunktZaehler,0
- ; Dateiende erreicht
- call ShowCR_LF
-
- call ShowQueueData
- if c jmp ErrorEnde1
-
- ; ----------------------------
- ; 1. Queue ausgeben
- Write_String Write1Msg
-
- l00:
- mov bx,Queue1Handle
- mov cx,255
- mov si,offset LineBuffer+1
- call ReadQueue
- call CheckQueueError
- jnc >l1
- call OutputMsg
- call ShowCR_LF
- jmp >l2 ; nächste Queue
-
- l1:
- ; Zeile schreiben
- mov bx,OutputFileHandle
- mov dx,offset LineBuffer+1
- mov ah,040h
- int 021h
- call CheckQueueError
- if c jmp ErrorEnde1
-
- mov dx,offset CR_LF ; CR_LF anhängen
- mov cx,CR_LF_Length
- mov ah,040h
- int 021h
- call CheckQueueError
- jnc l00
- jmp ErrorEnde1
-
- ; ----------------------------
- l2:
- Write_String Write2Msg
- ; 2. Queue ausgeben
- l00:
- mov bx,Queue2Handle
- mov cx,255
- mov si,offset LineBuffer+1
- call ReadQueue
- call CheckQueueError
- jnc >l1
- call OutputMsg
- call ShowCR_LF
- jmp >l2 ; nächste Queue
- l1:
- ; Zeile schreiben
- mov bx,OutputFileHandle
- mov dx,offset LineBuffer+1
- mov ah,040h
- int 021h
- call CheckQueueError
- if c jmp ErrorEnde1
-
- mov dx,offset CR_LF ; CR_LF anhängen
- mov cx,CR_LF_Length
- mov ah,040h
- int 021h
- call CheckQueueError
- jnc l00
- jmp ErrorEnde1
-
- ; ----------------------------
- l2:
- Write_String Write3Msg
- ; 3. Queue ausgeben
- l00:
- mov bx,Queue3Handle
- mov cx,200
- mov si,offset LineBuffer+1
- call ReadQueue
- call CheckQueueError
- jnc >l1
- call OutputMsg
- call ShowCR_LF
- jmp >l2 ; nächste Queue
- l1:
- ; Bytes schreiben
- mov bx,OutputFileHandle
- mov dx,offset LineBuffer+1
- mov ah,040h
- int 021h
- call CheckQueueError
- jnc l00
- jmp ErrorEnde1
-
- ; ----------------------------
- l2:
- call ShowQueueData
- if c jmp ErrorEnde1
-
- ; Schliesse die Queuen
- Write_String Close1Msg
-
- mov bx,Queue1Handle
- call CloseQueue
- call CheckQueueError
- jc ErrorEnde1
-
- Write_String Close2Msg
-
- mov bx,Queue2Handle
- call CloseQueue
- call CheckQueueError
- jc ErrorEnde1
-
- Write_String Close3Msg
-
- mov bx,Queue3Handle
- call CloseQueue
- call CheckQueueError
- jc ErrorEnde1
-
- call GetMaxQueues
- call CheckQueueError
- jc ErrorEnde1
-
- call ShowQueueStatistik
-
- jmp SHORT Ende
- ; ------------------
-
- ErrorEnde1:
- push cx,dx
- call ShowCR_LF
- pop dx,cx
- ; Fehlerausgang
- ; DX = Offset der Meldung
- ; CX = Länge der Meldung
- call OutputMsg
- call ShowCR_LF
-
- ErrorEnde:
- mov al,0FFh
- Ende:
- ; Ein- und Ausgabedateien schliessen
- call CloseFiles
-
- EndProcess
-
-
- ; ----------------------------
- ; ShowQueueData
- ;
- ; Funktion: Ausgabe der Daten aller Queuen und der globalen Daten
- ;
- ShowQueueData:
- mov bx,Queue1Handle
- call GetQueueData ; Daten der Queue ausgeben
- call CheckQueueError
- jc ret
- call ShowMHeader ; 1. Queue ist meldungsorientiert
-
- mov bx,Queue2Handle
- call GetQueueData ; Daten der Queue ausgeben
- call CheckQueueError
- jc ret
- call ShowMHeader ; 2. Queue ist meldungsorientiert
-
- mov bx,Queue3Handle
- call GetQueueData ; Daten der Queue ausgeben
- call CheckQueueError
- jc ret
- call ShowSHeader ; 1. Queue ist streamorientiert
-
- call GetMaxQueues ; und die globalen Daten ausgeben
- call CheckQueueError
- jc ret
- call ShowQueueStatistik
- clc
- ret
-
- ; ----------------------------
- ; ShowQueueStatistik
- ;
- ; Funktion: Ausgabe der globalen Werte
- ;
- ; Eingabe: Register wie von der Routine GetMaxQueues geliefert
- ;
- QueuesStatMsg db CR,LF
- db 'Daten der Queue-Verwaltung: '
- db CR,LF
- db 'Anzahl möglicher Queuen: '
- m1 db '_____,'
- db CR,LF
- db 'Anzahl geöffneter Queuen: '
- m2 db '_____'
- db CR,LF
- db 'davon streamorientiert: '
- m3 db '___, '
- db 'und meldungsorientiert: '
- m4 db '___'
- db CR,LF
- GETLENGTH QueuesStatMsg
-
- ShowQueueStatistik:
- push es
- mov es,cs
-
- push ax
- mov di,offset m4
- call Konvert_AL_To_Dezstring
- pop ax
-
- mov al,ah
- mov di,offset m3
- call Konvert_AL_To_Dezstring
-
- mov ax,cx
- mov di,offset m2
- call Konvert_AX_To_Dezstring
-
- mov ax,dx
- mov di,offset m1
- call Konvert_AX_To_Dezstring
-
- write_string QueuesStatMsg
-
- pop es
- ret
-
- ; ----------------------------
- ; ShowMHeader
- ;
- ; Funktion: Ausgabe der globalen Daten einer meldungsorientierten Queue
- ;
- ; Eingabe: AX, DX, CX und DI wie von der Routine GetQueueData geliefert
- ;
- MHeaderMsg db CR,LF
- db 'Daten der meldungs-orientierten Queue bei '
- m3 db '____h: '
- db CR,LF
- db 'Gesamtspeicher: '
- m4 db '_____, freier Speicher: '
- m5 db '_____, '
- m6 db '_____ Meldungen in der Queue'
- db CR,LF
- GETLENGTH MHeaderMsg
-
- ShowMHeader:
- push es
- mov es,cs
-
- push ax
- mov ax,di
- mov di,offset m3
- call Konvert_AX_To_Hexstring
- pop ax
-
- mov di,offset m6
- call Konvert_AX_To_Dezstring
-
- mov di,offset m4
- mov ax,dx
- call Konvert_AX_To_Dezstring
-
- mov di,offset m5
- mov ax,cx
- call Konvert_AX_To_Dezstring
-
- Write_String MHeaderMsg
-
- pop es
- ret
-
- ; ----------------------------
- ; ShowSHeader
- ;
- ; Funktion: Ausgabe der globalen Daten einer streamorientierten Queue
- ;
- ; Eingabe: AX, DX, CX und DI wie von der Routine GetQueueData geliefert
- ;
- SHeaderMsg db CR,LF
- db 'Daten der stream-orientierten Queue bei '
- m3 db '____h: '
- db CR,LF
- db 'Gesamtspeicher: '
- m4 db '_____, freier Speicher: '
- m5 db '_____, '
- db 'belegter Speicher: '
- m6 db '_____',CR,LF
- GETLENGTH SHeaderMsg
-
- ShowSHeader:
- push es
- mov es,cs
-
- push ax
- mov ax,di
- mov di,offset m3
- call Konvert_AX_To_Hexstring
- pop ax
-
- mov di,offset m6
- call Konvert_AX_To_Dezstring
-
- mov di,offset m4
- mov ax,dx
- call Konvert_AX_To_Dezstring
-
- mov di,offset m5
- mov ax,cx
- call Konvert_AX_To_Dezstring
-
- Write_String SHeaderMsg
-
- pop es
- ret
-
- ; ----------------------------
- ; CheckQueueError
- ;
- ; Funktion: Ermitteln der zu einer Fehlernummer der Routinen für die
- ; Verwaltung der Queuen gehörenden Fehlermeldung
- ;
- ; Eingabe: AX = Fehlercode der Routine
- ; CF = CF der Routine
- ;
- ; Ausgabe: CF = 0 ->> kein Fehler
- ; kein Register verändert
- ; CF = 1 ->> Fehler
- ; DX = Offset der Fehlermeldung
- ; CX = Länge der Fehlermeldung
- ; AX unverändert
- ;
- ; Fehlermeldungen der Routine aus
- ; MQUEUE.LIB
- QueueErrorMsg1 db '*MQ* Keine weitere Meldung in der Queue!'
- QueueErrorMsg2 db '*MQ* Nicht mehr genügend freier Speicher in der Queue!'
- QueueErrorMsg3 db '*MQ* Falsche Größe für die Queue angegeben!'
- QueueErrorMsg4 db '*MQ* Puffer ist für die nächste Meldung zu klein!'
- QueueErrorMsg5 db '*MQ* Angegebene Meldung ist zu lang!'
- QueueErrorMsg6 db '*MQ* Gleichzeitiger Zugriff von mehreren Routinen nicht erlaubt!'
-
- ; Fehlermeldungen der Routine aus
- ; SQUEUE.LIB
- QueueErrorMsg7 db '*SQ* Kein weiteres Byte in der Queue!'
- QueueErrorMsg8 db '*SQ* Nicht mehr genügend freier Speicher in der Queue!'
- QueueErrorMsg9 db '*SQ* Falsche Größe für die Queue angegeben'
- QueueErrorMsg10 db '*SQ* Gleichzeitiger Zugriff von mehreren Routinen nicht erlaubt!'
-
- ; Fehlermeldungen der Routine aus
- ; MEMORY.LIB
- QueueErrorMsg11 db '*ME* Falsche Adresse angegeben!'
- QueueErrorMsg12 db '*ME* Falsche Blockgröße angegeben!'
- QueueErrorMsg13 db '*ME* Speicherblock ist frei!'
- QueueErrorMsg14 db '*ME* Speicherblock gehört DOS!'
- QueueErrorMsg15 db '*ME* Block ist kein Hauptblock!'
- QueueErrorMsg16 db '*ME* Falscher Name für den Block angegeben!'
- QueueErrorMsg17 db '*ME* Block nicht gefunden!'
-
- ; Fehlermeldungen der Routine aus
- ; QUEUES.LIB
- QueueErrorMsg18 db '*QS* Funktion wird von der Queue nicht unterstützt!'
- QueueErrorMsg19 db '*QS* Falsches Handle angegeben!'
- QueueErrorMsg20 db '*QS* kein freies Handle mehr vorhanden!'
-
- ; DOS-Fehlermdeldungen
- QueueErrorMsg21 db 'DOS: Fehlercode 07'
- QueueErrorMsg22 db 'DOS: Fehlercode 08'
- QueueErrorMsg23 db 'DOS: Fehlercode 09'
-
- QueueErrorMsgU db '*** Unbekannter Fehlercode: '
- UErrorCode db '____h!'
- QueueErrorMsgL db 0 ; Dummy-Eintrag
-
- ; Tabelle der Fehlernummern und Fehlermeldungen
- ;
- ; Fehlernummer Offset der Fehlermeldung
- ; -----------------------------------------------
- QueueErrorTable dw MQueueIsEmpty , Offset QueueErrorMsg1
- dw MQueueIsFull , Offset QueueErrorMsg2
- dw MQueueLengthError , Offset QueueErrorMsg3
- dw MQueueBufferError , Offset QueueErrorMsg4
- dw MQueueMessageError , Offset QueueErrorMsg5
- dw MQueueAktivError , Offset QueueErrorMsg6
-
- dw SQueueIsEmpty , Offset QueueErrorMsg7
- dw SQueueIsFull , Offset QueueErrorMsg8
- dw SQueueLengthError , Offset QueueErrorMsg9
- dw SQueueAKtivError , Offset QueueErrorMsg10
-
- dw MemoryBlockError , Offset QueueErrorMsg11
- dw InvalidBlockLength , Offset QueueErrorMsg12
- dw BlockIsFree , Offset QueueErrorMsg13
- dw BlockBelongsToDOS , Offset QueueErrorMsg14
- dw BlockIsNoMainBlock , Offset QueueErrorMsg15
- dw InvalidBlockName , Offset QueueErrorMsg16
- dw BlockNotFound , Offset QueueErrorMsg17
-
- dw UnknownQSubFunction , Offset QueueErrorMsg18
- dw InvalidQUeueHandle , Offset QueueErrorMsg19
- dw NoMoreQueueHandles , Offset QueueErrorMsg20
-
- dw 007 , Offset QueueErrorMsg21
- dw 008 , Offset QueueErrorMsg22
- dw 009 , Offset QueueErrorMsg23
-
- ; Eintrag für unbekannte Fehlercodes
- QueueUnknownErr dw 0 , Offset QueueErrorMsgU
-
- ; Eintrag für die Ermittlung der Länge
- ; der letzten Fehlermeldung
- dw 0 , Offset QueueErrorMsgL
-
- CheckQueueError:
- jnc ret ; CF = 0 ->> kein Fehler aufgetreten
-
- push si,ds,ax ; CF = 1 ->> Fehler aufgetreten,
- ; Offset der Fehlermeldung ermitteln
- mov ds,cs ; DS = CS
- mov si,offset QueueErrorTable
- ; DS:SI -> Fehlertabelle
-
- ; Eintrag für unbekannte Fehlercodes korrigieren
- mov QueueUnknownErr,ax
-
- push es,di,ax
- mov es,cs
- mov di,offset UErrorCode
- call Konvert_AX_To_HexString
- pop ax,di,es
- mov dx,ax ; Fehlernummer nach DX
- l0:
- lodsw
- cmp ax,dx
- lodsw
- jne l0
-
- mov dx,ax ; DX = Offset der Fehlermeldung
- mov cx,[si+2] ; CX = Offset der nächsten Fehlermeldung
- sub cx,dx ; CX = Länge der Fehlermeldung
- stc
- pop ax,ds,si
- ret
-
- ; ----------------------------
- ; OpenInAndOutputFiles
- ;
- ; Funktion: Öffnet die Ein- und Ausgabe-Dateien und liest die Eingabe-Datei
- ;
- ; Ausgabe: CF = 0 ->> okay
- ; CF = 1 ->> Fehler
- ; DX = Offset der Fehlermeldung
- ; CX = Länge der Fehlermeldung
- ;
- OpenInAndOutputFiles:
- mov bx,1000h ; Speicher zum Lesen der Eingabe-Datei anfordern
- mov ah,048h ; 1 Segment
- int 021h
- jnc >l1
- ; Fehler, nicht genügend Speicher vorhanden
- mov dx,offset MemoryError
- mov cx,MemoryError_LENGTH
- stc
- ret
-
- ; ------------------
- l1:
- mov InputFileSeg,ax ; Segment sichern
-
- mov si,080h ; Parameter bearbeiten
- lodsb
- or al,al
- jnz >l1
- ; Fehler: Keine Parameter angegeben
- ParameterError:
- mov dx,offset ParamError
- mov cx,ParamError_LENGTH
- stc
- ret
-
- ; ------------------
- l1:
- call GetFileName ; Anfang des ersten Dateinamens suchen
- jc ParameterError
- ; DS:DX -> erster Dateiname als ASCIIZ-String
- ; ------------------
- mov ax,03D02h ; Eingabe-Datei öffnen
- int 021h
- jnc >l1
- ; ------------------
- InputFileError:
- mov dx,offset IFileError
- mov cx,IFileError_LENGTH
- stc
- ret
- ; ------------------
- l1:
- mov InputFileHandle,ax ; Handle der Eingabe-Datei sichern
- ; ------------------
- call GetFileName ; Name der Ausgabe-Datei ermitteln
- jc ParameterError
- ; ------------------
- ; Ausgabe-Datei anlegen
- mov cx,0 ; CX = Standard-Attribte
- mov ah,03Ch ; Datei erstellen
- int 021h
- jnc >l1
- ; ------------------
- OutputFileError:
- mov dx,offset OFileError
- mov cx,OFileError_LENGTH
- stc
- ret
- ; ------------------
- l1:
- mov OutputFileHandle,ax ; Handle der Ausgabe-Datei sichern
- ; ------------------
- mov ah,03Fh ; und Eingabe-Datei lesen
- mov cx,0FFF5h
- mov bx,InputFileHandle
- lds dx,InputFileOff ; DS <> CS
- int 021h
- mov ds,cs ; DS = CS
- jc InputFileError
- cmp ax,cx
- jb >l1
- ; ------------------
- InputFileError1:
- mov dx,offset IFileError1
- mov cx,IFileError1_LENGTH
- stc
- ret
- ; ------------------
- l1:
- mov InputFileLength,ax ; Länge der Datei sichern
- clc
- ret
-
- ; ----------------------------
- ; GetFileName
- ;
- ; Funktion: Ermittelt den nächsten Parameter und konvertiert ihn in
- ; einen ASCIIZ-String
- ;
- ; Eingabe: SI -> Ende des letzte Parameters
- ;
- ; Ausgabe: CF = 0 ->> okay, DX -> Anfang des Parameters
- ; CF = 1 ->> Fehler
- ;
- GetFileName:
- l0: ; Anfang des Parameters suchen
- lodsb
- cmp al,BLANK
- je l0
- cmp al,TAB
- je l0
- cmp al,CR
- je >l8
- ; ------------------
- lea dx,[si-1] ; Anfang des Parameters gefunden
-
- l1: ; Ende des Parameters suchen
- lodsb
- cmp al,BLANK
- je >l2
- cmp al,TAB
- je >l2
- cmp al,CR
- je >l2
- jmp l1
- l2:
- mov b[si-1],0 ; Nullbyte eintragen
- clc
- ret
-
- ; ------------------
- l8:
- stc
- ret
-
- ; ----------------------------
- ; GetNextLine
- ;
- ; Funktion: Ermittelt die nächste Zeile der Eingabe-Datei aus dem Puffer
- ;
- ; Eingabe: DS = CS
- ;
- ; Ausgabe: CF = 0 ->> LineBuffer ist gefüllt
- ; CF = 1 ->> EOF erreicht
- ;
- GetNextLine:
- mov ax,InputFileOff
- cmp ax,InputFileLength
- jb >l1
- stc ; EOF erreicht
- ret
- l1:
- push ds,es,si,di,cx
-
- mov es,cs ; ES = CS
- mov di,offset LineBuffer
- ; ES:DI -> Längenzähler des Zeilenpuffers
- xor cx,cx ; CX = Längenzähler
- lds si,cs:InputFileOff ; DS:SI -> akt. Position im Puffer
-
- push di
- inc di ; ES:DI -> Zeilenpuffer
- l0:
- cmp cl,255xD ; max. Zeilenlänge erreicht?
- je >l1 ; ja
-
- lodsb
- cmp al,CR
- je >l1 ; Zeilenende erreicht
- stosb ; Zeichen übernehmen
- inc cx ; Zähler korrigieren
- jmp l0
- l1:
- cmp b[si],LF
- if e inc si ; LF am Zeilenende überlesen
- pop di
- mov es:[di],cl ; Länge der Zeile eintragen
-
- mov cs:InputFileOff,si ; und Pufferzeiger sichern
- l9:
- clc
- pop cx,di,si,es,ds
- ret
-
-