; piotest-intr: Test the PIO's interrupt generating ability.

; PIO is on I/0 port %1111 1100 (FC) - to %1111 1111 (FF)
; FC = Port A, Data mode
; FD = Port A, Command mode
; FE = Port B, Data mode
; FF = Port B, Command Mode

; Port and function - place one of these on the address bus.
		DEFINE PortA_DATA #FC
		DEFINE PortA_CMD  #FD
		DEFINE PortB_DATA #FE
		DEFINE PortB_CMD  #FF

; Port mode - place on data bus. Bits 5 and 4 are ignored. Bit 7 (MSB) and 6
; are Mode, and the lower 4 bits indicate a mode selection command.
		DEFINE Output	%00001111
		DEFINE Input	%01001111
		DEFINE Bi	%10001111
		DEFINE Control	%11001111

		DEFINE EnableIntr %10000111

; The program
		org #0000
		ld sp,#400	; set the stack pointer - 1K
		ld a, VectorTable / 256	; High order byte of the table address
		ld i,a		; set intr vector register
		im 2		; Set interrupt mode 2
SetupPIO
		ld a, Output	; Put PIO port A into output mode
		out (PortA_CMD), a
		ld a, VectorTable % 256 ; Low order byte of intr. table addr
		out (PortA_CMD), a
		ld a, EnableIntr
		out (PortA_CMD), a
		ei		; enable interrupts

		ld c, PortA_DATA
		ld h, 1
		xor a		; set A to zero
BlinkenLights	out (c), h	; Send contents of H to port A
		cp 0		; If A register is zero, we shift right
		jr nz, RightShift
		rl h
				; Z80 doc says RL r rolls thru carry flag
				; and back around - but it doesn't!!
		jr nz, BlinkenLights
		ld h, 1		; reset
		jr BlinkenLights
RightShift	rr h
		jr nz, BlinkenLights
		ld h, #80	; reset
		jr BlinkenLights

; Interrupt handler for Port A - flip the bits of the A register and
; continue. This will cause the blinkenlights to go the other direction.
; This will get called when Port A's strobe pin gets strobed low.
;
; All it does is complement the A register (flip all the bits). The
; main program shifts the LED output in the direction specified by the
; A register, so flipping the bits will cause the main program to reverse
; direction.
PortA_Intr	
		cpl		; Invert all bits of A
		ei		; re-enable interrupts
		reti		; and that's it	

; Interrupt vector table must be on an even numbered page
		ASSERT $ <= #100
		BLOCK #100-$, 0

VectorTable	DEFW	PortA_Intr
		DEFB	0	; just for our RS232 reciever.

