*

*  HC11 - Serial Equates

*

SPCR	EQU	$1028			; SPI Control Register

SPSR	EQU	$1029	

SPDR	EQU	$102A			; SCI Data Register

BAUD	EQU	$102B			; SCI Baud Rate Control Register

SCCR1	EQU	$102C			; SCI Control Register 1

SCCR2	EQU	$102D			; SCI Control Register 2

SCSR	EQU	$102E			; SCI Status Register

SCDR	EQU     $102F			; SCI Data 

TDRE	EQU	$80			; Transmit Data Register Empty

TRENA	EQU	$0C			; Transmit, Receive ENAble

RDRF	EQU	$20			; Receive Data Register Full

PD_WOM	EQU	$20	

B9600	EQU	$B0

*

*  HC11 - PORT Equates

*

PORTA	EQU	$00			; Port A data register

PORTB	EQU	$04			; Port B data register

PORTC	EQU	$03			; Port C latched data register

PORTD   EQU	$08			; Port D data register

PORTE	EQU	$0A			; Port E data register

DDRC	EQU	$07			; Data Direction register for port C

HPRIO	EQU	$3C			; Highest Priority Interrupt and misc.

*

*  My Display Equates

*

LCDtmpX EQU	$0D

LCDtmpA	EQU	$0F

LCDrout	EQU	$10

PROMPT	EQU	'>'

* ________________________________________________________________________________

*

	ORG	$BFFE			; Reset Vector

	FDB	$C000			; org start of Monitor

* ________________________________________________________________________________

*

*  Start of Prog

*

	ORG	$C000        

	LDS	#$BFEF

*

	JSR	CPYprt			; Copy Display routine to Zero Page

*

	LDX	#$1000			; Set up Serial for 9600 Baud transmission

	BCLR	SPCR,X PD_WOM

	LDAA	#B9600

	STAA	BAUD,X

	LDAA	#TRENA

	STAA	SCCR2,X

* ________________________________________________________________________________

*

*  Set up Display

*

	LDAA	#$00			

	LDAB	#$0C			; Display On /  Cursor Off / Flash Off

	JSR	LCDrout

*

	LDAA	#$00			

	LDAB	#$38			; Two Line Display

	JSR	LCDrout

*

	LDAA	#$00			

	LDAB	#$03			; Home and Clear Display

	JSR	LCDrout

*

* ________________________________________________________________________________

*

	LDAA	#00			; Turn off Motor Outputs

	STAA	$7000

* ________________________________________________________________________________

*

* Copy Version to Buffer

*	

	LDX	#Line1

	LDY	#Verson

CpyV	LDAA	0,Y

	STAA	0,X

	INY

	INX

	CPX	#Lend

	BNE	CpyV

* ________________________________________________________________________________

*

*  Display Version message

*

	JSR	WrtDis

	LDX	#Line1			; buffalo message

	JSR	OUTSTRG

	JSR	OUTCRLF

* ________________________________________________________________________________

*

*  Input User Commands from Serial Line  ######### MAIN LOOP ############

*

MAIN	LDS	#$BFEF			; Initialize SP every time

	JSR	OUTCRLF

	LDAA	#PROMPT			; prompt user

	JSR	putch

	JSR	ClrDis

	CLRB

MAIN1	PSHB 

	JSR	getch			; Read terminal

	JSR	putch

	CMPA	#$08

	BNE	MAIN2			; jump if not bckspc

	PULB

	TSTB

	BEQ	MAIN			; jump if buffer empty

	DECB

	BRA	MAIN1

MAIN2	CMPA	#$0D

	BEQ	COMDO			; jump if cr

	LDX	#Line1

	PULB

	ABX				; pointer into buffer

	STAA	0,X

	INCB

	CMPB	#32

	BNE	MAIN1			; jump if not long

	LDX	#LngMsg			; Print Long Message

	JSR	OUTSTRG

	BRA	MAIN

* ________________________________________________________________________________

*

* Do Command

*

CmdNm	FCB	0			; Num Commands

CmdWd	FCC	'XX'			; Word

CmdA1	FCC	'00'			; Add1

CmdA2	FCC	'00' 			; Add2 or Data

CmdD	FCC	'00'			; Data

CmdAd	FCC	'00'			; Address Store

*

COMDO	JSR	OutCRLF

	LDX	#Line1			; Convert commands to UpperCase

UpCas	LDAA	0,X

	CMPA	#'a'

	BLT	UpCas1			; jump if < a

	CMPA	#'z'

	BGT	UpCas1			; jump if > z

	SUBA	#$20

	STAA	0,X

UpCas1	INX

	CPX	#Lend

	BNE	UpCas

*

	JSR	WrtDis			; Print command to Display

*

	CLR	CmdNm			; State No Commands (yet)

	LDX	#Line1			; Parse Command

	JSR	SkipB			

	STAA	CmdWd			; Store Cmd Char1

	LDAA	1,X	

	STAA	CmdWd+1			; Store Cmd Char1

	INC	CmdNm			; Got First Command So Num Commands =1

	INX

	INX

	JSR	SkipW

	JSR	GetNum			; Get First Addess

	LDD	CmdAd

	STD	CmdA1

	INC	CmdNm			; Got First Command So Num Commands =2

	JSR	SkipB

	JSR	GetNum

	LDD	CmdAd

	STD	CmdA2

	INC	CmdNm			; Got Second Command So Num Commands =3

	JSR	SkipB

	JSR	GetNum

	LDD	CmdAd

	STD	CmdD

	INC	CmdNm			; Got Third Command So Num Commands =4

	JMP	DetCom

*

SkipW	LDAA	0,X			; Skip Remaining Words then WhiteSpace

	CMPA	#$2C			; comma

	BEQ	SkipB

	CMPA	#$20			; space

	BEQ	SkipB

	CMPA	#$09			; tab

	BEQ	SkipB

	INX

	CPX	#Lend

	BNE	SkipW

	JMP	DetCom

SkipB	LDAA	0,X			; Skip White Space

	CMPA	#$2C			; comma

	BEQ	NeCh

	CMPA	#$20			; space

	BEQ	NeCh

	CMPA	#$09			; tab

	BEQ	NeCh

	RTS

NeCh	INX

	CPX	#Lend

	BNE	SkipB

	JMP	DetCom

*

GetNum	CLRB

	CLR	CmdAd

	CLR	CmdAd+1

GetA	LDAA	0,X

	CMPA	#'0'

	BLT	EGet			; jump if < 0

	CMPA	#'9'

	BGT	Get1			; jump if > 9

	INCB				; Is Num INC digits

	SUBA	#'0'

	BRA	Addit

Get1	CMPA	#'A'			; jump if < A

	BLT	EGet

	CMPA	#'F'	

	BGT	EGet

	SUBA	#55

	INCB				; Is Num INC digits

AddIt	ASL	CmdAd+1

	ROL	CmdAd

	ASL	CmdAd+1

	ROL	CmdAd

	ASL	CmdAd+1

	ROL	CmdAd

	ASL	CmdAd+1

	ROL	CmdAd

	ADDA	CmdAd+1

	STAA	CmdAd+1

	INX

	BRA	GetA

EGet	CMPB	#04

	BGT	DetCom	

	TSTB

	BEQ	DetCom

	RTS

*

DetCom	LDAA	CmdNm			; Check that more than Zero Commands

	BEQ	HlpEd

	LDAA	CmdWd			; Check If Load

	CMPA	#'L'

	BNE	Next1

	LDAA	CmdWd+1

	CMPA	#'O'

	BNE	Next1

	JSR	LOAD

	JMP	MAIN

Next1	LDAA	CmdWd			; Check If BFILL

	CMPA	#'B'

	BNE	Next2

	LDAA	CmdWd+1

	CMPA	#'F'

	BNE	Next2

	JSR	BFILL

	JMP	MAIN

Next2	LDAA	CmdWd			; Check If CALL

	CMPA	#'C'

	BNE	Next3

	LDAA	CmdWd+1

	CMPA	#'A'

	BNE	Next3

	JSR	CALL

	JMP	MAIN

Next3	LDAA	CmdWd			; Check If GO

	CMPA	#'G'

	BNE	Next4

	LDAA	CmdWd+1

	CMPA	#'O'

	BNE	Next4

	JSR	GO

	JMP	MAIN

Next4	LDAA	CmdWd			; Check If Move / MD / MM

	CMPA	#'M'

	BNE	HlpEd

	LDAA	CmdWd+1

	CMPA	#'O'			; Check If MO

	BNE	Next5

	JSR	MOVE

	JMP	MAIN

Next5	CMPA	#'D'			; Check If MD

	BNE	Next6

	JSR	MEMD

	JMP	MAIN

Next6	CMPA	#'M'			; Check If MM

	BNE	HlpEd

	JSR	MMOD

	JMP	MAIN

HlpEd	JSR	HELP

	JMP	MAIN 

* ________________________________________________________________________________

*

* Do Help Command

*

HDm	FCC	'UNKNOWN COMMAND '

HDm1	FCC	' DISPLAYING HELP'

HELP 	LDX	#HDm

	LDY	#Line1

HLP1	LDAA	0,X

	STAA	0,Y

	INX

	INY

	CPY	#Lend

	BNE	HLP1	

	JSR	WrtDis

	LDX	#HELPMSG

	JSR	OUTSTRG      		; print help screen

	RTS

*

HELPMSG FCC	'HANDYBOARD BUFFALO'

	FCB	$0D

	FCB	$0A

	FCC	'  LOAD                          = Load S-records.'

	FCB	$0D

	FCB	$0A

	FCC	'  BF <addr1> <addr2> [<data>]   = Block fill.'

	FCB	$0D

	FCB	$0A

	FCC	'  MOVE <Sadr1> <Dadr2> [<num>]  = Block move.'

	FCB	$0D

	FCB	$0A

	FCC	'  MD <addr1> [<addr2>]          = Memory dump.'

	FCB	$0D

	FCB	$0A

	FCC	'  MM <addr> <data>              = Memory modify.'

	FCB	$0D

	FCB	$0A

	FCC	'  CALL <addr>                   = Call user subroutine.'

	FCB	$0D

	FCB	$0A

	FCC	'  GO <addr>                     = Execute user code.'

	FCB	$0D

	FCB	$0A

	FCB	00

* ________________________________________________________________________________

*

* Do Load Command

*

MSG12	FCC	'Checksum error'

	FCB	0

MSG14	FCC	'Receiver error'

	FCB	0

MSG11	FCC	'Completed Load'

	FCB	0

*

SHFTREG	RMB	2		input shift register

AUTOLF	RMB	1		auto lf flag for i/o

TMP1 	FCB	0		main,hexbin,buffarg,termarg

TMP2	FCB	0

TMP3	FCB	0

TMP4	FCB	0

PTR3	RMB	2

*

LOAD	CLR  	TMP2            0=load

	CLR  	TMP3        	clear error flag

LOAD10  JSR	getch		; Read terminal

	CMPA 	#'S'

	BNE  	LOAD10      	jump if not S

	JSR	OutCRLF

	LDAA	#'S'

	JSR	putch

LOAD12	JSR	getch		; Read terminal

	CMPA 	#'9'

	BEQ  	LOAD90      	jump if S9 record

	CMPA 	#'1'

	BNE  	LOAD10      	jump if not S1

	JSR	putch

	CLR  	TMP4        	clear checksum

	JSR  	BYTE

	LDAB 	SHFTREG+1

	SUBB 	#$2         	b = byte count

	JSR  	BYTE

	JSR  	BYTE

	LDX  	SHFTREG     	x = base address

	DEX

LOAD20	JSR  	BYTE        	get next byte

	INX

	DECB             	check byte count

	BEQ  	LOAD30      	if b=0, go do checksum

	TST  	TMP3

	BNE  	LOAD10      	jump if error flagged

	TST  	TMP2

	BNE  	LOAD21      	jump if verify

	LDAA 	SHFTREG+1

	STAA 	0,X 

LOAD21	CMPA 	0,X         	verify ram location

	BEQ  	LOAD20      	jump if ram ok

	LDAA 	#$02

	STAA 	TMP3        	indicate rom error

	STX  	PTR3        	save error address

	BRA 	LOAD20      	finish download

* calculate checksum

LOAD30	TST  	TMP3

	BNE  	LOAD10      	jump if error already

	LDAA 	TMP4

	INCA             	do checksum

	BEQ  	LOAD10      	jump if s1 record okay

	LDAA 	#$03	

	STAA 	TMP3        	indicate checksum error

	BRA  	LOAD10

LOAD90	JSR	putch

	JSR  	BYTE

	LDAB 	SHFTREG+1 	b = byte count

LOAD91	JSR  	BYTE

	DECB

	BNE	LOAD91      	loop until end of record

	INC	AUTOLF      	turn on autolf

	LDX	#MSG11      	"done" default msg

	LDAA	TMP3

	CMPA	#$02

	BNE	LOAD92      	jump not rom error

	LDX  	#PTR3

	JSR  	OUT2BSP     	address of rom error

	BRA	LOAD95

LOAD92	CMPA	#$01

	BNE	LOAD93     	 jump not rcv error

	LDX	#MSG14      	"rcv error"

	BRA	LOAD94

LOAD93	CMPA	#$03

	BNE	LOAD94      	jump not checksum error

	LDX	#MSG12      	"checksum error"

LOAD94	JSR	OUTSTRG

	JSR	OutCRLF

LOAD95	RTS

**********

BYTE	PSHB

	PSHX

BYTE0	JSR	getch		; Read terminal

	JSR	putch

	JSR  	HEXBIN

BYTE1	JSR	getch		; Read terminal

	JSR	putch

	JSR  	HEXBIN

	LDAA 	SHFTREG+1

	ADDA 	TMP4

	STAA 	TMP4        	add to checksum

	PULX

	PULB

	RTS

*****************

HEXBIN	PSHA

	PSHB

	PSHX

	CMPA	#'a'

	BLT	UpCas2			; jump if < a

	CMPA	#'z'

	BGT	UpCas2			; jump if > z

	SUBA	#$20

UpCas2	CMPA 	#'0'

	BLT  	HEXNOT       		jump if a < $30

	CMPA 	#'9'

	BLE  	HEXNMB       		jump if 0-9

	CMPA 	#'A'	

	BLT  	HEXNOT       		jump if $39> a <$41

	CMPA 	#'F'

	BGT  	HEXNOT       		jump if a > $46

	ADDA 	#$9 			convert $A-$F

HEXNMB	ANDA 	#$0F         		convert to binary

	LDX  	#SHFTREG

	LDAB 	#4

HEXSHFT ASL  	1,X  			2 byte shift through

	ROL  	0,X        		carry bit

	DECB

	BGT  	HEXSHFT      		shift 4 times

	ORAA 	1,X

	STAA 	1,X

	BRA  	HEXRTS

HEXNOT	INC  	TMP1         		indicate not hex

HEXRTS	PULX

	PULB

	PULA

	RTS

* ________________________________________________________________________________

*

* Do BF Command

*

LdMs1	FCC	'Missing or Incorect Addresses for Block Fill'

	FCB	0

BFILL 	LDAA	CmdNm

	CMPA	#03

	BGE	BFO1

 	LDX	#LdMs1

	JSR	OUTSTRG;		; Print Error Message

	RTS

BFO1	LDAB	#00

	CMPA	#04

	BNE	BFO3

	LDAB	CmdD+1

BFO3	LDX	CmdA1

BFO2	STAB	0,X

	INX

	CPX	CmdA2

	BNE	BFO2	

	RTS

* ________________________________________________________________________________

*

* Do MOVE Command

*

ErrMM	FCC	'Missing or Incorect Addresses for Memory Move'

	FCB	0

MOVE 	LDAA	CmdNm

	CMPA	#03

	BGE	MMO1

 	LDX	#ErrMM

	JSR	OUTSTRG;		; Print Error Message

	RTS

MMO1	LDAB	#01

	CMPA	#04

	BNE	MMO3

	LDAB	CmdD+1

MMO3	LDX	CmdA1

	LDY	CmdA2

MMO2	LDAA	0,X

	STAA	0,Y

	INX

	INY

	DECB

	BNE	MMO2	

	RTS

* ________________________________________________________________________________

*

* Do MemDump Command

*

StM	FCC	'00'

StE	FCC	'00'

ErrMD	FCC	'Missing or Incorect Address for Memory Dump'

	FCB	0

MEMD 	LDX	CmdA1

	STX	StM

	LDAA	CmdNm

	CMPA	#01

	BNE	MEM1

 	LDX	#ErrMD

	JSR	OUTSTRG;		; Print Error Message

	RTS

MEM1	CMPA	#02

	BNE	MEM2

	LDY	CmdA1

	LDAB	#$0F

	ABY

	STY	StE

	BRA	GoPM

MEM2	LDX	CmdA2

	STX	StE

GoPM	LDX	#StM

	JSR	OUT2BSP

	LDAA	#'-'

	JSR	PutCh

	LDAA	#' '

	JSR	PutCh

	LDX	StM

	LDY	#$10

AgPM	JSR	OUT1BSP

	DEY

	BNE	AgPM

	JSR	OUTCRLF

	LDD	StM

	ADDD	#16

	STD	StM

	CPD	StE

	BLE	GoPM

	RTS

* ________________________________________________________________________________

*

* Do MemModify Command

*

LdMs4	FCC	'Missing or Incorect Address / Data for Memory Modify'

	FCB	0

MMOD 	LDAA	CmdNm

	CMPA	#03

	BEQ	MM1

 	LDX	#LdMs4

	JSR	OUTSTRG;		; Print Error Message

	RTS

MM1	LDX	#CmdA1

	JSR	OUT2BSP

	LDAA	#':'

	JSR	PutCh

	LDAA	#' '

	JSR	PutCh

	LDX	CmdA1

	JSR	OUT1BSP

	LDAA	#'-'

	JSR	PutCh

	LDAA	#'>'

	JSR	PutCh

	LDAA	#' '

	JSR	PutCh

	LDAA	CmdA2+1

	LDX	CmdA1

	STAA	0,X

	JSR	OUT1BSP

	JSR	OUTCRLF

	RTS

* ________________________________________________________________________________

*

* Do CALL Command

*

LdMs5	FCC	'Missing or Incorect Address for CALL'

	FCB	0

CALL	LDAA	CmdNm

	CMPA	#02

	BGE	COO1

 	LDX	#LdMs5

	JSR	OUTSTRG			; Print Error Message

	RTS

COO1	LDX	CmdA1

	JSR	0,X	

	RTS

* ________________________________________________________________________________

*

* Do GO Command

*

LdMs6	FCC	'Missing or Incorect Address for GO'

	FCB	0

GO	LDAA	CmdNm

	CMPA	#02

	BGE	GOO1

 	LDX	#LdMs6

	JSR	OUTSTRG			; Print Error Message

	RTS

GOO1	LDS	#$BFEF			; Initialize SP every time

	LDX	CmdA1

	JMP	0,X	

* ________________________________________________________________________________

*

* Get and Put Character (AccA) to Serial Line

*

getch	LDAA	SCSR

	ANDA	#RDRF

	BEQ	getch

	LDAA	SCDR

	RTS

*

putch	LDAB	SCSR

	ANDB	#TDRE

	BEQ	putch

	STAA	SCDR

	RTS

*

OUTSTRG	JSR	OUTCRLF

OUTS0	LDAA	0,X			; read char into acc A

	BEQ	OUTS3       		; jump if End

	JSR	putch			; output character

	INX

	BRA	OUTS0			; jump if no input

OUTS3	RTS

*

OUTCRLF	LDAA	#$0D        		; cr

	JSR	putch			; output acc A

	LDAA	#$0A

	JSR	putch			; output padding

	RTS

OUTLHLF	LSRA				shift data to right

	LSRA

	LSRA

	LSRA

OUTRHLF	ANDA	#$0F			mask top half

	ADDA	#$30			convert to ascii

	CMPA	#$39

	BLE	OUTA         		jump if 0-9

	ADDA	#$07         		convert to hex A-F

OUTA	JSR	PutCh			output character

	RTS

OUT1BYT	PSHA

	LDAA 	0,X          		get data in a

	PSHA    	          	save copy

	BSR  	OUTLHLF 	     	output left half

	PULA              		retrieve copy

	BSR	OUTRHLF      		output right half

	PULA

	INX

	RTS

OUT2BSP	JSR	OUT1BYT         	do first byte

OUT1BSP	JSR  	OUT1BYT         	do next byte

OUTSPAC	LDAA 	#$20            	output a space

	JSR	PutCh

	RTS

* ________________________________________________________________________________

*

*  Write the Byte value in AccA to the Screen as two letters ie '0C'

*

StAv	FCB	0

PNum	STAA	StAv

	RORA

	RORA

	RORA

	RORA

	ANDA	#$0F

	CMPA	#09

	BLE	NoAd1

	ADDA	#07

NoAd1	ADDA	#48

	TAB

	LDAA	#$02			

	JSR	LCDrout

	LDAA	StAv

	ANDA	#$0F

	CMPA	#09

	BLE	NoAd2

	ADDA	#07

NoAd2	ADDA	#48

	TAB

	LDAA	#$02			

	JSR	LCDrout

	RTS

* ________________________________________________________________________________

*

* Write Display Buffer to Screen

*

WrtDis	LDAA	#$00			

	LDAB	#$03			; Home and Clear Display

	JSR	LCDrout

	LDX	#Line1

PL1	LDAA	#$02			; Tell to Print

	LDAB	$00,X

	JSR	LCDrout

	INX

	CPX	#Line2

	BNE	PL1

*

	LDX	#24

NewL	LDAA	#$02			; Tell to Get to Next Line

	LDAB	#40

	JSR	LCDrout

	DEX

	BNE	NewL

*

	LDX	#Line2

PL2	LDAA	#$02			; Tell to Print

	LDAB	$00,X

	JSR	LCDrout

	INX

	CPX	#Lend

	BNE	PL2

	RTS

* ________________________________________________________________________________

*

* Clear Display Buffer

*	

ClrDis	LDAA	#32

	LDX	#Line1

Clr1	STAA	0,X

	INX

	CPX	#Lend

	BNE	Clr1

	RTS

* ________________________________________________________________________________

*

* Display Buffer

*

Line1	FCC	'HandyBoard      '

Line2	FCC	'Buffalo     V1.0'

Lend	FCB	$00

Verson	FCC	'HandyBoard      Buffalo     V1.0'

LngMSG	FCC     'Line is to Long!'

MEnd	FCB	$00

* ________________________________________________________________________________

*

*  Copy print routine to Zero Page

*

CPYprt	LDX	#SCRbeg

	LDY	#LCDrout

LCDloop

	LDAA	0,X

	STAA	0,Y

	INX

	INY

	CPX	#SCRend

	BNE	LCDloop

	RTS

* ________________________________________________________________________________

*

*   Print Routine:  A - Command, B - Data

*     Copied to Zero Page memory and Run there

*

SCRbeg	SEI				; disable interrupts

	STX	LCDtmpX

	LDX	#$1000

	BCLR	HPRIO,X %00100000	; put into single chip mode

	BCLR	PORTA,X %00010000	; turn off LCD E line

	STAA	LCDtmpA			; Temp A store

	CLR	DDRC,X			; make port C input

LCDBsy	LDAA	#1

	STAA	PORTB,X			; read operation from LCD (AKF-added ',X')

	BSET	PORTA,X %00010000	; frob LCD on

	LDAA	PORTC,X			; get status

	BCLR	PORTA,X %00010000	; frob LCD off

	ANDA	#$80			; bit 7 is busy flag

	BNE	LCDBsy

	LDAA	#$FF

	STAA	DDRC,X			; make port C output

	LDAA	LCDtmpA			; Temp A store

	STAA	PORTB,X			; high byte is control

	STAB	PORTC,X			; low byte is data

	BSET	PORTA,X %00010000

	BCLR	PORTA,X %00010000	; frob LCD

	BSET	HPRIO,X %00100000	; put into expanded chip mode

	LDX	LCDtmpX

	CLI				; enable interrupts

	RTS				; return to monitor command loop

SCRend	FCB	00

*