home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / OTL-MC6.DMS / in.adf / libsrc.lha / LIBSRC / buffers.asm < prev    next >
Encoding:
Assembly Source File  |  1994-04-08  |  7.2 KB  |  378 lines

  1.  
  2. * Maxon C++ Library:
  3. * Modul "buffers"
  4. * Jens Gelhar 19.03.93, 20.02.94
  5.  
  6.     xdef    _setvbuf,setvbuf__P06streamPciUi
  7.     xdef    _setbuf,setbuf__P06streamPc
  8.     xdef    _fflush,fflush__P06stream
  9.     xdef    _EXIT_2_Flush_Buffers_Yes_that_must_be
  10.  
  11.     xref    _DosBase,__Readfile__NoBuf,__Writefile__NoBuf
  12.     xref    _std__err,_std__out
  13.     xref    ___Filelist
  14.  
  15. ExecBase    = 4
  16.  
  17. AllocMem    = -198
  18. FreeMem        = -210
  19.  
  20. Seek        = -66
  21.  
  22. LF        = 10
  23.  
  24. str_mode    = 6
  25. str_error    = 7
  26. str_bufptr    = 8
  27.  
  28. buf_size    = 4
  29. buf_fill    = 6
  30. buf_pos        = 8
  31. buf_mode    = 10
  32. buf_own        = 11
  33. buf_read    = 12
  34. buf_write    = 16
  35. buf_flush    = 20
  36. buf_close    = 24
  37. buf_buf        = 28
  38. buf_SizeOf    = 32
  39.  
  40. _setbuf:
  41. setbuf__P06streamPc:
  42.     move.l d0,-(a7)
  43.     move.l #200,-(a7)
  44.     move.l #1,-(a7)
  45.     move.l 3*4+4+4(a7),-(a7)
  46.     move.l 3*4+4+4(a7),-(a7)
  47.     bsr.b    setvbuf__P06streamPciUi
  48.     lea 4*4(a7),a7
  49.     move.l (a7)+,d0
  50.     rts
  51.  
  52. _setvbuf:
  53. setvbuf__P06streamPciUi:    ; Parameter: 0 stream*, 4 char*, 8 mode, 12 size
  54.     movem.l d1/a0/a1/a6,-(a7)
  55.     tst.l 20(a7)
  56.     beq svbOK               ; File #0
  57.     tst.l 20+8(a7)
  58.     beq svbOK               ; _IONBF
  59.     move.l 20+12(a7),d0
  60.     beq svbOK               ; leerer Buffer
  61.     cmp.l #$FFFF,d0
  62.     bls.b svbcs
  63.     move.w #$FFFF,20+12+2(a7)       ; Maximalgröße 0xfff
  64. svbcs:    move.l 20(a7),a0
  65.     tst.l str_bufptr(a0)
  66.     beq.b    svbOldBuf
  67.     ; schon Puffer gesetzt: wegschmeißen!
  68.     movem.l d0/a0,-(a7)
  69.     move.l str_bufptr(a0),a0
  70.     move.l buf_close(a0),a6
  71.     jsr (a6)
  72.     movem.l (a7)+,d0/a0
  73. svbOldBuf:
  74.     move.l 20+4(a7),d0
  75.     bne.b svb1              ; Speicherbereich angegeben?
  76.     move.w 20+12+2(a7),d0
  77.     moveq #0,d1
  78.     move.l ExecBase.w,a6
  79.     jsr AllocMem(a6)
  80.     tst.l d0
  81.     beq svbErr
  82. svb1:    ; Speicher d0 verwenden:
  83.     move.l d0,-(a7)
  84.     moveq #buf_SizeOf,d0
  85.     move.l #$10000,d1
  86.     move.l ExecBase.w,a6
  87.     jsr AllocMem(a6)        ; buf-Struct einrichten
  88.     move.l (a7)+,d1
  89.     tst.l d0
  90.     beq.b svbErr
  91.     move.l d0,a1
  92.     move.l d1,buf_buf(a1)
  93.     move.l 20(a7),a0
  94.     move.l a0,(a1)          ; Rückverweis auf Stream
  95.     move.l a1,str_bufptr(a0)
  96.     move.w 20+12+2(a7),buf_size(a1)
  97.     tst.l 20+4(a7)
  98.     bne.b svb2              ; Buffer nachher wieder freigeben?
  99.     move.b #1,buf_own(a1)
  100. svb2:
  101.     cmp.b #1,str_mode(a0)
  102.     beq.b svbRead
  103.     ; Schreibpuffer:
  104.     lea WriteFlush(pc),a0
  105.     move.l a0,buf_flush(a1)
  106.     move.b #1,buf_mode(a1)
  107.     tst.l 20+8(a7)
  108.     bpl.b svb3
  109.     move.b #2,buf_mode(a1)
  110.     bra.b svb3
  111. svbRead:    ; Lesepuffer:
  112.     move.b #-1,buf_mode(a1)
  113.     lea ReadFlush(pc),a0
  114.     move.l a0,buf_flush(a1)
  115. svb3:    ; gemeinsame Funktionen:
  116.     lea ReadBuffer(pc),a0
  117.     move.l a0,buf_read(a1)
  118.     lea WriteBuffer(pc),a0
  119.     move.l a0,buf_write(a1)
  120.     lea CloseBuffer(pc),a0
  121.     move.l a0,buf_close(a1)
  122.  
  123. svbOK:    moveq #0,d0
  124. svbRet:    movem.l (a7)+,d1/a0/a1/a6
  125.     rts
  126. svbErr:    move.l #1002,d0
  127.     bra.b svbRet
  128.  
  129. CloseBuffer:    ; Buffer *a0 löschen
  130.     tst.b buf_mode(a0)
  131.     beq.b clb0
  132.     bmi.b clb1
  133.     ; bei Schreibpuffer noch FLUSH machen
  134.     move.l a0,-(a7)
  135.     bsr WriteFlush
  136.     move.l (a7)+,a0
  137. clb0:    tst.b buf_own(a0)
  138.     beq.b clb1
  139.     ; Buffer selbst löschen:
  140.     moveq #0,d0
  141.     move.w buf_size(a0),d0
  142.     move.l buf_buf(a0),a1
  143.     move.l ExecBase.w,a6
  144.     move.l a0,-(a7)
  145.     jsr FreeMem(a6)
  146.     move.l (a7)+,a0
  147. clb1:    ; Bufferstruct löschen
  148.     move.l (a0),a1          ; Rückverweis auf stream
  149.     clr.l str_bufptr(a1)    ; Buffer austragen
  150.     move.l ExecBase.w,a6
  151.     move.l a0,a1
  152.     moveq #buf_SizeOf,d0
  153.     jmp FreeMem(a6)
  154.  
  155. ReadBuffer:    ; Buffer *a0, void *d2, size_t d3, Returncode = gelesene Anzahl
  156.     tst.b buf_mode(a0)
  157.     bpl.b rbWrite
  158.     exg d2,a1
  159.     moveq #0,d0
  160. rb0:    tst.l d3
  161.     beq.b rbEnd
  162.     moveq #0,d1
  163.     move.w buf_fill(a0),d1
  164.     sub.w buf_pos(a0),d1
  165.     bhi.b rb1
  166.     movem.l d0/d3/a1,-(a7)
  167.     bsr.b FillBuffer
  168.     move.l d0,d1
  169.     movem.l (a7)+,d0/d3/a1
  170.     tst.l d1
  171.     beq.b rbEnd       ; Dateiende erreicht
  172. rb1:    ; noch d1 Zeichen im Puffer:
  173.     cmp.l d3,d1
  174.     bls.b rb2
  175.     move.l d3,d1            ; Pufferinhalt > zu lesende Daten?
  176. rb2:    ; d1 > 0 Daten übertragen:
  177.     move.l a2,-(a7)
  178.     add.l d1,d0
  179.     sub.l d1,d3
  180.     move.w buf_pos(a0),a2
  181.     add.l buf_buf(a0),a2
  182.     add.w d1,buf_pos(a0)
  183. rbCopy:    move.b (a2)+,(a1)+
  184.     subq.w #1,d1
  185.     bne.b rbCopy
  186.     move.l (a7)+,a2
  187.     ; fertig?
  188.     tst.l d3
  189.     bne.b rb0
  190. rbEnd:    exg d2,a1
  191.     rts
  192. rbWrite:    ; Schreibpuffer, also "flush" und dann normal lesen
  193.     movem.l d2/d3/a0,-(a7)
  194.     bsr WriteFlush
  195.     movem.l (a7)+,d2/d3/a0
  196.     move.l (a0),a0
  197.     jmp __Readfile__NoBuf
  198.  
  199. FillBuffer:    ; a0 auffüllen, gelesene Zeichen nach d0
  200.     move.l buf_buf(a0),d2
  201.     moveq #0,d3
  202.     move.w buf_size(a0),d3
  203.     move.l a0,-(a7)
  204.     move.l (a0),a0
  205.     jsr __Readfile__NoBuf
  206.     move.l (a7)+,a0
  207.     clr.w buf_pos(a0)
  208.     move.w d0,buf_fill(a0)
  209.     rts
  210.  
  211. WriteBuffer:    ; Buffer *a0, void *d2, size_t d3, Ergebnis <> 0 bei Fehler
  212.     tst.b buf_mode(a0)
  213.     beq wbRead
  214.     bmi wbRead
  215.     exg d2,a1
  216.     cmp.b #2,buf_mode(a0)
  217.     bne.b wbFull
  218.     ; Zeilenpuffer:
  219.     tst.l d3
  220.     beq.b wbFull
  221.     movem.l d3/a1,-(a7)
  222. wb0:    ; Schleife: auf LF testen
  223.     cmp.b #LF,(a1)+
  224.     beq.b wbLF
  225.     subq.l #1,d3
  226.     bne.b wb0
  227.     ; kein LF mehr gefunden:
  228.     movem.l (a7)+,a1/d3
  229.     bra.b wbFull
  230. wbLF:    ; Zeilenende gefunden:
  231.     move.l a1,d0
  232.     movem.l (a7)+,a1/d3
  233.     sub.l a1,d0     ; d0 von d3 Zeichen schreiben
  234.     exg d3,d0
  235.     move.l a1,-(a7)
  236.     add.l d3,(a7)
  237.     sub.l d3,d0
  238.     move.l d0,-(a7)
  239.     move.l a0,-(a7)
  240.     bsr.b wbFull            ; bis einschl. Zeilenende voll ausgeben
  241.     move.l (a7),a0
  242.     bsr.b WriteFlush
  243.     move.l (a7)+,a0
  244.     move.l (a7)+,d3
  245.     move.l (a7)+,d2
  246.     tst.l d0
  247.     beq.b WriteBuffer       ; und Rest ausgeben
  248.     rts
  249.  
  250. wbFull:    ; Vollgepufferte Ausgabe
  251.     tst.l d3
  252.     beq.b wbRet
  253. wbLoop:    moveq #0,d0
  254.     move.w buf_size(a0),d0
  255.     sub.w buf_pos(a0),d0
  256.     bhi.b wb1
  257.     movem.l d3/a1,-(a7)
  258.     bsr.b WriteFlush
  259.     movem.l (a7)+,d3/a1
  260.     tst.w d0
  261.     bne.b wbRet
  262.     moveq #0,d0
  263.     move.w buf_size(a0),d0
  264. wb1:    ; Puffer hat noch Platz für d0.l Bytes
  265.     cmp.l d0,d3
  266.     bhs.b wb2
  267.     move.l d3,d0
  268. wb2:    ; d0.l > 0 Bytes übertragen:
  269.     move.l a2,-(a7)
  270.     move.w buf_pos(a0),a2
  271.     add.l    buf_buf(a0),a2
  272.     add.w    d0,buf_pos(a0)
  273.     sub.l    d0,d3
  274. wb3:    move.b    (a1)+,(a2)+
  275.     subq.w    #1,d0
  276.     bne.b    wb3
  277.     move.l    (a7)+,a2
  278.     tst.l    d3
  279.     bne.b    wbLoop
  280.     moveq    #0,d0
  281. wbRet:    exg    d2,a1
  282.     rts
  283. wbRead:    ; Lesepuffer, also normal Schreiben:
  284.     movem.l    a0/d2/d3,-(a7)
  285.     bsr.b    ReadFlush
  286.     movem.l    (a7)+,a0/a2/a3
  287.     jmp    __Writefile__NoBuf
  288.  
  289. WriteFlush:    ; Buffer *a0 wegschreiben, d0<>0 bei Fehler
  290.     move.l a0,-(a7)
  291.     move.l buf_buf(a0),d2
  292.     moveq #0,d3
  293.     move.w buf_pos(a0),d3
  294.     move.l (a0),a0
  295.     jsr __Writefile__NoBuf
  296.     move.l (a7)+,a0
  297.     clr.w buf_pos(a0)
  298.     rts
  299.  
  300. ReadFlush:    ; Buffer *a0 (Daten invalidieren, mit Seek zurückgehen)
  301.     move.w    buf_pos(a0),d2
  302.     sub.w    buf_fill(a0),d2
  303.     bhs.b    rf1
  304.     ext.l    d2
  305.     moveq    #0,d3        ; Offset_Current
  306.     clr.w    buf_fill(a0)
  307.     clr.w    buf_pos(a0)    ; Inhalt vergessen
  308.     move.l    _DosBase,a6
  309.     move.l    (a0),a0
  310.     clr.b    str_error(a0)
  311.     move.l    (a0),d1
  312.     beq.b    rf1
  313.     jsr    Seek(a6)
  314. rf1:    rts
  315.  
  316. _EXIT_2_Flush_Buffers_Yes_that_must_be:
  317.     clr.l    -(a7)
  318.     bsr.b    fflush__P06stream
  319.     addq.l    #4,a7
  320.     rts
  321.  
  322. _fflush:
  323. fflush__P06stream:    ; Parameter: FILE *
  324.     tst.l 4(a7)
  325.     bne.b    flsub
  326.     ; Alle offenen Files:
  327.     move.l a0,-(a7)
  328.     clr.l -(a7)
  329.     move.l ___Filelist,a0
  330. flLoop:    cmp.l #0,a0
  331.     beq.b    flEnd
  332.     move.l (a0),-(a7)
  333.     pea 4(a0)
  334.     bsr.b    flsub
  335.     addq.l #4,a7
  336.     move.l (a7)+,a0
  337.     or.l d0,(a7)            ; Fehler summieren...
  338.     bra.b flLoop
  339. flEnd:    pea _std__err
  340.     bsr.b flsub
  341.     move.l #_std__out,(a7)
  342.     bsr.b flsub
  343.     addq.l #4,a7
  344.     or.l (a7)+,d0           ; Fehlercode
  345.     move.l (a7)+,a0
  346.     rts
  347.  
  348. flsub:    ; File 4(a7) <> 0
  349.     moveq #0,d0
  350.     move.l a0,-(a7)
  351.     move.l 8(a7),a0
  352.     tst.l str_bufptr(a0)
  353.     beq.b flok
  354.     move.l str_bufptr(a0),a0
  355.     tst.b buf_mode(a0)
  356.     beq.b flok
  357.     bmi.b flread
  358.     ; Schreibpuffer:
  359.     movem.l d1-d3/a1/a6,-(a7)
  360.     move.l buf_flush(a0),a6
  361.     jsr (a6)
  362.     movem.l (a7)+,d1-d3/a1/a6
  363.     tst.l d0
  364.     beq.b flok
  365.     bra.b flerr
  366. flread:    ; Lesepuffer:
  367.     movem.l    d1-d3/a1/a6,-(a7)
  368.     move.l    buf_flush(a0),a6
  369.     jsr    (a6)
  370.     movem.l    (a7)+,d1-d3/a1/a6
  371.     moveq    #0,d0
  372.     bra.b    flok
  373. flerr:    moveq    #-1,d0
  374. flok:    move.l    (a7)+,a0
  375.     rts
  376.  
  377.     end
  378.