;Name:	Derek Marston and Kristin Kelly
;Date:  10/8/02
;Description:  This program contains the EEPROM subroutines

Monitor 	EQU	0FF7Ch
CmdReg		EQU	8800h
PortA		EQU	1000h
StatusReg	EQU	8800h
DataReg		EQU	8000h
SCIStatusReg	EQU	102Eh
SCIDataReg	EQU	102Fh
CharOut		EQU	0FFB8h
StrOut		EQU	0FFC7h
LineFeed	EQU	0FFC4h

US		EQU	'3'  ;Our node address
BROADCAST	EQU	'0'  ;Broadcast address

;EQU's to access stuff from regular RAM
RecFlag		EQU	0000h
dspFlag		EQU	0001h
Data2SendFlag	EQU	0002h
KBFlag		EQU	0003h
;IntrRoutine	EQU	0139h

RecBuff		EQU	0102h
dspBuff		EQU	0115h
KBBuff		EQU	0128h
KBPtr		EQU	013Bh

	org 0B600h

;jump table
	jmp	Config8251A
	jmp	InitializeVars
	jmp	InstallInterruptVector
	jmp	TransmitA
	jmp	Receive
	jmp	dspData
	jmp	ProcessKey
	jmp	CopyBuff
	jmp	SendFree
	jmp	IntrRoutine
	jmp	CollectToken
	jmp	sendBusy
	jmp	ProcessFreeToken

;Name:		Config8251A
;Input:		None
;Output: 	None
;Destroys:	A
;Description:	Configure 8251 for :
;		Asyncronous serial data
;		Baud Rate Factor = 16
;		8Bit data, no parity
;		1 stop bit
;		Enable transmitter

Config8251A:
	ldaa	#0FFh;		Sets pin 6 high
	staa	PortA;		sends hardware reset to USART
	ldaa	#00h;
	staa	PortA;
	ldaa 	#4Eh;		Load data
	staa 	CmdReg;		Send data to register
        ldaa    #05h;
	staa	CmdReg;		Transmit data
	rts;

;Name:		InitializeVars
;Input:		None.
;Output:	None.
;Destroys:	A, B
;Description:	Initializes pointers and flags

InitializeVars:
	clr	RecFlag		;clears flags
	clr	KBFlag
	clr	dspFlag
	clr	Data2SendFlag

	ldd	#KBBuff		;initialize keyboard pointer
	std	KBPtr

	cli			;Enables Interrupt system
	rts


;Name:		InstallInterruptVector
;Input:		None
;Output:	None
;Destroys:	A, B, Flags
;Desc:		enables interrupt system

InstallInterruptVector:
	ldaa	#7Eh		;writes jmp
	staa	00EEh		;to memory
	ldd	#IntrRoutine	;writes value of IntrRoutine
	std	00EFh		;to memory
	rts

;Name:		TransmitA
;Input:		A = the Byte to transmit.
;Output:	None.
;Destroys:	X, Flags
;Description:	Wait until the transmitter is ready (wait until the
;		TxRDY bit in the same Status Register is 1), then
;		write the contents of A to the Data register.
TransmitA:
	ldx 	#StatusReg
	brclr	0,x,01h,TransmitA	; go to write A if contents
					; Back to loop to wait
	staa	DataReg			; Write data
	rts				; Return to loop for more data

;Name:		Receive
;Input:		None.
;Output:	A = the Byte that was received.
;Destroys:	A, Y
;Description:	Wait until the receiver has a byte (wait until the
;		RxRDY bit in the same Status Register is 1), then
;		read the byte from the Data register and return
;		from the subroutine with the data in Accumulator A

Receive:
	ldy 	#StatusReg
	brclr 	0,y,02h,Receive		;exit loop if RxRDY
	ldaa	DataReg
	rts

;Name:		dspData
;Input:		None.
;Output:	None.
;Destroys:	A, X
;Description:	Send data in Display Buffer to the screen
;		Display all until you reach OD


dspData:
	
	ldx	#dspBuff ;	initialize pointer
printchar:
	ldaa	0,x
	cmpa	#0Dh	; see if character is enter
	beq	ResetdspFlag

	jsr	CharOut	; if so, print it to screen
	inx
	bra	printchar

ResetdspFlag:
        jsr     LineFeed
	clr	dspFlag	; if not, reset flag
	rts		; and return

;Name:		ProcessKey
;Input:		None.
;Output:	None.
;Destroys:	A,X
;Description:	Read character code, put it in the buffer.
;		Update the pointer.  If code is 0D,
;		Reset the pointer to KBBuff,
;		Data2SendFlag=true.
ProcessKey:
	
	ldx	#SCIStatusReg;
	brset	0,x,00100000q,ReadChar
	rts		;if key waiting, process	
ReadChar:
	ldaa	SCIDataReg; load character typed

;special characters
	cmpa	#27t	; if Esc is pressed,
	beq	sendFree; send a free token

	cmpa	#08t	; if Backspace is pressed,
	bne	NormalChar;
	ldx	KBPtr
	dex
	stx	KBPtr	;decrement the pointer
	rts
	
NormalChar:
	ldx	KBPtr
	staa	0,x	; store it to the buffer

	ldx	KBPtr;	increment the pointer
	inx
	stx	KBPtr

	cmpa	#0Dh ;if key pressed is enter,
	beq	ResetPointers

	jsr	CharOut	;print the character to screen
	rts

ResetPointers:
	ldaa	#0FFh	;set Data2SendFlag to true
	staa	Data2SendFlag
	ldx	#KBBuff
	stx	KBPtr
	
	jsr	LineFeed

;	ldx	#KBBuff	;display what was just typed
;	ldy	#dspBuff
;	jsr	CopyBuff
;	jsr	dspData
	rts

;Name:		CopyBuff
;Input:		X = Source Buffer, y = Destination Buffer
;Output: 	None
;Destroys:	A, B, X, Y, Flags
;Description:	copies one buffer to another

CopyBuff:
	ldab	#18t	; initialize counter

docopy:
	ldaa	0,x
	staa	0,y
	inx
	iny
	decb
	bne	docopy

	ldaa	#0Dh	; force 0D in last spot of the buffer
	staa	0,y
	rts

;Name:		SendFree
;Input:		none.
;Output:	none.
;Destroys:	A, flags	
;Description:	Send one free token
SendFree:
	ldaa	#0AAh
	jsr	TransmitA
	ldaa	#0FFh
	jsr	TransmitA
	ldaa	#0AAh
	jsr	TransmitA
	rts

;Name:		IntrRoutine
;Input:		None
;Output:	None
;Destroys:	Nothing
;Desc:		Receive a token

IntrRoutine:
	jsr	CollectToken
	rti

;Name:		CollectToken
;Input:		None
;Output:	None
;Destroys:
;Desc:		Reads in entire token and stores it
;		in the received buffer RecBuff
;		Then it sets the receieved flag RecFlag

CollectToken:
	clr	RecFlag		;Reset Flag
	jsr	Receive		;read first byte
	cmpa	#0AAh		;see if it's AA
	bne	done		;if not, bad token:discarded
	ldx	#RecBuff	;Initialize x w/buffer
	jsr	Receive		;read second byte

	cmpa	#0BBh		;see if busy token
	beq	BusyHere	
	cmpa	#0FFh		;if not see if free token
	bne	done		;if not, token invalid
	
	jsr 	Receive		;Token is free?
	cmpa 	#0AAh		
	bne	done		;if not token is invalid
	ldaa	#0FFh		;if so, set free token flag
	staa	RecFlag
	bra	done
	
BusyHere:			;set up loop
	ldab	#18t		;load counter with 18 data bits
	staa	0,x		;store data to buffer
	inx			;next byte in buffer

GetRest:
	jsr	Receive		;get next byte
	staa	0,x		;store it
	inx
	decb
	bne	GetRest		;loop
	
	jsr	Receive		;get terminating #AA byte
	cmpa	#0AAh		;see if it is
	bne	done		;if not, discard token
	ldaa	#0BFh		;if it is, set token rec. flag
	staa	RecFlag
done:
	rts

;Name:		sendBusy
;Input:		None
;Output:	None
;Destroys:	A, B, Y, Flags
;Desc:		Sends the contents of the keyboard buffer
;		with the appropriate token data
sendBusy:
	ldy	#RecBuff	;adds the source byte

	ldaa	#0AAh		;send leading AA
	jsr	TransmitA

	ldab	#19t;		;initialize counter

startBusy:
	
	ldaa 	0,y		;load a byte to send
	jsr	TransmitA	;send it
	iny	
	decb			;decrement counter
	bne	startBusy

	ldaa	#0AAh		;append final AA to token
	jsr	TransmitA	

	rts

;Name:		ProcessFreeToken
;Input:		None
;Output:	None
;Destroys:	A, X, Y, Flags
;Desc:		Send a busy token if there is data to send
;		Otherwise send a free token

ProcessFreeToken:
	clr	RecFlag		;token received
	ldaa	Data2SendFlag	;do we have data2send?
	bne	prepBusy	;yes
	
	jsr	sendFree	;no-pass free on
	rts	
prepBusy:
	ldx	#KBBuff
	ldy	#RecBuff	;actually, this is the 
				;Tx Buffer now.  HAHAHA

	ldaa	#0BBh		;append leading BB to token
	staa	0,y
	iny

	ldaa	#US		;put our node address into 
	staa	0,y		;the source byte of token
	iny

	jsr	CopyBuff	;copy busy token
				;into Tx/Rx buffer
	jsr	sendBusy
;	clr	Data2SendFlag
	rts