   .MODEL TINY
   .CODE
;==========================================================================
;
;       Modified to suit printer port MIDI adaptor March 30 1992
;

IRQ          equ     07h
IRQLOC       equ     0BEh
BASEPORT     equ     378h
COPYRIGHT    equ     1Dh
FAIL         equ     0
SUCCESS      equ     1

MAX_RESETS   equ     5
MAX_WAIT     equ     65535


IF_READY     equ     80h
INT_PENDING  equ     40h
DATA_READY   equ     20h
OVERRUN      equ     10h
FRAME_ERR    equ     08
STATUS       equ     00
STROBE       equ     01
READ_HI      equ     02
READ_LO      equ     04
INT_ENABLE   equ     10h
RESET        equ     READ_LO+READ_HI

;==========================================================================
CSEG    SEGMENT
assume  CS:CSEG
        org     00h
start:

;==========================================================================
;
;       All Cakewalk drivers start with a similar string here.  God
; knows what it does (it may be executable), but we will reproduce it
; faithfully...
;

;==========================================================================
;
;       The jump table
;
        JMP       init
        JMP       quit
        JMP       ready
        JMP       output
        JMP       bufchk
        JMP       getchar
        JMP       setname

;==========================================================================
;
;       Threatening text...
;
        org     start + copyright

;==========================================================================
;
;       Data area
;

;
;       Following are filled in after load...
;
dataport        DW      0
stsport         DW      0
ctlport         DW      0
callback        DD      0
main_DS         DW      0
save_SS         DW      0
save_SP         DW      0
main_SP         DW      0
;
; locations for interrupt handling
;
old_vector      DD      0
int_mask        DB      0
int_n_mask      DB      0
save_int_mask   DB      0
int_sts_buf     DB      8 DUP(0)
int_sts_index   DW      0
;
; locations for buffering input.  A circular buffer is used to hold
; characters in the event that the main code gets behind the midi
; device.  The interrupt routine calls the main code callback when 
; there is data available, and the callback routine in turn uses our
; bufchk and getchar routines to empty it.  To avoid problems in the
; non-re-entrant callback routine, the lock byte is used to avoid
; re-calling it if another interrupt occurs while the buffer is being
; emptied.
;
lock_byte       DB      0
in_ptr          DW      iobuf
out_ptr         DW      iobuf
iobuf           DB      256 DUP(0)
buf_limit       DW      0
                DB      "COUNT"
int_count       DW      0
int_exit        DW      0
int_n_exit      DW      0
int_err         DW      0
                DB      "WEIRD"
last_weird_sts  DB      0

;===========================================================================
;
;       Init: initialise the driver data areas from the supplied
; parameter list, install the interrupt handler, reset the interface,
; set MPU into UART mode
;       Returns: AX = 1 - success
;               AX = 0 - failure
;

init:

;===========================================================================
;
;       Quit: reset i/f, restore interrupt vector
;
 
quit:

;===========================================================================
;
;       Ready: return SUCCESS if ready to receive more data; FAIL if not
;

ready:

;===========================================================================
;
;       Output: output the string of bytes held in the low order of a
; sequence of words pushed on the stack.  End-of-string is indicated by a
; flag word with the high bit set
;

output:


;===========================================================================
;
;       Bufchk: return SUCCESS if there is data in buffer, FAIL if no
;

bufchk:

;===========================================================================
;
;       Getchar: remove one character from buffer and return it in AL,
; with AH=0.  Return AH=AL=0xFF if no data
;

getchar:

;===========================================================================
;
;       Setname: stow the seg:offset form of the location of the interface
; name into the calling routine's buffer
;

setname:

;===========================================================================
;
;       Int_setup: calculate and store the interrupt masks for enable
; (zero bit in our irq location) and disable (one bit ditto)
;


;===========================================================================
;
;        Install_isr: use DOS call 25 to install our ISR for the device.
;

install_isr:

;===========================================================================
;
;        Remove_isr: use DOS call 25 to restore original interrupt handler
;


remove_isr:

;===========================================================================
;
;        If_reset: reset the interface
;

if_reset:

;===========================================================================
;
;        Isr: our interrupt handler
;

isr:

;===========================================================================
;
;        Int_disable: turn off our interrupt via the 8259 PIC
;

int_disable:
           

;===========================================================================
;
;        Int_restore: reset previous 8259 int-enable status
;

int_restore:

       ENDS     CSEG
       END  start


