home *** CD-ROM | disk | FTP | other *** search
-
- * Maxon C++ Library:
- * Modul "buffers"
- * Jens Gelhar 19.03.93, 20.02.94
-
- xdef _setvbuf,setvbuf__P06streamPciUi
- xdef _setbuf,setbuf__P06streamPc
- xdef _fflush,fflush__P06stream
- xdef _EXIT_2_Flush_Buffers_Yes_that_must_be
-
- xref _DosBase,__Readfile__NoBuf,__Writefile__NoBuf
- xref _std__err,_std__out
- xref ___Filelist
-
- ExecBase = 4
-
- AllocMem = -198
- FreeMem = -210
-
- Seek = -66
-
- LF = 10
-
- str_mode = 6
- str_error = 7
- str_bufptr = 8
-
- buf_size = 4
- buf_fill = 6
- buf_pos = 8
- buf_mode = 10
- buf_own = 11
- buf_read = 12
- buf_write = 16
- buf_flush = 20
- buf_close = 24
- buf_buf = 28
- buf_SizeOf = 32
-
- _setbuf:
- setbuf__P06streamPc:
- move.l d0,-(a7)
- move.l #200,-(a7)
- move.l #1,-(a7)
- move.l 3*4+4+4(a7),-(a7)
- move.l 3*4+4+4(a7),-(a7)
- bsr.b setvbuf__P06streamPciUi
- lea 4*4(a7),a7
- move.l (a7)+,d0
- rts
-
- _setvbuf:
- setvbuf__P06streamPciUi: ; Parameter: 0 stream*, 4 char*, 8 mode, 12 size
- movem.l d1/a0/a1/a6,-(a7)
- tst.l 20(a7)
- beq svbOK ; File #0
- tst.l 20+8(a7)
- beq svbOK ; _IONBF
- move.l 20+12(a7),d0
- beq svbOK ; leerer Buffer
- cmp.l #$FFFF,d0
- bls.b svbcs
- move.w #$FFFF,20+12+2(a7) ; Maximalgröße 0xfff
- svbcs: move.l 20(a7),a0
- tst.l str_bufptr(a0)
- beq.b svbOldBuf
- ; schon Puffer gesetzt: wegschmeißen!
- movem.l d0/a0,-(a7)
- move.l str_bufptr(a0),a0
- move.l buf_close(a0),a6
- jsr (a6)
- movem.l (a7)+,d0/a0
- svbOldBuf:
- move.l 20+4(a7),d0
- bne.b svb1 ; Speicherbereich angegeben?
- move.w 20+12+2(a7),d0
- moveq #0,d1
- move.l ExecBase.w,a6
- jsr AllocMem(a6)
- tst.l d0
- beq svbErr
- svb1: ; Speicher d0 verwenden:
- move.l d0,-(a7)
- moveq #buf_SizeOf,d0
- move.l #$10000,d1
- move.l ExecBase.w,a6
- jsr AllocMem(a6) ; buf-Struct einrichten
- move.l (a7)+,d1
- tst.l d0
- beq.b svbErr
- move.l d0,a1
- move.l d1,buf_buf(a1)
- move.l 20(a7),a0
- move.l a0,(a1) ; Rückverweis auf Stream
- move.l a1,str_bufptr(a0)
- move.w 20+12+2(a7),buf_size(a1)
- tst.l 20+4(a7)
- bne.b svb2 ; Buffer nachher wieder freigeben?
- move.b #1,buf_own(a1)
- svb2:
- cmp.b #1,str_mode(a0)
- beq.b svbRead
- ; Schreibpuffer:
- lea WriteFlush(pc),a0
- move.l a0,buf_flush(a1)
- move.b #1,buf_mode(a1)
- tst.l 20+8(a7)
- bpl.b svb3
- move.b #2,buf_mode(a1)
- bra.b svb3
- svbRead: ; Lesepuffer:
- move.b #-1,buf_mode(a1)
- lea ReadFlush(pc),a0
- move.l a0,buf_flush(a1)
- svb3: ; gemeinsame Funktionen:
- lea ReadBuffer(pc),a0
- move.l a0,buf_read(a1)
- lea WriteBuffer(pc),a0
- move.l a0,buf_write(a1)
- lea CloseBuffer(pc),a0
- move.l a0,buf_close(a1)
-
- svbOK: moveq #0,d0
- svbRet: movem.l (a7)+,d1/a0/a1/a6
- rts
- svbErr: move.l #1002,d0
- bra.b svbRet
-
- CloseBuffer: ; Buffer *a0 löschen
- tst.b buf_mode(a0)
- beq.b clb0
- bmi.b clb1
- ; bei Schreibpuffer noch FLUSH machen
- move.l a0,-(a7)
- bsr WriteFlush
- move.l (a7)+,a0
- clb0: tst.b buf_own(a0)
- beq.b clb1
- ; Buffer selbst löschen:
- moveq #0,d0
- move.w buf_size(a0),d0
- move.l buf_buf(a0),a1
- move.l ExecBase.w,a6
- move.l a0,-(a7)
- jsr FreeMem(a6)
- move.l (a7)+,a0
- clb1: ; Bufferstruct löschen
- move.l (a0),a1 ; Rückverweis auf stream
- clr.l str_bufptr(a1) ; Buffer austragen
- move.l ExecBase.w,a6
- move.l a0,a1
- moveq #buf_SizeOf,d0
- jmp FreeMem(a6)
-
- ReadBuffer: ; Buffer *a0, void *d2, size_t d3, Returncode = gelesene Anzahl
- tst.b buf_mode(a0)
- bpl.b rbWrite
- exg d2,a1
- moveq #0,d0
- rb0: tst.l d3
- beq.b rbEnd
- moveq #0,d1
- move.w buf_fill(a0),d1
- sub.w buf_pos(a0),d1
- bhi.b rb1
- movem.l d0/d3/a1,-(a7)
- bsr.b FillBuffer
- move.l d0,d1
- movem.l (a7)+,d0/d3/a1
- tst.l d1
- beq.b rbEnd ; Dateiende erreicht
- rb1: ; noch d1 Zeichen im Puffer:
- cmp.l d3,d1
- bls.b rb2
- move.l d3,d1 ; Pufferinhalt > zu lesende Daten?
- rb2: ; d1 > 0 Daten übertragen:
- move.l a2,-(a7)
- add.l d1,d0
- sub.l d1,d3
- move.w buf_pos(a0),a2
- add.l buf_buf(a0),a2
- add.w d1,buf_pos(a0)
- rbCopy: move.b (a2)+,(a1)+
- subq.w #1,d1
- bne.b rbCopy
- move.l (a7)+,a2
- ; fertig?
- tst.l d3
- bne.b rb0
- rbEnd: exg d2,a1
- rts
- rbWrite: ; Schreibpuffer, also "flush" und dann normal lesen
- movem.l d2/d3/a0,-(a7)
- bsr WriteFlush
- movem.l (a7)+,d2/d3/a0
- move.l (a0),a0
- jmp __Readfile__NoBuf
-
- FillBuffer: ; a0 auffüllen, gelesene Zeichen nach d0
- move.l buf_buf(a0),d2
- moveq #0,d3
- move.w buf_size(a0),d3
- move.l a0,-(a7)
- move.l (a0),a0
- jsr __Readfile__NoBuf
- move.l (a7)+,a0
- clr.w buf_pos(a0)
- move.w d0,buf_fill(a0)
- rts
-
- WriteBuffer: ; Buffer *a0, void *d2, size_t d3, Ergebnis <> 0 bei Fehler
- tst.b buf_mode(a0)
- beq wbRead
- bmi wbRead
- exg d2,a1
- cmp.b #2,buf_mode(a0)
- bne.b wbFull
- ; Zeilenpuffer:
- tst.l d3
- beq.b wbFull
- movem.l d3/a1,-(a7)
- wb0: ; Schleife: auf LF testen
- cmp.b #LF,(a1)+
- beq.b wbLF
- subq.l #1,d3
- bne.b wb0
- ; kein LF mehr gefunden:
- movem.l (a7)+,a1/d3
- bra.b wbFull
- wbLF: ; Zeilenende gefunden:
- move.l a1,d0
- movem.l (a7)+,a1/d3
- sub.l a1,d0 ; d0 von d3 Zeichen schreiben
- exg d3,d0
- move.l a1,-(a7)
- add.l d3,(a7)
- sub.l d3,d0
- move.l d0,-(a7)
- move.l a0,-(a7)
- bsr.b wbFull ; bis einschl. Zeilenende voll ausgeben
- move.l (a7),a0
- bsr.b WriteFlush
- move.l (a7)+,a0
- move.l (a7)+,d3
- move.l (a7)+,d2
- tst.l d0
- beq.b WriteBuffer ; und Rest ausgeben
- rts
-
- wbFull: ; Vollgepufferte Ausgabe
- tst.l d3
- beq.b wbRet
- wbLoop: moveq #0,d0
- move.w buf_size(a0),d0
- sub.w buf_pos(a0),d0
- bhi.b wb1
- movem.l d3/a1,-(a7)
- bsr.b WriteFlush
- movem.l (a7)+,d3/a1
- tst.w d0
- bne.b wbRet
- moveq #0,d0
- move.w buf_size(a0),d0
- wb1: ; Puffer hat noch Platz für d0.l Bytes
- cmp.l d0,d3
- bhs.b wb2
- move.l d3,d0
- wb2: ; d0.l > 0 Bytes übertragen:
- move.l a2,-(a7)
- move.w buf_pos(a0),a2
- add.l buf_buf(a0),a2
- add.w d0,buf_pos(a0)
- sub.l d0,d3
- wb3: move.b (a1)+,(a2)+
- subq.w #1,d0
- bne.b wb3
- move.l (a7)+,a2
- tst.l d3
- bne.b wbLoop
- moveq #0,d0
- wbRet: exg d2,a1
- rts
- wbRead: ; Lesepuffer, also normal Schreiben:
- movem.l a0/d2/d3,-(a7)
- bsr.b ReadFlush
- movem.l (a7)+,a0/a2/a3
- jmp __Writefile__NoBuf
-
- WriteFlush: ; Buffer *a0 wegschreiben, d0<>0 bei Fehler
- move.l a0,-(a7)
- move.l buf_buf(a0),d2
- moveq #0,d3
- move.w buf_pos(a0),d3
- move.l (a0),a0
- jsr __Writefile__NoBuf
- move.l (a7)+,a0
- clr.w buf_pos(a0)
- rts
-
- ReadFlush: ; Buffer *a0 (Daten invalidieren, mit Seek zurückgehen)
- move.w buf_pos(a0),d2
- sub.w buf_fill(a0),d2
- bhs.b rf1
- ext.l d2
- moveq #0,d3 ; Offset_Current
- clr.w buf_fill(a0)
- clr.w buf_pos(a0) ; Inhalt vergessen
- move.l _DosBase,a6
- move.l (a0),a0
- clr.b str_error(a0)
- move.l (a0),d1
- beq.b rf1
- jsr Seek(a6)
- rf1: rts
-
- _EXIT_2_Flush_Buffers_Yes_that_must_be:
- clr.l -(a7)
- bsr.b fflush__P06stream
- addq.l #4,a7
- rts
-
- _fflush:
- fflush__P06stream: ; Parameter: FILE *
- tst.l 4(a7)
- bne.b flsub
- ; Alle offenen Files:
- move.l a0,-(a7)
- clr.l -(a7)
- move.l ___Filelist,a0
- flLoop: cmp.l #0,a0
- beq.b flEnd
- move.l (a0),-(a7)
- pea 4(a0)
- bsr.b flsub
- addq.l #4,a7
- move.l (a7)+,a0
- or.l d0,(a7) ; Fehler summieren...
- bra.b flLoop
- flEnd: pea _std__err
- bsr.b flsub
- move.l #_std__out,(a7)
- bsr.b flsub
- addq.l #4,a7
- or.l (a7)+,d0 ; Fehlercode
- move.l (a7)+,a0
- rts
-
- flsub: ; File 4(a7) <> 0
- moveq #0,d0
- move.l a0,-(a7)
- move.l 8(a7),a0
- tst.l str_bufptr(a0)
- beq.b flok
- move.l str_bufptr(a0),a0
- tst.b buf_mode(a0)
- beq.b flok
- bmi.b flread
- ; Schreibpuffer:
- movem.l d1-d3/a1/a6,-(a7)
- move.l buf_flush(a0),a6
- jsr (a6)
- movem.l (a7)+,d1-d3/a1/a6
- tst.l d0
- beq.b flok
- bra.b flerr
- flread: ; Lesepuffer:
- movem.l d1-d3/a1/a6,-(a7)
- move.l buf_flush(a0),a6
- jsr (a6)
- movem.l (a7)+,d1-d3/a1/a6
- moveq #0,d0
- bra.b flok
- flerr: moveq #-1,d0
- flok: move.l (a7)+,a0
- rts
-
- end
-