home *** CD-ROM | disk | FTP | other *** search
- ;************************************************************************
- ; FIFO BUFFERS FOR CP/M BIOS
- ;
- ; The following code is submitted by Glenn Ewing and Bob Richardson
- ; of MicroPro. It is intended as an aid to those who wish to implement
- ; interrupts in their systems. Also included in the submission is a
- ; sample port driver and console bios routine intended to show the
- ; implementation of the routines as ring buffers for a Bios.
- ;
- ; Further Distribution of this file should contain the notice:
- ; This code Copyright (c) 1981 MicroPro International Corp.
- ; made available by permission of the authors
- ; and by MicroPro. Not to be Resold.
- ; Good Luck!
- ; ps: most of this code is Glenn's - Bob R.
- .z80
- size0 equ 16 ; size definition for the fifo queue -must be power of
- ; 2 - actual size depends on the device in questionc
- ;
- ; fifo stuf
- defb 'COPYRIGHT (c) 1981 MicroPro International Corp'
- ;
- ;
- ; This module impliments first-in-first-out buffers for the
- ; various BIOS I/O paths. The buffers function as follows:
- ;
- ; If:
- ; cnt = number of characters currently stored in buffer, and
- ;
- ; nout = relative position in buffer of characer to be output
- ; next, and
- ;
- ; size = size of buffer (even power of 2), and
- ;
- ; base = address of bottom of buffer, then
- ;
- ; A character is stored in the buffer at address:
- ;
- ; base + ((cnt + nout) mod size)
- ;
- ; and the variables are updated:
- ;
- ; cnt = (cnt + 1) mod size
- ;
- ; Alternately, a character is retrieved from address:
- ;
- ; base + nout
- ;
- ; and the variables are updated:
- ;
- ; cnt = (cnt - 1) mod size
- ;
- ; nout = (nout + 1) mod size.
- ;
- ;
- ; These items are stored in memory as follows:
- ;
- fifo macro size
- ;
- defb 0 ; cnt
- defb 0 ; nout
- defb size-1 ; mask for mod ops
- defs size ; actual buffer
- endm
- ;
- ;
- ;
- ; The fifo input and output routines provide no protection
- ; from underflow and overflow. The calling code must use
- ; the fstat routine to ensure that these conditions are
- ; avoided. Also, the calling code must enable and disable
- ; interupts as appropriate to ensure proper maintainance of
- ; the variables.
- ;
- ;
- fstat:
- ; routine to determine status (fullness) of a buffer.
- ; enter with ix = adr of cnt.
- ; return Z-flag set if buffer empty, Cy set if buffer full.
- ; note that buffer capacity is actually size-1.
- ;
- ld a, (ix + 0) ; get cnt
- push de
- ld e, (ix + 2) ; get mask
- and e ; cnt = cnt mod size
- dec e ; e = size - 2
- cp e ; test for full
- pop de
- inc a ; clear z leaving cy
- dec a
- ccf
- ret
- ;
- ;
- fin:
- ; routine to enter a character into a buffer.
- ; enter with c=chr, ix=.cnt
- ;
- ld a, (ix + 0) ; compute: (cnt + nout) mod size
- inc (ix + 0) ; first update cnt
- add a, (ix + 1)
- and (ix + 2)
- push de
- ld e, a ; compute base + nin
- ld d, 0
- inc ix
- inc ix
- inc ix
- add ix, de
- pop de
- ld (ix+0), c ; store character
- ret
- ;
- ;
- ;
- fout:
- ; routine to retreve a character from a buffer.
- ; enter with ix=.cnt
- ; return with c=chr
- ;
- dec (ix + 0) ; update cnt
- ld a, (ix + 1) ; compute: base + nout
- inc (ix + 1)
- and (ix + 2)
- push de
- ld e, a
- ld d, 0
- inc ix
- inc ix
- inc ix
- add ix, de
- pop de
- ld c, (ix + 0) ; get chr
- ret
- ;
- fifo0: fifo size0 ; sample invocation of the fifo macro
- fifo1: fifo size0 ; dummy queues for sample codes
- ;
- sample:
- jp cboot ; phoney jp
- jp wboot ; phoney jp
- jp const ; console status
- jp conin ; console input vector
- jp conout ; console output routine
- ; end of phoney bios branch vector-
- ; note that for this end of the queueing, all that is necessary is to test
- ; the status of the queue and return a value based on the queue status-
- ; not the status of the device-
- ;
- ;*************************************************************************
- ; start of the front end queue - dequeue routines - these routines are
- ; code samples only and are not intended to run on any particular machine
- ; and in fact ignore specifically some details of implementation
- const:
- ld ix,fifo0 ; note on real sys, you must save ix
- ; this sets up the pointer for the
- ; fifo routines
- call fstat ; check on the status of the queue
- ret z ; return if z-flag set, and hence
- ; ; no char is ready - this will
- ; ; also have zero in a at this point
- ld a,0ffh ; get flag to show that a char is rdy
- ret ; and return that value -
- ;
- ;
- conin: ; read a char from the queue
- call const ; first, wait until a char is
- ; available - necessary to avoid
- ; underflow
- jp z,conin ; loop until char is ready
- di ; interrupts must be off to use
- ; fin and fout routines
- call fout ; get a character from the queue
- ld a,c ; and put it in correct register
- and 07fh ; strip parity per spec
- ret ; to caller
- ;
- ;
- conout: ; send a character to the console
- ld ix,fifo1 ; setup for console output queue
- call fstat ; test queue status
- jp c,conout ; wait for a space in the queue
- ; note: carry set if queue is full
- di ; interrupts off for queue manipulation
- push ix ; save queue pointer for conditional
- ; output routine
- call fin ; put a character into the fifo queue
- pop ix ; restore pointer
- call tryout ; routine to output a character and
- ; turn on interrupts from console
- ; if a character is waiting and if
- ; port is not busy
- ei ; restart interrupts
- ret ; to caller
-
- tryout:
- ; This routine is installation dependant-
- ; it must output a character to the console if and only if
- ; the port is ready to accept a character
- ; I will not supply the routine, but rather the logic for the routine
- ; which would run as follows:
- ; select the status port for the console or modem
- ; test the tx ready bit
- ; return if not ready
- ; otherwise if tx is ready to go
- ; call fout <- gets next char in c register
- ; output the character to the data port
- ; then return
- ;*****************************************************************************
- ;*****************************************************************************
- ; now - the easy part - servicing the interrupts from the console/printer/
- ; whatever you have hooked up - I am going to just give you the logic for
- ; the routine we have been working on, without getting into details as this
- ; is obviously a highly installation dependant part of the code.
- ; the philosophy of the coding is, however, the same as the front end
- ; when the device needs a character, get one from the queue with
- ; call fout ; and then
- ; send the character to the device through whatever mode you use to speak
- ; to it - if the queue becomes empty, you generally want to ignore the next
- ; interrupt
- ; ++++++++++++++++++++++++++++++++++++++++++++
- ; if, therefore
- ; it is an input device with a character ready
- ; read the character from the device and then
- ; use
- ; call fin ; to put the newly read character into queue
- ; if the input queue fills up, you will want to ignore further characters-
- ; one standard thing to do is just throw them into the bit bucket and return
- ; from the interrupt
- ; sample code for the output interrupt on an sio might read:
- sint0:
- ld ix,fifo1 ; get output queue
- call fstat ; check queue status
- ;
- jp z,underf ; the queue is empty - no more chars to send
- call tryout ; note: this is the same routine we created
- ; prviously to handle output to port if not
- ; busy -
- ; This is interrupt code so it is not necessary to disable the interrupts
- ; before calling the fin and fout routines
- underf:
- ;this routine should turn off the transmit interrupt with a device dependant
- ; code - ie, for the sio it would send a 28h to the status port for the sio
- ; and then
- ret
- ;the code for an input interrupt would be similar, except the routine would
- ; read a byte from the device
- ; call fstat
- ; ret c ; throw away character if queue full
- ; call fin ; else put it in queue
- ; ret ; and return
- ;
- ;
- ;
- ;
- ;******************************************************************************
- ; the end - note - this file is copyright (c) Micropro International Corp.
- ; and may not be duplicated in whole or in part for resale. The code
- ; contained here does not exist in any real implementation of bios except for
- ; the fifo routines and are presented here as a service and in expression
- ; of our support for this group. Any source copy of the fifo stuff must
- ; retain the credits for this piece of code. Good luck, may all your
- ; interruptions be quick ones.
- ; -bob-