{ 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