; HPC Demo Program
;
; This program provides a simple way to demonstrate the emulation and 
; analysis capabilities of the HP 64775 emulator for the National HPC
; series of microcontrollers.
;
; The program simulates a primitive command interpreter. A location is
; designated as a command input location. This location is continually
; read by the input loop. If the location is non-zero, the contents
; are copied to a pending command location and a flag is set.
; 
; Timer 2 of the HPC is used as a command processing timer. When Timer
; 2 underflows, it generates an interrupt. The interrupt service
; routine checks to see if a command is pending; if so, it interprets
; the command and writes the appropriate message to an output buffer
; area.

; Register name definitions

	enir=0x00d0:B
	r2=0x0186:W
	t2=0x0188:W
	tmmode=0x0190:W
	pwmode=0x0150:W
	divby=0x018e:W

; Export definitions and globals

	.public	enir,r2,t2,tmmode,pwmode,divby

	.public CMD_PEND,PENDING_FLAG,MSG_A,MSG_B,MSG_I
	.public	END_MSGS,MSG_DEST,CMD_INPUT

;Import external variables

	.extrn	HANDLE_CMD

; Define interrupt vector for Timer interrupt

	.SECT	INTVECTSECT, ROM8

TIMERS=5
VECTOR:		.IPT	TIMERS, HANDLE_CMD		

; Set section

	.SECT	DATABUFF, RAM8

; Define command input byte

CMD_INPUT:	.DSB	1

; Define command pending byte and command pending flag

CMD_PEND:	.DSB	1
PENDING_FLAG:	.DSB	1

; Define output buffer area

MSG_DEST:	.DSB	32


; New section for messages

	.SECT	MSGBUFF, ROM8

; Define message storage areas

MSG_A:		.BYTE	'Command A entered '
MSG_B:		.BYTE	'Entered B command '
MSG_I:		.BYTE	'Invalid command '

END_MSGS:       .BYTE	0


; Define section for subroutines

	.SECT	SUBROUTINES, ROM8


; The following subroutine clears the timer interrupt during timer
; interrupt servicing.

; Disable interrupts

	.public STOP_TIMER

STOP_TIMER:	LD	enir, #0

; Stop and reset T0..T3

		LD	tmmode, #0x4440
		NOP
		NOP
		LD	tmmode, #0xccc8
		RET

; The following subroutine restarts the timer and enables interrupts
; after timer interrupt servicing.

; Enable interrupts

	.public	START_TIMER

START_TIMER:	LD	enir, #0x21

; Start timer 2

		LD	tmmode, #0xc9c8
		RET

; Set program section for main program

		.SECT	MAINSECT, ROM8

; Initialization code: set up stack and timer, clear pending flag

	.public	INIT

INIT:		LD	SP, #2
		LD	enir, #0	; Disable interrupts
		LD	PENDING_FLAG, #0

; Set up timers per HPC user's manual
; Stop and reset t0..t3

		LD	tmmode, #0x4440
		NOP
		NOP
		LD	tmmode, #0xccc8
			
; Stop and reset t4-t7

		LD	pwmode, #0x4444 
			; no effect for non-003 applications
		NOP
		NOP
		LD	pwmode, #0xcccc 
			; no effect for non-003 applications

; The following should give interrupts about every 16.7 mS
; (60 Hz interrupt frequency) with a CKI of 20 MHz.
			
; Select divide by 131072 clock for t3, uart and uwire, divide by 32
; for t2.
			
		LD	divby, #0xf3ff

; Load Timer 2 and its input register

		LD	t2, #10437
		LD	r2, #10437
			
; Enable interrupts

		LD	enir, #0x21

; Start timer 2

		LD	tmmode, #0xc9c8

; Start of main code

; Clear command input byte

CLEAR_INPUT:	LD	CMD_INPUT, #0

; Read command input byte. If no command has been entered, continue
; to scan for input.

SCAN:		IFEQ	CMD_INPUT, #0
		JP	SCAN	

; A command was entered. Copy it to the command pending byte, set the
; pending flag and return to CLEAR_INPUT label.

PROCESS_CMD:	LD	CMD_PEND, CMD_INPUT
		LD	CMD_INPUT, #0
		LD	PENDING_FLAG, #1
		JP	SCAN

END_MAIN:	.END	INIT
