{ File: Buffer.asm
Modification History:
last modification by Jim Frandeen: September 15, 1982 4:53 PM: Initialize KeyMap in the IO Page.
last modification by Jim Frandeen: August 9, 1982 4:15 PM: Add BlockBuffer for Processor ReadBlock and WriteBlock commands. Put initial code and Burdock code in the Floppy buffer.
last modification by Jim Frandeen: April 22, 1982 1:05 PM: Rewrite RS232C
}
{ This file contains the allocation of the large buffer areas for Domino. The buffers are allocated at the end of the code, so that they do not take up room during the loading of Domino during booting. This module should always be the LAST module in the Domino
configuration. }
GET "RS232CDefs.asm"
GET "SysDefs.asm"
GET "CommonDefs.asm"
IMP CheckCPDmaComplete ;CPSubs
IMP ClearMiscControl1Bit ;Common
IMP DisableRST ;Common
IMP GetTOD ;BookKeepingTask
IMP MainLoop ;BookKeepingTask
IMP ProcData0 ;BookKeepingTask
IMP ProcData1 ;BookKeepingTask
IMP ProcData2 ;BookKeepingTask
IMP PutMPanel ;Common
IMP ReadKeyboard ;BookKeepingTask
IMP ResetProcessorCommand ;BookKeepingTask
IMP SetMiscControl1Bit ;Common
IMP StartCPReadDma ;CPSubs
IMP StartCPWriteDma ;CPSubs
IMP TransferProcessorCSB ;BookKeepingTask
IMP Wait ;Common
EXP BlockBuffer
EXP DoReadIOPCmd
EXP DoReadUmbilicalBlockCmd
EXP DoWriteIOPCmd
EXP DoWriteUmbilicalBlockCmd
EXP EndFDBuffer ; FloppyTask buffer
EXP FDBuffer0 ; FloppyTask buffer
EXP FDBuffer1 ; FloppyTask buffer
EXP RxFIFO ; For RS232CTask
EXP Start
EXP StartFDBuffer ; FloppyTask buffer
EXP TxBuffer
; RS232C Task Buffers
TxBuffer:
DS TxBufferSize ; Tx Data Buffer
RxFIFO:
DS RxFifoSize ; Rx Data Buffer
;
{ Floppy Task buffers:
Note that the Start code and the Burdock code is in the Floppy buffers. This means that the Burdock code cannot be used if the Floppy has been used.
(Each buffer is large enough to hold a one page sector):
(The area from StartFDBuffer to EndFDBuffer can hold 4 standard Sectors)}
;
StartFDBuffer:
BlockBuffer:
ds 0
FDBuffer0:
ds 0
Start:
DI ;For Initializing
LXI SP,UserStkStart ;Initialize user stack pointer
MVI A,ResetRst75+Rst75DisableMsk+Rst65DisableMsk
CALL DisableRST ;Disable RST 6.5 and 7.5, clear 7.5 FF (RS232C, Floppy)
MVI A,DisableFDC ;Disable floppy controller, Enable Waits
OUT FDCState
IN DmaStatus ;Clear the DMA status register
XRA A ;Clear A
OUT DmaMode ;Disable controller
EI ;For mouse halting
CMA ;Set all clock bits high
OUT MiscClocks1
LXI H,MPStartDomino ;Initialize the Maintenance Panel
CALL PutMPanel ;MP ← StartDomino (500)
OUT MouseClr ;Clear hardware counters
MVI A,KBDiag ;Set KB diag mode
CALL SetMiscControl1Bit
LXI H,KBDiagWait ;Initialize delay for KBDiag signal
CALL Wait ;Wait 15 msec
MVI A,nKBDiag ;Clear KB diag mode
CALL ClearMiscControl1Bit ;clear bit in register
{Initialize the TOD state.}
LXI H,MPInitTOD
CALL PutMPanel ;MP ← InitTOD (501)
CALL GetTOD
LXI H,MPInitTODDone
CALL PutMPanel ;MP ← InitTODDone (502) and RET
CALL ReadKeyboard ;Initialize KeyMap in IO Page
JMP MainLoop
LastStartInstruction DS 0
StartCodeCount EQU LastStartInstruction-Start
ds 512-StartCodeCount
FDBuffer1:
ds 1024
;
StartBurdockCode:
BlockPCB:
;This PortControlBlock is used to transfer data to and from the CP for the ReadBlock and WriteBlock Processor commands.
BlockAddressLo:
DW 0
BlockAddressHi:
DW 0
BlockByteCount:
DW 0
DW BlockBuffer
TimeOutConst equ 0A000H ; Approx. .25 sec
DoReadIOPCmd:
{Command 5: Do Read IOP Command. The address of the byte to read is in ProcData2. The byte read will be returned in the low byte of ProcData1.}
LHLD ProcData2 ;HL ← memory address
MOV A,M ;A ← byte
STA ProcData1
JMP TransferProcessorCSB
DoWriteIOPCmd:
{Command 6: Do Write IOP Command. The address of the byte to write is in ProcData2. The low byte of ProcData1 contains the byte to write.}
LHLD ProcData2 ;HL ← memory address
LDA ProcData1 ;A ← byte to write
MOV M,A ;Write byte to IOP memory
JMP ResetProcessorCommand
DoReadUmbilicalBlockCmd:
{Command 7: Do Read Umbilical Block Command. ProcData2 contains the number of bytes to write in the high order byte. ProcData1 and ProcData0 contain a Long Pointer to the user's buffer area. This area must be resident. Set up the PCB to transfer the data between CP virtual memory and BlockBuffer. NOTE: the FLoppy buffer is used for the DMA transfer. This means we can't be doing floppy operaions at the same time, and the buffer is limited to 1536 bytes.}
LHLD ProcData1
SHLD BlockAddressLo
LHLD ProcData0
SHLD BlockAddressHi
LHLD ProcData2
SHLD BlockCopyCount
INX H ;Make the count even
MOV A,L
ANI 0FEH
MOV L,A
SHLD BlockByteCount
LXI D,BlockBuffer ;DE ← IOP Buffer address
ReadBlockLoop:
{Now wait to determine whether Burdock is there. The inner loop is approximately 49 cycles (~= 17 usec). The delay is approximately 17 * TimeOutConst usec.}
LXI H,TimeOutConst ; [10] Time-out constant
WaitToReadByte:
IN AltoPPIC
ANI IntBMask ;[7]
JNZ ReadByte ;[7] nz => Byte is ready
DCX H ;[6]
MOV A,H ;[4]
ORA L ;[4]
JNZ WaitToReadByte ;[10]
JMP SetUmbilicalReturnCode
ReadByte:
IN AltoPPIB
STAX D ;Store byte in buffer
INX D ;Increment buffer address
LHLD BlockCopyCount
DCX H
SHLD BlockCopyCount
MOV A,H
ORA L
JNZ ReadBlockLoop
LXI H,BlockPCB
CALL StartCPWriteDma ;Send block to CP
WaitForUmbilicalBlockTransfer:
{Wait for the transfer to complete. It would take extra code to pass control to the next task. Since we only use this for Burdock, it won't hurt to wait for the DMA.}
CALL CheckCPDmaComplete
JZ WaitForUmbilicalBlockTransfer
JMP SetUmbilicalReturnCode
DoWriteUmbilicalBlockCmd:
{Command 7: Do Write Umbilical Block Command. ProcData2 contains the number of bytes to write in the high order byte. ProcData1 and ProcData0 contain a Long Pointer to the user's buffer area. This area must be resident. Set up the PCB to transfer the data between CP virtual memory and BlockBuffer. NOTE: the FLoppy buffer is used for the DMA transfer. This means we can't be doing floppy operaions at the same time, and the buffer is limited to 1536 bytes.}
LHLD ProcData1
SHLD BlockAddressLo
LHLD ProcData0
SHLD BlockAddressHi
LHLD ProcData2
SHLD BlockCopyCount
INX H ;Make the count even
MOV A,L
ANI 0FEH
MOV L,A
SHLD BlockByteCount
LXI H,BlockPCB
CALL StartCPReadDma ;Read block from CP
WaitForWriteBlock:
{Wait for the transfer to complete. It would take extra code to pass control to the next task. Since we only use this for Burdock, it won't hurt to wait for the DMA.}
CALL CheckCPDmaComplete
JZ WaitForWriteBlock
LXI D,BlockBuffer ;DE ← IOP Buffer address
WriteBlockLoop:
LDAX D ;A ← next byte from buffer
OUT AltoPPIA ;Write data
{Now wait to determine whether Burdock is there. The inner loop is approximately 49 cycles (~= 17 usec). The delay is approximately 17 * TimeOutConst usec.}
LXI H,TimeOutConst ; [10] Time-out constant
WaitAckLoop:
IN AltoPPIC ;[11] Read Channel B interrupt
ANI IntAMask ;[7]
JNZ NextByte ;[7] nz => Burdock took byte
DCX H ;[6]
MOV A,H ;[4]
ORA L ;[4]
JNZ WaitAckLoop ;[10]
SetUmbilicalReturnCode:
LHLD BlockCopyCount ;Will be zero if
SHLD ProcData0 ;all bytes transferred
JMP TransferProcessorCSB
NextByte:
INX D ;Increment buffer address
DB opLXIH ;HL ← BlockCopyCount
BlockCopyCount:
DW 0
DCX H
SHLD BlockCopyCount
MOV A,H
ORA L
JNZ WriteBlockLoop
JMP SetUmbilicalReturnCode
LastBurdockInstruction: DS 0
BurdockInstructionCount EQU LastBurdockInstruction-StartBurdockCode
ds 512-BurdockInstructionCount
;
EndFDBuffer:
ds 0
;-----------------------------------------------------
NextLoc:
ds 1 ; Next free location
END Buffer