{  File: SmallDominoBuffer.asm
Modification History:
	DEG     .PA:	 6-Oct-84  0:15:06: Add 1984 to the copyright notice
	DEG     .PA:	 1-Sep-84 18:45:55: Add copyright notice
	JMM   .PA:	26-Oct-83 10:16:16: release some space for burdock version of SmallDomino.bin
	DEG     .PA:   9-Oct-83 13:28:03: Fix up kludges.
	DEG     .PA:  26-Sep-83 22:54:07: Fold in Hals changes for Burdock.
	DEG     .PA:  12-Apr-83 20:08:14: Overlay the voice and RS232C Buffers.
	Jim JXF     :  September 15, 1982  4:53 PM: Initialize KeyMap in the IO Page.
	Jim JXF     :  August 9, 1982  4:15 PM: Add BlockBuffer for Processor ReadBlock and WriteBlock commands. Put initial code and Burdock code in the Floppy buffer.
	Jim JXF     :  April 22, 1982  1:05 PM: Rewrite RS232C
}

{ 	Copyright (C) 1982, 1983 by Xerox Corporation.  All rights reserved.}

{  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	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	SetMiscControl1Bit	;Common
	IMP	TransferProcessorCSB	;BookKeepingTask
	IMP	Wait		;Common

	EXP	EndFDBuffer	; FloppyTask buffer
	EXP	FDBuffer0	; FloppyTask buffer
	EXP	FDBuffer1	; FloppyTask buffer
	EXP	RxFIFO	 	; For RS232CTask
	EXP	Start
	EXP	StartFDBuffer	; FloppyTask buffer
{	EXP	SpeechOutBuffer0	; From Buffer
	EXP	SpeechOutBuffer1	; From Buffer
	EXP	SpeechInBuffer0		; From Buffer
	EXP	SpeechInBuffer1		; From Buffer
	}
	EXP	TxBuffer

; Burdock
	IMP	BurdockIOCB		;CPSubs
	IMP	ReadCPBuffer		;CPSubs
	IMP	WriteCPBuffer		;CPSubs
	IMP	StartCPReadDma		;CPSubs
	IMP	StartCPWriteDma		;CPSubs
	IMP	CheckCPDmaComplete	;CPSubs
	IMP	DoNakedNotify		;CPSubs
	IMP	ZeroCommand		;From Common

	EXP	OldReadUmbilical
	EXP	OldWriteUmbilical
	EXP	DoBurdockCmd

; Voice equates to eventually go into SysDefs.asm
VoiceBufferSize	EQU	512
TxRemBufferSize	EQU	TxBufferSize-(2*VoiceBufferSize)
VBSMinusTxRBS	EQU	VoiceBufferSize-TxRemBufferSize
RxRemBufferSize	EQU	RxFifoSize-VoiceBufferSize-VBSMinusTxRBS

; RS232C Task Buffers
TxBuffer:
{	DS	RxFifoSize+TxBufferSize  jmm&deg 13-Oct-83 16:21:14
	}
;	DS	4*VoiceBufferSize	(whichever is greater)

SpeechOutBuffer0	EQU	TxBuffer
SpeechOutBuffer1	EQU	SpeechOutBuffer0+VoiceBufferSize
SpeechInBuffer0		EQU	SpeechOutBuffer1+VoiceBufferSize
SpeechInBuffer1		EQU	SpeechInBuffer0+VoiceBufferSize
RxFIFO			EQU	TxBuffer+TxBufferSize

;
{  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:
BurdockDataBuffer:
	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
	
FD1BufferSize	EQU	1024

FDBuffer1:

{For the copyright notice to be readable in the microcode file every other character has to be switched.  It is important that the copyright notice be placed on an even boundary}

CopyrightNotice:
	DB	"oCypirhg tC( )9108 ,9118 ,9128 ,9138 ,9148b  yeXor xoCprrotaoi.n  lA lirhgstr sereev.d"
EndOfCopyrightNotice:

CopyrightNoticeLength	EQU	EndOfCopyrightNotice-CopyrightNotice


	ds	FD1BufferSize-CopyrightNoticeLength
;
StartBurdockCode:
TimeOutConst	equ	0A000H	;  Approx. .25 sec


OldReadUmbilical:
{Processor Command 7:  Read a Block of Data from the other IOP via the Umbilical box

ProcData2 contains the number of bytes to transfer. ProcData1 and ProcData0 contain a Long Pointer to the user's buffer area. This area must be resident.}

	CALL	SetupOldDataPCB
	LXI	D,BurdockDataBuffer	;DE ← IOP Buffer address

ReadBlockLoop:
{Wait for a byte from (other) IOP Kernel. The inner loop is approximately 49 cycles (~= 17 usec). The delay is approximately 17 * TimeOutConst usec.}

	LXI	H,TimeOutConst
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

	CALL	WriteDataBuffer	; Send block to CP
	JMP	SetUmbilicalReturnCode


OldWriteUmbilical:
{Processor Command 8:  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 BurdockDataBuffer.
	CALL	SetupOldDataPCB
	CALL	ReadDataBuffer	; Read block from CP

	LXI	D,BurdockDataBuffer	;DE ← IOP Buffer address
WriteBlockLoop:
	LDAX	D		;A ← next byte from buffer
	OUT	AltoPPIA	;Write data
{Now wait for the (other) IOP Kernel to grab the byte. The inner loop is approximately 49 cycles (~= 17 usec). The delay is approximately 17 * TimeOutConst usec.}

	LXI	H,TimeOutConst
WaitAckLoop:
	IN	AltoPPIC	;[11]
	ANI	IntAMask	;[7]
	JNZ	NextByte	;[7]  nz => IOP Kernel 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

SetupOldDataPCB:
; Set up the PCB to transfer the data between CP virtual memory and BurdockDataBuffer.
	LHLD	ProcData1
	SHLD	BurdockDataLo
	LHLD	ProcData0
	SHLD	BurdockDataHi
	LHLD	ProcData2
	SHLD	BlockCopyCount
	INX	H		; Make the count even
	MOV	A,L
	ANI	0FEH
	MOV	L,A
	SHLD	BurdockByteCnt
	RET
	
;
BaseAddress	EQU	AltoPPI		; For IN and OUT
Status		EQU	BaseAddress+0
BufferFrmCPFull	EQU	8H
BufferToCPFull	EQU	10H
CPData		EQU	BaseAddress+1
Finger		EQU	BaseAddress+2
Contents	EQU	BaseAddress+3

{Beware of byte order: the bytes within a word get swapped}
BurdockInfo:	DS	0
BurRegister:	DS	1	; Register to use for DebuggerBoard operations
BurCommand:	DS	1	; Command byte
BurNotifyBits:	DS	2	; Naked Notify bits
BurDataLow:	DS	2	; CP buffer pointer (low)
BurDataHigh:	DS	2	; CP buffer pointer (high)
BurByteCount:	DS	2
BurdockInfoEnd:	DS	0
BurdockInfoSize	EQU	BurdockInfoEnd-BurdockInfo

CopyBurdockIocb:
	DS	2		; CP buffer pointer (low)
	DW	0		; CP buffer pointer (high)
	DW	BurdockInfoSize	; CP buffer count (bytes)
	DW	BurdockInfo	; Pointer to IOP buffer
	
ZeroBurdockIocb:
	DW	BurdockIocbLoc	; CP buffer pointer (low)
	DW	CPIOPageHi	; CP buffer pointer (high)
	DW	2		; CP buffer count (bytes)
	DW	ZeroCommand	; Pointer to IOP buffer

BurdockDataPCB:	 ; PortControlBlock for sloshing Burdock data
BurdockDataLo:	DW	0
BurdockDataHi:	DW	0
BurdockByteCnt:	DW	0
		DW	BurdockDataBuffer

DoBurdockCmd:
	LHLD	BurdockIOCB
	SHLD	CopyBurdockIocb
	LXI	H,CopyBurdockIocb
	CALL	ReadCPBuffer		; Copy over IOCB

	LHLD	BurDataLow;		; Setup data PCB
	SHLD	BurdockDataLo
	LHLD	BurDataHigh
	SHLD	BurdockDataHi
	LHLD	BurByteCount
	INX	H			; Make the count even
	MOV	A,L
	ANI	0FEH
	MOV	L,A
	SHLD	BurdockByteCnt

	LDA	BurCommand
	CPI	1
	JZ	ReadUmbilicalBlock
	CPI	2
	JZ	WriteUmbilicalBlock
	CPI	3
	JZ	ReadDebuggerBlock
	CPI	4
	JZ	WriteDebuggerBlock
	CPI	5
	JZ	ReadCPBlock
	CPI	6
	JZ	WriteCPBlock
	JMP	UnknownBurdockCommand
	

ReadUmbilicalBlock:
	CALL	WriteDataBuffer
	JMP	UnknownBurdockCommand
	
WriteUmbilicalBlock:
	CALL	ReadDataBuffer
	JMP	UnknownBurdockCommand

ReadDebuggerBlock:
	LDA	BurRegister
	OUT	Finger
	LXI	D,BurdockDataBuffer	;DE ← IOP Buffer address
ReadDebuggerBlockLoop:
	IN	Contents
	STAX	D			; Store byte in buffer
	INX	D			; Increment buffer address
	LHLD	BurByteCount
	DCX	H
	SHLD	BurByteCount
	MOV	A,H
	ORA	L
	JNZ	ReadDebuggerBlockLoop
	CALL	WriteDataBuffer
	JMP	FinishBurdockCommand

WriteDebuggerBlock:
	CALL	ReadDataBuffer
	LDA	BurRegister
	OUT	Finger
	LXI	D,BurdockDataBuffer	; DE ← IOP Buffer address
WriteDebuggerBlockLoop:
	LDAX	D			; Load byte from buffer
	OUT	Contents
	INX	D			; Increment buffer address
	LHLD	BurByteCount
	DCX	H
	SHLD	BurByteCount
	MOV	A,H
	ORA	L
	JNZ	WriteDebuggerBlockLoop
	JMP	FinishBurdockCommand

ReadCPBlock:
	LXI	D,BurdockDataBuffer
ReadCPBlockLoop:
	LXI	H,TimeOutConst
ReadCPBlockWait:
	DCX	H
	MOV	A,H
	ORA	L
	JZ	Timeout       
	IN	Status
	ANI	BufferFrmCPFull
	JZ	ReadCPBlockWait
	IN	CPData
	STAX	D
	INX	D
	LHLD	BurByteCount
	DCX	H
	SHLD	BurByteCount
	MOV	A,H
	ORA	L
	JNZ	ReadCPBlockLoop
	CALL	WriteDataBuffer
	JMP	FinishBurdockCommand

WriteCPBlock:
	CALL	ReadDataBuffer
	LXI	D,BurdockDataBuffer
WriteCPBlockLoop:
	LDAX	D			; A ← next byte from buffer
	OUT	CPData
	LXI	H,TimeOutConst
WriteCPBlockWait:
	DCX	H
	MOV	A,H
	ORA	L
	JZ	Timeout       
	IN	Status
	ANI	BufferToCPFull
	JNZ	WriteCPBlockWait
	INX	D
	LHLD	BurByteCount
	DCX	H
	SHLD	BurByteCount
	MOV	A,H
	ORA	L
	JNZ	WriteCPBlockLoop
	JMP	FinishBurdockCommand

UnknownBurdockCommand:
	XRA	A
	STA	BurCommand		; Smash command byte for error marker

Timeout:
FinishBurdockCommand:
	LXI	H,CopyBurdockIocb	; Write back updated byte count
	CALL	WriteCPBuffer
	LXI	H,ZeroBurdockIocb
	CALL	WriteCPBuffer
	LHLD	BurNotifyBits
	JMP	DoNakedNotify		; and RET


ReadDataBuffer:
	LXI	H,BurdockDataPCB
	CALL	StartCPReadDma
	JMP	WaitForTransfer

WriteDataBuffer:
	LXI	H,BurdockDataPCB
	CALL	StartCPWriteDma
WaitForTransfer:
	CALL	CheckCPDmaComplete
	JZ	WaitForTransfer
	RET

LastBurdockInstruction:	DS	0
BurdockInstructionCount	EQU	LastBurdockInstruction-StartBurdockCode
	ds	512-BurdockInstructionCount
;
EndFDBuffer:
	ds	0


;-----------------------------------------------------
NextLoc:
	ds	1		;  Next free location
	END	Buffer