;
;   FILE: i o _ q u e u e
;
;   u t _ q e o f
;   u t _ q i n
;   u t _ q o u t
;   u t _ q s e t
;   u t _ q t e s t
;
; QDOS routines for queue handling.  Includes routines for:
;       - setting EOF marker
;       - adding a byte
;       - removing a byte
;       - setting up a queue
;       - testing a queue
;
; equivalent to C routines
;   void   ut_qeof  (char *queue_pointer)
;   int    ut_qin   (char *queue_pointer, int byte_value)
;   void   ut_qout  (char *queue_pointer, char * next_byte)
;   void   ut_qset  (char *queue_pointer, long queue_length)
;   void   ut_qtest (char *queue_pointer, char * next_byte, long_ * free_space)
;
; AMENDMENT HISTORY
; ~~~~~~~~~~~~~~~~~
;   10 Jul 93   DJW   - First version
;
;   27 Jul 93   DJW   - Produced single file merging all queue handling
;                       routines into a single source file
;                     - Added SMS entry points
;
;   06 Nov 93   DJW   - Added underscore to entry point names
;                     - Added SMS entry point names
;
;   24 Jan 94   DJW   - Added (yet another) underscore to entry point names
;                       for name hiding purposes

    .text
    .even

    .globl __io_qset
    .globl __ioq_setq
__io_qset:
__ioq_setq:
    move.w  $dc, a0             ; set vector
    bra     io_queue            ; ... and use common code


    .globl __io_qtest
    .globl __ioq_test
__io_qtest:
__ioq_test:
    move.w  $de, a0             ; set vector
    bsr     io_queue           ; ... and use common code
    tst.l   8(a7)               ; next byte wanted ?
    beq     nobyte              ; ... NO, skip
    move.l  8(a7),a0            ; get address to store next byte
    move.b  d1,(a0)             ; store byte in user area
nobyte:
    tst.l   12(a7)              ; free space wanted ?
    beq     nofree              ; ... NO, jump
    move.l  12(a7),a0           ; get address to store free space
    move.l  a1,(a0)             ; store length in user area
nofree:
    rts


    .globl __io_qin
    .globl __ioq_pbyt
__io_qin:
__ioq_pbyt:
    move.w  $e0, a0             ; set vector
    bra     io_queue            ; ... and use common code


    .globl __io_qout
    .globl __ioq_gbyt
__io_qout:
__ioq_gbyt:
    move.w  $e2, a0             ; set vector
    bsr     io_queue           ; ... and use common code
    move.l  8(a7),a0            ; get address to store next byte
    move.b  d1,(a0)             ; store byte in user area
    rts


    .globl __io_qeof
    .globl __ioq_seof
__io_qeof:
__ioq_seof:
    move.w  $e4, a0             ; set vector
    bra     io_queue            ; ... and use common code


;   Common code

io_queue:
    movem.l d2/a2-a3,-(a7)      ; save register variables
    move.l  4+4+12(a7),a2       ; queue pointer
    move.l  8+4+12(a7),d1       ; queue length/byte to put in
    jsr     (a0)                ; call it
    tst.l   d0                  ; OK ?
    bne     fin                 ; ... and jump if error
    move.l  d2,a1               ; save value for use in io_qtest()
fin:
    movem.l (a7)+,d3/a2-a3      ; restore register variables
    rts

