;********************************************************************** ; Scribe Interrupt Support: IntSup.asm V2.00 01/14/92 ; Copyright (c) 1987-1992 Andrew J. Michalik ; ;********************************************************************** extrn isr_data:word, __ccode:word ;Non "C" externals INCLUDE mixed.inc .MODEL SMALL, C .8086 ;********************************************************************** ; Interrupt Support Routines ;********************************************************************** INCLUDE intsup.inc ;********************************************************************** ;********************************************************************** .CODE public ucSndBuf, usSBfPtr, usSBfStp public usSndFnc, usSndPrt public ucStbLow, ucStbHgh, ucPwrLow, ucPwrHgh public pfOldTimVec, pfOldGSVVec, pfOldMpxVec, pfOldXchVec public usStbTim, usCnt18z, usFra18z, usMax18z public ucTSRMID, ucTSRInt ;====================================================================== ; CS Referenced Variables for access from int hdlr ;====================================================================== ALIGN 4 MbxPrmBuf db MBXLOCSIZ dup(0);Local mailbox parameter copy ucSndBuf db BUFMSK+1 dup(0) ;Voice I/O buffer usSBfPtr dw 0 ;Current usSBfStp dw 0 ;When SBfPtr = SBfStp, stop usSndFnc dw 0 ;Sound function usSndPrt dw 0378h ;Sound I/O port ucPwrHgh db 04h ;DSS strobe high bit pattern ucPwrLow db 0ch ;DSS strobe low bit pattern ucStbHgh db 04h ;DSS strobe high bit pattern ucStbLow db 0ch ;DSS strobe low bit pattern pfOldGSVVec dd 0 ;Original "get/set vector" vector pfOldTimVec dd 0 ;Original timer interrupt vector pfOldMpxVec dd 0 ;Original TSR Mpx shared vector pfOldXchVec dd 0 ;Original X-change interrupt vector usStbTim dw 10h ;I/O operation delay time usCnt18z dw 910 ;Cnt to determine pfOldTimVec call usFra18z dw 0 ;Fractional part of 18Hz counter usMax18z dw 910 ;ratio of old timer count to new ucTSRMID db MPXTSRMID ;TSR Mpx ID (A+M) ucTSRInt db 0 ;TSR Interrupt number ;====================================================================== ; Get/ Set Interrupt Vector ;====================================================================== ALIGN 4 GetSetVec PROC FAR ;********************************************************** ;********************************************************** TstGet: cmp ax, GETTIMVEC jne TstSet mov bx, WORD PTR cs:pfOldTimVec mov es, WORD PTR cs:pfOldTimVec+2 jmp RetTrp TstSet: cmp ax, SETTIMVEC jne SkpTrp mov WORD PTR cs:pfOldTimVec, dx push ds pop WORD PTR cs:pfOldTimVec+2 jmp RetTrp ;********************************************************** ;********************************************************** RetTrp: iret SkpTrp: jmp cs:pfOldGSVVec GetSetVec ENDP ;====================================================================== ; TSR Multiplex Interrupt ;====================================================================== ALIGN 4 TSRMpxInt PROC FAR ;********************************************************** ;********************************************************** cmp ah, cs:ucTSRMID ;My Mpx ID? je ChkIns ;Yes, parse request jmp cs:pfOldMpxVec ;No, continue along chain ChkIns: cmp al, 00h ;Install check sub-func? je TMIRet ;Yes, we're done GetVec: cmp al, MPXGETVEC ;Get vector sub-function? jne TMIRet ;No, exit mov dh, 0 ;dx = interrupt address mov dl, cs:ucTSRInt jmp TMIRet ;Exit ;********************************************************** ;********************************************************** TMIRet: mov al, MPXACKRSP ;Indicate TSR installed (ack) iret TSRMpxInt ENDP ;====================================================================== ;====================================================================== ALIGN 4 XchComInt PROC FAR ;********************************************************** ; Function is fully pre-emptive, so can only post message */ ;********************************************************** push ds ;Save DS push es ;Save ES push bx ;Save BX push cx ;Save CX push dx ;Save DX push di ;Save DI push si ;Save SI push cs:isr_data ;Push TSR data segment pop ds ;Pop TSR data segment ;********************************************************** ; Get mailbox pointer, check if full ;********************************************************** mov es, __ccode ;Beginning of code seg mov bx, es:08h ;Pointer to cfg_blk cmp [bx].usMbxLck, 00h ;usMpxLck == FALSE? jne NegAck ;No, exit ;********************************************************** ; Set mailbox return receipt address ;********************************************************** mov [bx].crCmdReq, ax ;AX = Command request mov WORD PTR [bx].ulRetAdr, di mov WORD PTR [bx].ulRetAdr+2, dx ;********************************************************** ;********************************************************** cmp cx, 0 ;CX:SI -> additional parameters? jne Get001 ;Yes, get it cmp si, 0 ;Maybe? je PosAck ;No, exit Get001: push ds ;Save DS push cs ;ES = CS pop es mov di, OFFSET MbxPrmBuf;ES:DI -> Local destination mov ds, cx ;DS:SI -> Parameter source mov cx, MBXLOCSIZ - 1 ;CX = max size with terminator Lod001: lodsb ;AL = DS:SI = *pSrc++ stosb ;*pDst++ = ES:DI = AL cmp al, 0 ;Done? loopne Lod001 ;No, continue Trm001: mov BYTE PTR es:[di], 0 ;Force terminator pop ds ;Restore DS mov WORD PTR [bx].ulPrm001, OFFSET MbxPrmBuf mov WORD PTR [bx].ulPrm001+2, cs ;********************************************************** ; Message received; acknowledge ;********************************************************** PosAck: mov ax, [bx].crCmdReq ;Restore command request or ax, CMDACKFLG ;Acknowledge command mov [bx].usMbxLck, 01h ;usMpxLck = TRUE ;********************************************************** ; Mailbox full; no acknowledge ;********************************************************** NegAck: pop si ;Restore SI pop di ;Restore DI pop dx ;Restore DX pop cx ;Restore CX pop bx ;Restore BX pop es ;Restore ES pop ds ;Restore DS iret XchComInt ENDP ;====================================================================== ; Covox Speech Thing Interrupt service routine ;====================================================================== ; Abs worst case: 388 clock cycles (350 cycles = 74 uS) @ 210nS/ cycle ; (350 cycles = 44 uS) @ 125nS/ cycle ; Typ loading: 321 cycles ; Timing: 88 ; ---------- ALIGN 4 CSTTODInt PROC FAR ; 51 PUBLIC CSTTODPbk, CSTTODChk push ax ; 15 ;********************************************************** ;********************************************************** jmp cs:usSndFnc ; 20 ;********************************************************** ; Play file at 1x speed ;********************************************************** ALIGN 4 CSTTODPbk LABEL NEAR mov ax, cs:usSBfPtr ;AX = sound buffer index 18 cmp ax, cs:usSBfStp ;End of Buffer? 18 je CSTTODChk ; 4 ;********************************************************** ; Increment circular buffer pointer ;********************************************************** inc ax ;Increment index 3 and ax, BUFMSK ;Trim to less than 16K 18 mov cs:usSBfPtr, ax ;Store it back 19 ;********************************************************** ; Send PCM to D/A output port ;********************************************************** xchg ax, bx ;AX <==> BX 2 mov bl, cs:ucSndBuf[bx] ;BL = pulse byte 22 xchg ax, bx ;AX <==> BX 2 push dx ; 15 mov dx, cs:usSndPrt ;DX = D/A port 18 out dx, al pop dx ; 12 ;********************************************************** ; Perform TOD Interrupt Processing ;********************************************************** ALIGN 4 CSTTODChk LABEL NEAR NOTTODRET ;Exit if not TOD Int 121 pop ax ; 12 jmp cs:pfOldTimVec ; 04 CSTTODInt ENDP ;====================================================================== ; Disney Sound Source Interrupt service routine ;====================================================================== DSSPBKBUF MACRO LOCAL SndSmp ;********************************************************** ; Initialize index buffer pointer & Sample count ;********************************************************** push bx ; 15 push cx ; 15 push dx ; 15 mov dx, cs:usSndPrt ;DX = D/A port 18 mov bx, ax ;BX = buffer pointer 2 mov cx, cs:usSBfStp ;CX = buffer end 2 sub cx, ax ;CX = +/- Samples remaining 3 add cx, BUFMSK ;CX = abs (sample count) 4 and cx, BUFMSK ; 18 inc cx ;CX = Sample count (1 to n) 3 cmp cx, 16 ;CX = 1 to 16 ? jle SndSmp ;Yes, output remaining mov cx, 16 ;No, set to 16 ;********************************************************** ; Send 1 to 16 samples from circular buffer until full ;********************************************************** inc dx ;DX => Status port SndSmp: in al, dx ;Check status 08 test al, 40h ;Full? 04 jnz SmpDon ;Yes, exit loop 04 dec dx ;DX => I/O port 03 inc bx ;Increment index 3 and bx, BUFMSK ;Trim to less than 16K 18 mov al, cs:ucSndBuf[bx] ;AL = pulse byte 22 out dx, al ; 08 add dx, 2 ;DX => Control port 04 mov al, cs:ucStbLow ; 10 out dx, al ; 08 nop ; 03 nop nop nop mov al, cs:ucStbHgh ; 10 out dx, al ; 08 dec dx ;DX => Control port 03 loop SndSmp ; 17 ;********************************************************** ;********************************************************** SmpDon: mov cs:usSBfPtr, bx ;Store it back 19 pop dx ; 12 pop cx ; 12 pop bx ; 12 ENDM ;====================================================================== ;====================================================================== ; Timing: 88 ; ---------- ALIGN 4 DSSTODInt PROC FAR ; 51 PUBLIC DSSTODPbk, DSSTODChk push ax ; 15 ;********************************************************** ;********************************************************** jmp cs:usSndFnc ; 20 ;********************************************************** ; Play file at 1x speed ;********************************************************** ALIGN 4 DSSTODPbk LABEL NEAR mov ax, cs:usSBfPtr ;AX = sound buffer index 18 cmp ax, cs:usSBfStp ;End of Buffer? 18 je DSSTODChk ; 4 ;********************************************************** ; Initialize index buffer pointer & Sample count ; Send 1 to 16 samples from circular buffer ;********************************************************** DSSPBKBUF ; xx ;********************************************************** ; Perform TOD Interrupt Processing ;********************************************************** ALIGN 4 DSSTODChk LABEL NEAR NOTTODRET ;Exit if not TOD Int 121 pop ax ; 12 jmp cs:pfOldTimVec ; 04 DSSTODInt ENDP ;====================================================================== ; Speaker Interrupt service routine ;====================================================================== ; Abs worst case: 388 clock cycles (350 cycles = 74 uS) @ 210nS/ cycle ; (350 cycles = 44 uS) @ 125nS/ cycle ; Typ loading: 321 cycles ; Timing: 88 ; ---------- ALIGN 4 SpkTODInt PROC FAR ; 51 PUBLIC SpkTODPbk, SpkTODChk push ax ; 15 ;********************************************************** ;********************************************************** jmp cs:usSndFnc ; 20 ;********************************************************** ; Play file at 1x speed ;********************************************************** ALIGN 4 SpkTODPbk LABEL NEAR mov ax, cs:usSBfPtr ;AX = speaker buffer index 18 cmp ax, cs:usSBfStp ;End of Buffer? 18 je SpkTODChk ; 4 ;********************************************************** ; Increment circular buffer pointer ;********************************************************** inc ax ;Increment index 3 and ax, BUFMSK ;Trim to less than 16K 18 mov cs:usSBfPtr, ax ;Store it back 19 ;*********************************************************** ; Set up speaker one-shot timer ;*********************************************************** xchg ax, bx ;AX <==> BX 2 mov bh, cs:ucSndBuf[bx] ;Get pulse byte 22 xchg ax, bx ;AX <==> BX 2 mov al, TMLOXX ;Load spkr timer mode, load low 4 out TCPORT, al ;Set speaker timer mode 14 mov al, ah ; 2 out TDSPKR, al ;Set low count byte (838 ns) 14 ;********************************************************** ; Perform TOD Processing & Insure SPKR/GATE bits set ;********************************************************** NOTTODRET ;Exit if not TOD Int 121 in al, PIPORT ;Get current PIO contents or al, 3h ;Set Spkr=1 || Gate=1 out PIPORT, al ;Set PIO ;********************************************************** ;********************************************************** pop ax ; 12 jmp cs:pfOldTimVec ; 04 ;********************************************************** ; Perform TOD Interrupt Processing Only ;********************************************************** ALIGN 4 SpkTODChk LABEL NEAR NOTTODRET ;Exit if not TOD Int 121 pop ax ; 12 jmp cs:pfOldTimVec ; 04 SpkTODInt ENDP ;********************************************************************** ;********************************************************************** end