{  File:  MitchCommon.asm


Last change by Lichtenberg - add capability to continue after MP errors 1/84
Last change by Jim Frandeen July 30, 1982  12:41 PM: new IOPage format
Rewritten by Jim Frandeen April 2, 1982  8:26 AM
Written by Roy Ogus (As Exec) May 6, 1980 2:26 PM}

;  DEFINITION FILES:

	GET	"SysDefs"
	GET	"CommonDefs"
	GET	"FloppyDefs"

;  IMPORTS/EXPORTS:

	IMP	ExitInterrupt	;From RS232CSubs
	IMP	FloppyIntr		;From FloppyTask
	IMP	NoMoreBytesToSend	;From RS232CInterrupts
	IMP	RxAsyncDataInt	;From RS232CGet
	IMP	RxAsyncExternalInt	;From RS232CGet
	IMP	RxAsyncSpecialInt	;From RS232CGet
	IMP	RxSDLCDataInt	;From RS232CGet
	IMP	RxSDLCExternalInt	;From RS232CGet
	IMP	RxSDLCSpecialInt	;From RS232CGet
	IMP	RxBisyncExternalInt	;From RS232CGet
	IMP	RxBisyncSpecialInt	;From RS232CGet
	IMP	RxIllegalInt		;From RS232CSubs
	IMP	Start
	IMP	TxAsyncDataInt		;From RS232CInterrupts
	IMP	TxAsyncExternalInt	;From RS232CInterrupts
	IMP	TxSDLCExternalInt	;From RS232CInterrupts
	IMP	TxBisyncExternalInt	;From RS232CInterrupts
	IMP	TxIllegalInt		;From RS232CSubs

	EXP	ClearMiscControl1Bit
	EXP	ClearMPanel
	EXP	DisableRST
	EXP	DoMiscClock
	EXP	EnableRST
	EXP	ErrorReport
	EXP	KeyMap
	EXP	MiscControl1Val
	EXP	PutMPanel
	EXP	RS232CInterruptSwitch
	EXP	RxBisyncStateSwitch
	EXP	SetMiscControl1Bit
	EXP	Wait
	EXP	ZeroCommand
;
;---------------- START of Program @ 2000H -------------------------
Go:
	JMP	Start
;----------------- Hook for Kernel BurdockCP interrupt @ 2003H------
GoToBurdockCPIntr:
	JMP	BurdockCPIntrError
;----------------- Hook for RS232C RST 6.5 interrupt @ 2006H------
GoToRS232CIntr:
	DB	opJMP		;JMP oc code
RS232CInterruptSwitch:
	DW	0
;	JMP	AsyncRS232CInterrupt
;	JMP	SdlcRS232CInterrupt
;	JMP	BisyncRS232CInterrupt
;----------------- Hook for Floppy RST 7.5 interrupt @ 2009H------
GoToFloppyIntr:
	JMP	FloppyIntr		;Go to Floppy interrupt routine
;----------------- Hook for IOP break RST 2 @ 200CH------
GoToIOPBreakTrap:
	lxi	h,ErrorIOPBreak
	JMP	ErrorReport
;------------------------------------------------------------
	
KeyMap:
{ First 8 bytes are Alto keyboard map.  Last 4 bytes are Extended Map. Note:  Bit = 0 means DOWN, bit = 1 means UP. Bytes are stored least significant byte, then most significant byte}
	DB	0FFH		;0: Zero,K,Dash,P,Slash,BackSlash,LF,BS
	DB	0FFH		;1: Five,Four,Six,E,Seven,D,U,V

	DB	0FFH		;2: X,O,L,Comma,Quote,RightBracket,Spare2,Spare1
	DB	0FFH		;3: Three,Two,W,Q,S,A,Nine,I

	DB	0FFH		;4: Z,LeftShift,Period,SemiColon,Return,Arrow,DEL,FL3
	DB	0FFH		;5: One,ESC,TAB,F,Ctrl,C,J,B

	DB	0FFH		;6: Lock,Sp,LeftBracket,Equal,RightShift,Spare3,FL4,FR5
	DB	0FFH		;7: R,T,G,Y,H,Eight,N,M

	DB	0FFH		;8: A8, L8, L5, L2, R2, R7, R4, D2
	DB	0FFH		;9: R5, R9, L10, L7, L4, L1, A9, R10

	DB	0FFH		;A: T8, T10, R3, Key47, A10, R8, A11, A12
	DB	0FFH		;B: D1, Key48, T1, T3, T4, T5, T6, T7
;
ZeroCommand:
	DW	0

{The next location is at 2020. This is the jump table to jump to the appropriate RS232C interrupt handler for SDLC mode. We start at an address with zero in the 5 low order bits so that we can multiply the inerrupt vector by two and OR the result into a jump table address.}
SDLCJumpTable:
	JMP	NoMoreBytesToSend	;When Vecter =0 Tx Buffer Empty
	DB	0
	JMP	TxSDLCExternalInt	;When Vecter =2 Ex Stat
	DB	0
	JMP	TxIllegalInt	;When Vecter =4 Tx Char
	DB	0
	JMP	ExitInterrupt	;When Vecter =6 Sp Tx Cond
	DB	0
	JMP	RxIllegalInt	;When Vecter =8 Tx Buffer Empty
	DB	0
	JMP	RxSDLCExternalInt	;When Vecter =A Ex Stat
	DB	0
	JMP	RxSDLCDataInt	;When Vecter =C Rx Char
	DB	0
	JMP	RxSDLCSpecialInt	;When Vecter =E Sp Rx Cond
	DB	0

{The next location is at 2040. This is the jump table to jump to the appropriate RS232C interrupt handler for Bisync mode. We start at an address with zero in the 5 low order bits so that we can multiply the inerrupt vector by two and OR the result into a jump table address.}
BisyncJumpTable:
	JMP	TxIllegalInt	;When Vecter =0 Tx Buffer Empty
	DB	0
	JMP	TxBisyncExternalInt	;When Vecter =2 Ex Stat
	DB	0
	JMP	TxIllegalInt	;When Vecter =4 Tx Char
	DB	0
	JMP	ExitInterrupt	;When Vecter =6 Sp Tx Cond
	DB	0
	JMP	RxIllegalInt	;When Vecter =8 Tx Buffer Empty
	DB	0
	JMP	RxBisyncExternalInt	;When Vecter =A Ex Stat
	DB	0
	DB	opJMP		;When Vecter =C Rx Char
RxBisyncStateSwitch:
	DW	0
	DB	0
	JMP	RxBisyncSpecialInt	;When Vecter =E Sp Rx Cond
	DB	0

{The next location is at 2060. This is the jump table to jump to the appropriate RS232C interrupt handler for Async mode. We start at an address with zero in the 5 low order bits so that we can multiply the interrupt vector by two and OR the result into a jump table address.}
AsyncJumpTable:
	JMP	TxAsyncDataInt	;When Vecter =0 Tx Buffer Empty
	DB	0
	JMP	TxAsyncExternalInt	;When Vecter =2 Ex Stat
	DB	0
	JMP	TxIllegalInt	;When Vecter =4 Tx Char
	DB	0
	JMP	ExitInterrupt	;When Vecter =6 Sp Tx Cond
	DB	0
	JMP	RxIllegalInt	;When Vecter =8 Tx Buffer Empty
	DB	0
	JMP	RxAsyncExternalInt	;When Vecter =A Ex Stat
	DB	0
	JMP	RxAsyncDataInt	;When Vecter =C Rx Char
	DB	0
	JMP	RxAsyncSpecialInt	;When Vecter =E Sp Rx Cond
	DB	0
;
{COMMON  SUBROUTINES}


;  Programming the 8085 interrupt mask.
;  The two subroutines allow access to the 8085 interrupt mask.
;  Each subroutine has on entry, an RSTInterruptMask in A.
;  RSTInterruptMask format:
;	bit 0,1,2  -  don't care
;	bit 3       -  0 = don't reset RST 7.5 FF, 1 = Reset RST 7.5 FF
;	bit 4       -  don't care
;	bit 5       -  1 = Floppy interrupt (RST 7.5) specified, 0 = not specified
;	bit 6       -  1 = RS232C interrupt (RST 6.5) specified, 0 = not specified
;	bit 7       -  1 = Burdock/CP interrupt (RST 5.5) specified, 0 = not specified
;  Note:  RST 5.5 currently has privileged use.


;  Subroutine:  DisableRST [A:  RSTInterruptMask].
;   Program the interrupt mask to disable the specified interrupts in the 8085.
;  On entry:   A =  RSTInterruptMask.
DisableRST:
	ORI	MskSetEnable	;OR in IE bit
	MOV	D,A		;Save interrupt mask in D
	RIM			;Get current interrupt disable mask
	ANI	RSTMask	;Discard all but interrupt masks
	ORA	D		;OR in new values (can use directly)
	SIM			;Change the mask
	RET

;  Subroutine:  EnableRST [A:  RSTInterruptMask].
;   Program the interrupt mask to enable the specified interrupts in the 8085.
;   Note:  RST 7.5 FF can be cleared as well.
;  On entry:   A =  RSTInterruptMask.
EnableRST:
	MOV	D,A		;Save interrupt mask in D
	ANI	ResetRst75	;Isolate the Reset &.5 FF bit in mask
	ORI	MskSetEnable	;OR in IE bit
	MOV	E,A		;Save OR component in E
	MOV	A,D		;Retrieve interrupt mask again
	ANI	RSTMask		;Isolate RST flags
	CMA			;Make into active low signals
	MOV	D,A		;Save AND part in D
	RIM			;Get current interrupt disable mask
	ANI	RSTMask		;Discard all but interrupt masks
	ANA	D		;AND component
	ORA	E		;OR component 
	SIM			;Change the mask
	RET

;  Subroutine:  Wait [H,L:  WaitValue].
;   Waits a period of time specified in H,L (16 bits).
;  On entry:   H,L = wait value.
;  Delay is approx:  38 +  20*WaitValue  cycles  
;  	  =  13 +  6.67*WaitConst  usec  
Wait:
	PUSH	psw		;[12] Save A
	XRA	A		;[4] Clear A
WaitLoop:
	DCX	H		;[6]
	CMP	L		;[4] Check low
	JNZ	WaitLoop	;[10]
	CMP	H		;[4] Check high
	JNZ	WaitLoop	;[10]

	POP	psw		;[10] Restore A
	RET			;[12]

;  Subroutine:  PutMPanel.
;  Put a number in the maintenance panel (no Yields).
;  On entry:  H,L contains the number to be put in the panel.

PutMPanel:
	CALL	ClearMPanel	;Clear the panel
	INX	H		;Bias so that a value of zero can be used
	JMP	PutMPanelCheck
PutMPanelLoop:
	CALL	IncrMP
PutMPanelCheck:
	XRA	A		;Clear A
	DCX	H		;Decrement the count
	CMP	L		;Check low part for zero
	JNZ	PutMPanelLoop		;nz => not done yet
	CMP	H		;Low part is zero, check high part for zero
	JNZ	PutMPanelLoop		;nz => not done yet
;  Done.
	RET

;  Subroutine:  SetMiscControl1Bit [A:  Mask of bit(s) to be set].
;  Set the bit(s) specified in A in MiscControl1Val and MiscControl1.

SetMiscControl1Bit:
	DB	opORI		;OR in current MiscControl1Val
MiscControl1Val:
	DB	0

ChangeMiscControl1Bit:
	OUT	MiscControl1
	STA	MiscControl1Val
	STA	MiscControl1Val2
	RET

;  Subroutine:  ClearMPanel.
;  Clear the maintenance panel, and to disable blanking.
ClearMPanel:
	MVI	D,ClrMPanel	;Mask for ClrMPanel clock
	CALL	DoMiscClock
UnBlankMP:
	MVI	A,nBlankMPanel		;Blank the panel
;  Fall through to ClearMiscControl1Bit and return.


;  Subroutine:  ClearMiscControl1Bit [A:  Mask of bit(s) to be cleared].
;  Clear the bit(s) specified in A (by 0's) in MiscControl1Val and MiscControl1.

ClearMiscControl1Bit:
	DB	opANI		;Turn off bits in MiscControl1Val
MiscControl1Val2:
	DB	0
	JMP	ChangeMiscControl1Bit

;  Subroutine:  [IncrMP].
;  Increment the maintenance panel.
IncrMP:
	MVI	D,IncMPanel	;Mask for IncMPanel clock
;  Fall through to DoMiscClock and return.

;  Subroutine [DoMiscClock].
;  Clocks a bit in the MiscClocks1 register.
;  Width of clock pulse is 14 cycles (~5 usec).
;    On entry:	D  contains a mask of the bit(s) to be toggled.

DoMiscClock:
	MVI	A,0FFH		;Set all high
	XRA	D		;Clear clock bit(s)
	OUT	MiscClocks1	
	XRA	D		;Toggle bit again
	OUT	MiscClocks1	
	RET


;  Trap:  ErrorReport.
;  Blink the Maintenance panel with the error code.
;  On entry:  H,L = error code.

ErrorReport:
	CALL	PutMPanel	;Put the number in the panel (no Yields)
	MVI	A,BlankMPanel	;Blank bit in A
ErrorTrap:
	OUT	MiscControl1	;Blank/unblank the panel
	LXI	H,BlinkConst	;H,L ← blink constant (~.5 sec)
	CALL	Wait
	push	psw		; save blinking state
	IN	MiscInput1	; read the alt boot button
	ani	AltBootMask
	jnz	GoStart		; restart domino
	pop	psw		; restore blank bit
	
	XRI	BlankMPanel	;Toggle blank bit
	JMP	ErrorTrap

;  Burdock attempted to use the EtherKludge.  Signal an error.
BurdockCPIntrError:
	LXI	H,ErrorBurdockCPDisabled
	JMP	ErrorReport
	
GoStart:
	DI
	jmp	Go

	END	Common