mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-03-02 18:14:55 +00:00
39 lines
16 KiB
Plaintext
39 lines
16 KiB
Plaintext
head 1.1;
|
||
branch 1.1.1;
|
||
access ;
|
||
symbols start:1.1.1.1 Xerox:1.1.1;
|
||
locks ; strict;
|
||
comment @;; @;
|
||
|
||
|
||
1.1
|
||
date 2001.08.12.22.22.29; author freier; state Exp;
|
||
branches 1.1.1.1;
|
||
next ;
|
||
|
||
1.1.1.1
|
||
date 2001.08.12.22.22.29; author freier; state Exp;
|
||
branches ;
|
||
next ;
|
||
|
||
|
||
desc
|
||
@@
|
||
|
||
|
||
|
||
1.1
|
||
log
|
||
@Initial revision
|
||
@
|
||
text
|
||
@{ File: [Iris]<WMicro>DLion>VoiceTask.asm
|
||
|
||
Modification History:
|
||
Dennis DEG : 1-Sep-84 17:18:53 Added copyright notice.
|
||
Dennis DEG : 7-Jun-83 9:40:54
|
||
Dennis DEG : 14-Apr-83 8:52:33 variable baud rates for slow link.
|
||
Dennis DEG : 28-Jan-83 11:58:18
|
||
Jim JXF : October 21, 1982 10:55 AM
|
||
Created by Jim JXF : 21-Sep-82 13:20:50
|
||
}
|
||
|
||
{ Copyright (C) 1982, 1983 by Xerox Corporation. All rights reserved.}
|
||
|
||
|
||
Get "SysDefs"
|
||
Get "CommonDefs"
|
||
|
||
IMP ClearDmaChannel ; From DmaSubs
|
||
IMP DoNakedNotify ; From CPSubs
|
||
IMP DmaActive ; From DmaSubs
|
||
IMP MainLoop ; From BookKeepingTask
|
||
IMP PortBusyFlag ; From CPSubs
|
||
IMP ReadCPBuffer ; From CPsubs
|
||
IMP RS232CInterruptSwitch ; From Common
|
||
IMP RS232CMiscTask
|
||
IMP StartCPReadDMA ; From CPsubs
|
||
IMP CheckCPDmaComplete ; From CPsubs
|
||
IMP VoiceCommand ; From BookKeepingTask
|
||
IMP VoiceSwitch ; From RS232CMiscTask
|
||
IMP WriteCPBuffer ; From CPsubs
|
||
IMP SpeechOutBuffer0 ; From Buffer
|
||
IMP SpeechOutBuffer1 ; From Buffer
|
||
IMP SpeechInBuffer0 ; From Buffer
|
||
IMP SpeechInBuffer1 ; From Buffer
|
||
IMP EnableRST ; From Common
|
||
IMP DisableRST ; From Common
|
||
|
||
EXP VoiceCommandTask
|
||
|
||
; VOICE BOX DEFINITIONS (to go in SysDefs)
|
||
|
||
VoiceStatusRegister EQU 0C0H
|
||
VoiceControlRegister EQU 0C0H
|
||
VoiceResetRegister EQU 0C2H
|
||
VoiceRxReady EQU 80H
|
||
VoiceTxReady EQU 40H
|
||
VoiceUartControl EQU 0CFH
|
||
VoiceUartData EQU 0CEH
|
||
VoiceUartStatus EQU 0CFH
|
||
VoiceInternalReset EQU 40H
|
||
VoiceTxEnable EQU 1
|
||
VoiceRxEnable EQU 4
|
||
EnableFrameSync EQU 20H
|
||
EnableSpeechIn EQU 80H
|
||
EnableSpeechOut EQU 40H
|
||
EnableSpeechLoopBack EQU 10H
|
||
SpeechBaudRate300 EQU 0
|
||
SpeechBaudRate600 EQU 4
|
||
SpeechBaudRate1200 EQU 8
|
||
SpeechBaudRate2400 EQU 0CH
|
||
|
||
; VOICE BOX DEFINITIONS (to go in CommonDefs)
|
||
|
||
VoiceCSBLoc EQU 0FF66H
|
||
VoiceCommandBufferLoc EQU 0FF6FH
|
||
VoiceCommandLoc EQU 0FF18H ;same as RS232CMiscFlagLoc
|
||
VoiceBoxMessageLoc EQU 0FF65H
|
||
VoiceGetCommandLoc EQU 0FF1AH ;same as RS232CGetFlagLoc
|
||
VoicePutCommandLoc EQU 0FF19H ;same as RS232CPutFlagLoc
|
||
;
|
||
; VOICE BOX DEFINITIONS (for internal use)
|
||
|
||
ClearSpeechInterruptFF EQU 0C3H
|
||
KnownMode EQU 80H
|
||
NumberOfCommands EQU 11
|
||
WriteDma EQU 40H
|
||
ReadDma EQU 80H
|
||
EnSODma EQU 8H
|
||
EnSIDma EQU 4H
|
||
TerminalCountStop EQU 40H
|
||
SpeechChannels EQU EnSODma+EnSIDma
|
||
SOChannelMask EQU EnSODma+TerminalCountStop
|
||
SIChannelMask EQU EnSIDma+TerminalCountStop
|
||
SpeechDmaIntr EQU 2
|
||
TwoTimesNumberOfCommands EQU NumberOfCommands+NumberOfCommands
|
||
VoiceBoxMode EQU 4EH ;Async, 1 stop bit, no parity, 8 bit length, 16x
|
||
Rst65Mask EQU 2
|
||
|
||
VoiceCommandTask:
|
||
{This task executes commands specified by VoiceCommand: StartVoiceBox, StopVoiceBox, VoiceBoxCommand.}
|
||
|
||
{Whenever we start a DMA operation we modify this entry point to check for a DMA complete. Otherwise we just continue with the StartVoiceCommandTask}
|
||
DB opJMP
|
||
VoiceCommandContinueAddress:
|
||
DW StartVoiceCommandTask
|
||
;either
|
||
; JMP WaitForCommandString
|
||
;or
|
||
; JMP StartVoiceCommandTask
|
||
|
||
StartVoiceCommandTask:
|
||
LDA PortBusyFlag
|
||
ORA A
|
||
JNZ VoiceCommandTaskYield
|
||
|
||
DB opJMP
|
||
VoiceCommandTaskResumeAddress:
|
||
DW BeginVoiceCommandTask
|
||
; JMP SendVoiceBoxCommandCharacters
|
||
|
||
|
||
VoiceCSB:
|
||
NakedMask:
|
||
DW 0
|
||
GetByteCount:
|
||
DW 0
|
||
PutByteCount:
|
||
DW 0
|
||
GetBufferPtrLo:
|
||
DB 0
|
||
GetBufferPtrMid:
|
||
DB 0
|
||
GetBufferPtrHi:
|
||
DB 0
|
||
DB 0 ;not used
|
||
GetBufferByteCount:
|
||
DW 0
|
||
PutBufferPtrLo:
|
||
DB 0
|
||
PutBufferPtrMid:
|
||
DB 0
|
||
PutBufferPtrHi:
|
||
DB 0
|
||
DB 0 ;not used
|
||
PutBufferByteCount:
|
||
DW 0
|
||
VoiceCSBSize: EQU 18
|
||
|
||
VoiceCommandBuffer:
|
||
DS 10
|
||
DB 0 ;high order of CommandByteCount
|
||
CommandByteCount:
|
||
DB 0
|
||
VoiceCommandSize: EQU 12
|
||
|
||
ResetCommand:
|
||
DB 0
|
||
VoiceStatus:
|
||
DB 0 ;0 = success
|
||
{ 4 = overrun
|
||
8 = parity error
|
||
10 = overflow error
|
||
20 = frame error
|
||
40 = break
|
||
80 = good completion
|
||
}
|
||
|
||
CharacterReceivedFlag:
|
||
DB 0 ; = 80H if CP has not processed character
|
||
VoiceBoxCharacter:
|
||
DB 0 ;character received from VoiceBox
|
||
|
||
GetStatus:
|
||
DW 0
|
||
GetStatusHighByte EQU GetStatus+1
|
||
|
||
PutStatus:
|
||
DW 0
|
||
PutStatusHighByte EQU PutStatus+1
|
||
|
||
; PCB to read Voice CSB
|
||
PCBReadVoiceCSB:
|
||
DW VoiceCSBLoc ;CP Buffer Pointer(Low)
|
||
DW CPIOPageHi ;CP Buffer Pointer(Hi)
|
||
DW VoiceCSBSize ;CP Buffer Count (Bytes)
|
||
DW VoiceCSB ;Pointer to IOP Buffer
|
||
|
||
; PCB to read VoiceCommandBuffer and the CommandByteCount
|
||
PCBReadVoiceBoxCommand:
|
||
DW VoiceCommandBufferLoc ;CP Buffer Pointer(Low)
|
||
DW CPIOPageHi ;CP Buffer Pointer(Hi)
|
||
DW VoiceCommandSize ;CP Buffer Count (Bytes)
|
||
DW VoiceCommandBuffer ;Pointer to IOP Buffer
|
||
|
||
; PCB to Reset Voice Command and return Status in low byte
|
||
PCBResetVoiceCommand:
|
||
DW VoiceCommandLoc ;CP Buffer Pointer(Low)
|
||
DW CPIOPageHi ;CP Buffer Pointer(Hi)
|
||
DW 2 ;CP Buffer Count (Bytes)
|
||
DW ResetCommand ;Pointer to IOP Buffer
|
||
|
||
; PCB to read and write VoiceBoxMessage
|
||
PCBVoiceBoxMessage:
|
||
DW VoiceBoxMessageLoc ;CP Buffer Pointer(Low)
|
||
DW CPIOPageHi ;CP Buffer Pointer(Hi)
|
||
DW 2 ;CP Buffer Count (Bytes)
|
||
DW CharacterReceivedFlag ;Pointer to IOP Buffer
|
||
|
||
; PCB to read/write getCommand.status
|
||
PCBGetStatus:
|
||
DW VoiceGetCommandLoc ;CP Buffer Pointer(Low)
|
||
DW CPIOPageHi ;CP Buffer Pointer(Hi)
|
||
DW 2 ;CP Buffer Count (Bytes)
|
||
DW GetStatus ;Pointer to IOP Buffer
|
||
|
||
; PCB to read/write putCommand.status
|
||
PCBPutStatus:
|
||
DW VoicePutCommandLoc ;CP Buffer Pointer(Low)
|
||
DW CPIOPageHi ;CP Buffer Pointer(Hi)
|
||
DW 2 ;CP Buffer Count (Bytes)
|
||
DW PutStatus ;Pointer to IOP Buffer
|
||
|
||
; PCB to get Digital Speech input data
|
||
PCBSpeechIn:
|
||
DW 0 ;CP Buffer Pointer(Low)
|
||
DW 0 ;CP Buffer Pointer(Hi)
|
||
DW 0 ;CP Buffer Count (Bytes)
|
||
DW 0 ;Pointer to IOP Buffer
|
||
|
||
; PCB to put Digital Speech output data
|
||
PCBSpeechOut:
|
||
DW 0 ;CP Buffer Pointer(Low)
|
||
DW 0 ;CP Buffer Pointer(Hi)
|
||
DW 0 ;CP Buffer Count (Bytes)
|
||
DW 0 ;Pointer to IOP Buffer
|
||
|
||
|
||
SavedVoiceUartStatus:
|
||
DB 0
|
||
|
||
SOBuffer:
|
||
DW SpeechOutBuffer0
|
||
SOBufferNext:
|
||
DW SpeechOutBuffer1
|
||
|
||
SpeechBaudRate:
|
||
DB SpeechBaudRate1200
|
||
;
|
||
SODMAStart:
|
||
LHLD PCBSpeechOut+4
|
||
DCX H
|
||
MOV A,L
|
||
OUT DmaCh3Count
|
||
MOV A,H
|
||
ORI ReadDma
|
||
OUT DmaCh3Count
|
||
LHLD PCBSpeechOut+6
|
||
MOV A,L
|
||
OUT DmaCh3Addr
|
||
MOV A,H
|
||
OUT DmaCh3Addr
|
||
LDA DmaActive
|
||
MOV H,A
|
||
XRA A
|
||
OUT DmaMode
|
||
IN DmaStatus
|
||
CMA
|
||
ANA H
|
||
ORI SOChannelMask
|
||
OUT DmaMode
|
||
STA DmaActive
|
||
LDA VoiceControllerMode
|
||
ORI EnableSpeechOut
|
||
STA VoiceControllerMode
|
||
OUT VoiceControlRegister
|
||
RET
|
||
|
||
SIDMAStart:
|
||
LHLD PCBSpeechIn+4
|
||
DCX H
|
||
MOV A,L
|
||
OUT DmaCh2Count
|
||
MOV A,H
|
||
ORI ReadDma
|
||
OUT DmaCh2Count
|
||
LHLD PCBSpeechIn+6
|
||
MOV A,L
|
||
OUT DmaCh2Addr
|
||
MOV A,H
|
||
OUT DmaCh2Addr
|
||
LDA DmaActive
|
||
MOV H,A
|
||
XRA A
|
||
OUT DmaMode
|
||
IN DmaStatus
|
||
CMA
|
||
ANA H
|
||
ORI SIChannelMask
|
||
OUT DmaMode
|
||
STA DmaActive
|
||
LDA VoiceControllerMode
|
||
ORI EnableSpeechIn
|
||
STA VoiceControllerMode
|
||
OUT VoiceControlRegister
|
||
RET
|
||
|
||
BeginVoiceCommandTask:
|
||
{When we come here, we know the CP port is free.}
|
||
|
||
{We will now compute the address of the routine to execute and then branch to that routine}
|
||
LDA VoiceCommand
|
||
|
||
ADD A ;Multiply command by 2
|
||
JZ VoiceCommandTaskYield ;Added to make idle loop faster
|
||
CPI TwoTimesNumberOfCommands ;{Something fishy about EQU Statements}
|
||
JP IllegalVoiceCommand
|
||
LXI H,CommandJumpTable ;Get base address of table of pointers to command routines.
|
||
ADD L ;Add in the offset
|
||
MOV L,A ;Update the low part of the register
|
||
JNC JumpToCommand ;If no carry we can branch to routine now.
|
||
INR H ;Correct the high byte first.
|
||
JumpToCommand:
|
||
MOV A,M
|
||
INX H
|
||
MOV H,M
|
||
MOV L,A
|
||
PCHL ;Do that command.
|
||
|
||
CommandJumpTable:
|
||
DW VoiceCommandTaskYield ;No command to be processed.
|
||
DW StartVoiceBox ;Command = 1
|
||
DW StopVoiceBox
|
||
DW VoiceOutTask
|
||
DW AbortVoiceIn
|
||
DW AbortVoiceOut
|
||
DW AbortVoiceCommand
|
||
DW Set300Baud
|
||
DW Set600Baud
|
||
DW Set1200Baud
|
||
DW Set2400Baud
|
||
EndCommandJumpTable:
|
||
|
||
{Illegal voice command.}
|
||
IllegalVoiceCommand:
|
||
BREAK
|
||
JMP ResetVoiceCommand ;For debugging only
|
||
|
||
VoiceControllerMode:
|
||
DB 0
|
||
|
||
VoiceInterrupt:
|
||
PUSH PSW
|
||
PUSH D
|
||
|
||
{This next section of code is a streamlined section of ReadDmaCompletion from DmaSubs. Since we are in a section of code with the interrupts disabled we do not want to waste precious time. Also, if the floppy is running then ReadDmaCompletion would re-enable interrupts before we were ready to have them re-enabled.}
|
||
LDA DmaActive ;D ¬ DmaActive
|
||
MOV D,A
|
||
IN DmaStatus ;Get the completed channels
|
||
MOV E,A ;Save a copy
|
||
CMA ;Form complement mask of completed channels
|
||
ANA D ;Clear channels in DmaActive
|
||
STA DmaActive ;Store back in DmaActive
|
||
MVI A,DmaCh3Mask ;Check for Speech Out Completion
|
||
ANA E
|
||
DB opORI ;Mask in old flag state
|
||
SpeechOutFlag:
|
||
DB 0
|
||
STA SpeechOutFlag ;Update flag state
|
||
MVI A,DmaCh2Mask ;Check for Speech In Completion
|
||
ANA E
|
||
DB opORI ;Mask in old flag state
|
||
SpeechInFlag:
|
||
DB 0
|
||
STA SpeechInFlag ;Update flag state
|
||
OUT ClearSpeechInterruptFF
|
||
PUSH H
|
||
CheckSpeechIn:
|
||
LDA SpeechInFlag
|
||
MOV E,A ;Save SpeechInFlag
|
||
XRA A
|
||
STA SpeechInFlag ;Reset SpeechInFlag
|
||
ORA E ;A ¬ SpeechInFlag, Set Flags
|
||
JZ CheckSpeechOut
|
||
BREAK
|
||
CheckSpeechOut:
|
||
LDA SpeechOutFlag
|
||
MOV E,A ;Save SpeechOutFlag
|
||
XRA A
|
||
STA SpeechOutFlag ;Reset SpeechOutFlag
|
||
ORA E ;A ¬ SpeechInFlag, Set Flags
|
||
JZ ExitVoiceInterrupt
|
||
BREAK
|
||
DB opMVIA
|
||
SOIBufferMask:
|
||
DB 1
|
||
MOV E,A
|
||
MOV A,B
|
||
XRA E
|
||
MOV B,A
|
||
MVI A,3
|
||
SUB E
|
||
STA SOIBufferMask
|
||
ExitVoiceInterrupt:
|
||
POP H
|
||
POP D
|
||
POP PSW
|
||
EI
|
||
RET
|
||
|
||
AbortVoiceIn:
|
||
{Abort voice in over the DMA link. This is used by InitializeCleanup in the Head, e.g., when the Debugger is called.
|
||
Nothing to do here until the code for the DMA link is written.}
|
||
JMP StopVoiceBox
|
||
|
||
AbortVoiceOut:
|
||
{Abort voice out over the DMA link. This is used by InitializeCleanup in the Head, e.g., when the Debugger is called.
|
||
Nothing to do here until the code for the DMA link is written.}
|
||
JMP StopVoiceBox
|
||
|
||
Set300Baud:
|
||
MVI A,SpeechBaudRate300
|
||
JMP SetBaudRate
|
||
|
||
Set600Baud:
|
||
MVI A,SpeechBaudRate600
|
||
JMP SetBaudRate
|
||
|
||
Set1200Baud:
|
||
MVI A,SpeechBaudRate1200
|
||
JMP SetBaudRate
|
||
|
||
Set2400Baud:
|
||
MVI A,SpeechBaudRate2400
|
||
|
||
SetBaudRate:
|
||
STA SpeechBaudRate
|
||
|
||
AbortVoiceCommand:
|
||
{We should only get this command if we are waiting for the VoiceBox to be ready to send a character. We might get this command here due to a race condition.}
|
||
JMP ResetVoiceCommand
|
||
|
||
StartVoiceBox:
|
||
MVI A,SpeechChannels
|
||
CALL ClearDmaChannel
|
||
LXI H,VoiceInterrupt ;Get address for Interrupt Service Subroutine (RST 6.5)
|
||
SHLD RS232CInterruptSwitch ;Store address to vector interrupt
|
||
|
||
LXI H,PCBReadVoiceCSB
|
||
CALL ReadCPBuffer ;Read Voice CSB
|
||
|
||
MOV L,C ;Save the contents of the BC register pair
|
||
MOV H,B
|
||
SHLD SavedBC
|
||
|
||
OUT VoiceResetRegister ;Make sure the Voice hardware is initialized correctly.
|
||
|
||
{Set speech baud rate.}
|
||
LDA SpeechBaudRate
|
||
ORI EnableFrameSync+SpeechDmaIntr
|
||
STA VoiceControllerMode
|
||
OUT VoiceControlRegister
|
||
|
||
{Enable interrupts on 6.5 line}
|
||
MVI A,Rst65Mask
|
||
CALL EnableRST
|
||
|
||
{Reset VoiceBox UART}
|
||
MVI A,KnownMode ;Force UART into a known state
|
||
OUT VoiceUartControl
|
||
XRA A ;Clear the Accumulator
|
||
OUT VoiceUartControl ;Clear the UART registers
|
||
MVI A,VoiceInternalReset
|
||
OUT VoiceUartControl ;Reset voice box
|
||
|
||
{Set up Mode instruction: Async mode, 1 stop bit, no parity, 8 bit length, 16x}
|
||
MVI A,VoiceBoxMode
|
||
OUT VoiceUartControl
|
||
|
||
{Set up command instruction: Enable Transmit, Enable Receive}
|
||
MVI A,VoiceTxEnable+VoiceRxEnable
|
||
OUT VoiceUartControl
|
||
LXI B,0 ;Since voice and RS232C cannot be used simultaneously we can take advantage of the BC register pair.
|
||
JMP ResetVoiceCommand ;VoiceBox should now be started.
|
||
|
||
StopVoiceBox:
|
||
{Disable interrupts on 6.5 line}
|
||
MVI A,Rst65Mask
|
||
CALL DisableRST
|
||
|
||
DB opLXIB
|
||
SavedBC:
|
||
DW 0 ;we have saved the BC register pair here when we started the Voice Box
|
||
MVI A,SpeechChannels
|
||
CALL ClearDmaChannel
|
||
XRA A ;Disable Frame Sync and shut off digital speech
|
||
OUT VoiceControlRegister
|
||
LXI H,RS232CMiscTask
|
||
SHLD VoiceSwitch ;Enable RS232
|
||
|
||
JMP ResetVoiceCommand
|
||
|
||
VoiceOutTask:
|
||
{Send characters to the VoiceBox over the slow RS232 link. First read in the VoiceCommandBuffer and the CommandByteCount.}
|
||
|
||
LXI H,PCBReadVoiceBoxCommand
|
||
|
||
{Note that we must use The DMA channel to read in the command buffer. This is because the command buffer is in the form of a text string. Each word must be transferred from the CP as follows: high byte of CP word to low byte of IOP word, low byte of CP word to high byte of IOP word. Note that this also reverses the bytes of the count. We only look at the low order byte, which is stored in our high order byte.}
|
||
CALL StartCPReadDma
|
||
|
||
{Wait for the Transfer to complete.}
|
||
LXI H,VoiceCommandBuffer ;Set up pointer to the command characters
|
||
SHLD NextCommandCharacterPtr
|
||
LXI H,WaitForCommandString ;Fix entry to VoiceTask to check
|
||
SHLD VoiceCommandContinueAddress ;for DMA complete.
|
||
|
||
WaitForCommandString:
|
||
CALL CheckCPDmaComplete ;If DMA is complete PortBusyFlag is reset
|
||
JZ VoiceCommandTaskYield
|
||
|
||
LXI H,StartVoiceCommandTask ;DMA completed so fix up entry
|
||
SHLD VoiceCommandContinueAddress ;point to VoiceTask
|
||
LXI H,SendVoiceBoxCommandCharacters
|
||
SHLD VoiceCommandTaskResumeAddress
|
||
|
||
SendVoiceBoxCommandCharacters:
|
||
IN VoiceStatusRegister
|
||
ANI VoiceTxReady
|
||
JZ SendNextVoiceBoxCharacter
|
||
|
||
{The VoiceBox is not yet ready for a character. Check VoiceBoxCommand to see if the Head wants to abort the command.}
|
||
LDA VoiceCommand
|
||
CPI 6
|
||
JNZ VoiceCommandTaskYield
|
||
JMP CommandCharactersSent
|
||
|
||
SendNextVoiceBoxCharacter:
|
||
{The VoiceBox is ready for the next character.}
|
||
DB opLXIH ;HL ¬ NextCommandCharacterPtr
|
||
NextCommandCharacterPtr:
|
||
DW 0
|
||
MOV A,M ;A ¬ NextCommandCharacter
|
||
OUT VoiceUartData ;Send next command character
|
||
INX H ;Point to next character
|
||
SHLD NextCommandCharacterPtr
|
||
LDA CommandByteCount
|
||
DCR A
|
||
STA CommandByteCount
|
||
JNZ VoiceCommandTaskYield ;Jump if not last command character
|
||
|
||
CommandCharactersSent:
|
||
{Continue if the last command character has been sent to the VoiceBox.}
|
||
LXI H,BeginVoiceCommandTask
|
||
SHLD VoiceCommandTaskResumeAddress
|
||
|
||
ResetVoiceCommand:
|
||
LXI H,PCBResetVoiceCommand
|
||
CALL WriteCPBuffer
|
||
|
||
VoiceCommandTaskYield:
|
||
DS 0
|
||
;
|
||
VoiceInTask:
|
||
{The voice input task reads characters from the VoiceBox over the slow RS232C link and sends them to the CP. This task is activated by StartVoiceBox.}
|
||
LDA PortBusyFlag
|
||
ORA A
|
||
JNZ VoiceInTaskYield ;Jump if port is busy
|
||
IN VoiceStatusRegister
|
||
ANI VoiceRxReady ;See if input character is waiting
|
||
JNZ VoiceInTaskYield ;Yield if no character waiting
|
||
|
||
{Continue if a character from the voice box is ready. Read in the VoiceBoxMessage from the CP to see if the CP has processed the last character.}
|
||
LXI H,PCBVoiceBoxMessage
|
||
CALL ReadCPBuffer
|
||
LDA CharacterReceivedFlag ;Check CP Ready
|
||
ORA A ;See if CP has processed last char
|
||
MVI A,80H ;Set character received, assume no overrun
|
||
JZ StoreVoiceCompletion
|
||
|
||
{If the CP has not processed the last character, we have an overrun condition.}
|
||
MVI A,4 ;Set overrun
|
||
|
||
StoreVoiceCompletion:
|
||
STA CharacterReceivedFlag
|
||
IN VoiceUartData ;Read character from UART
|
||
SendVoiceBoxChar:
|
||
STA VoiceBoxCharacter
|
||
IN VoiceUartStatus
|
||
STA SavedVoiceUartStatus
|
||
{Check for break detected, Frame Error, Overflow Error, Parity Error}
|
||
ANI 78H
|
||
JZ NoVoiceTransmissionError
|
||
|
||
{Continue if transmission error. Return error code to the Head.}
|
||
STA CharacterReceivedFlag
|
||
|
||
NoVoiceTransmissionError:
|
||
LXI H,PCBVoiceBoxMessage
|
||
CALL WriteCPBuffer
|
||
LHLD NakedMask
|
||
CALL DoNakedNotify
|
||
|
||
VoiceInTaskYield:
|
||
SpeechInTask:
|
||
LDA PortBusyFlag
|
||
ORA A
|
||
JNZ SpeechInTaskYield ;Jump if port is busy
|
||
LXI H,PCBGetStatus
|
||
CALL ReadCPBuffer
|
||
LDA GetStatusHighByte
|
||
ORA A
|
||
JZ SpeechInTaskYield
|
||
DB opMVIA
|
||
SIBufferMask:
|
||
DB 1
|
||
ANA C
|
||
JNZ SpeechInTaskYield
|
||
BREAK
|
||
LDA SIBufferMask
|
||
MOV D,A
|
||
DI
|
||
ORA C
|
||
MOV C,A
|
||
EI
|
||
MVI A,3
|
||
SUB D
|
||
STA SIBufferMask
|
||
SpeechInTaskYield:
|
||
SpeechOutTask:
|
||
LDA PortBusyFlag
|
||
ORA A
|
||
JNZ SpeechOutTaskYield ;Jump if port is busy
|
||
LXI H,PCBPutStatus
|
||
CALL ReadCPBuffer
|
||
LDA PutStatusHighByte
|
||
ORA A
|
||
JZ SpeechOutTaskYield
|
||
DB opMVIA ;Load current Speech Out buffer mask
|
||
SOBufferMask:
|
||
DB 1
|
||
ANA B ;Check for buffer available
|
||
JNZ SpeechOutTaskYield
|
||
LHLD PutBufferPtrLo
|
||
SHLD PCBSpeechOut
|
||
LHLD PutBufferPtrHi
|
||
SHLD PCBSpeechOut+2
|
||
LHLD PutBufferByteCount
|
||
SHLD PCBSpeechOut+4
|
||
LHLD SOBuffer
|
||
SHLD PCBSpeechOut+6
|
||
MOV D,H
|
||
MOV E,L
|
||
LHLD SOBufferNext
|
||
SHLD SOBuffer
|
||
XCHG
|
||
SHLD SOBufferNext
|
||
LXI H,PCBSpeechOut
|
||
CALL ReadCPBuffer
|
||
CALL SODMAStart
|
||
LDA SOBufferMask
|
||
MOV D,A
|
||
DI
|
||
ORA B
|
||
MOV B,A
|
||
EI
|
||
MVI A,3
|
||
SUB D
|
||
STA SOBufferMask
|
||
XRA A
|
||
STA PutStatusHighByte
|
||
LXI H,PCBPutStatus
|
||
CALL WriteCPBuffer
|
||
LHLD PutBufferByteCount
|
||
SHLD PutByteCount
|
||
LHLD NakedMask
|
||
CALL DoNakedNotify
|
||
SpeechOutTaskYield:
|
||
{Continue to the next task. This is the last task in Domino.cfg, so we jump back to the top of the round-robin task management.}
|
||
JMP MainLoop
|
||
|
||
END
|
||
@
|
||
|
||
|
||
1.1.1.1
|
||
log
|
||
@first add
|
||
@
|
||
text
|
||
@@
|