* PROCEDURE WAVE(VAR XVALUE,YVALUE:INT_ARRAY;VAR N:INTEGER;MAXN:INTEGER);

* AN EXTERNAL ROUTINE TO FILL ARRAYS X AND Y FROM THE HIPAD,IN STREAM MODE.
* POINT COLLECTING STARTS WHEN THE PEN GOES DOWN.(i.e.CONTROL BYTE = 0F4H)
* A POINT IS REJECTED IF IT IS < 0.2mm TO THE RIGHT OF THE PRECEDING POINT.
* THE PROCEDURE ENDS IF THE PEN COMES UP OR WHEN MAXN POINTS HAVE BEEN READ.

VBYTES	EQU  9	# OF BYTES ON STACK
XVALUE	EQU 16    OFFSETS TO (IX) FOR ADDRESS OF POINTERS
YVALUE	EQU 14    TO TRANSMITTED VARIABLES.
N	EQU 12
MAXN	EQU  9

STAT_RDY EQU 0F7H  STATUS PORT DATA AVAILABLE CODE
STAT_PRT EQU 00AH  ADDRESS OF STATUS PORT
DATA_PRT EQU 008H     "    "   DATA    "

		NAME	WAVE
		ENTRY	WAVE

PASS:		MACRO	ARG	; STORES THE 16BIT NO. IN DE
				; IN A LOCATION WHOSE BASE
				; ADDRESS IS CALCULATED FROM ARG.
				; & WHOSE OFFSET = 2 x IY
		PUSH	H	;
		PUSH	B	; SAVE ALL REGISTERS USED 
		PUSH	Y	;
		MOV H,ARG(IX)	; GET BASE ADDRESS OF
		MOV L,ARG-1(IX)	; ARRAY => HL
		DADY	Y	; OFFSET = 2 * Y
		PUSH	Y
		POP	B	; OFFSET --> BC
		DSBC	B	; ADDRESS OF ARRAY[N] = HL-OFFSET
		XCHG		; ADDRESS => DE : ARG => HL
		MOV A,H		;
		STAX	D	;
		DCX	D	;
		MOV A,L		;
		STAX	D	;
		POP	Y
		POP	B
		POP	H
		ENDMAC

WAVE:
		ENTR D,2,0
		JMP START
OLD_X:	DS 2

START:
		PUSH Y		 : SAVE IY FOR PASCAL/Z
		MOV B,MAXN(IX)	 : GET VALUE OF
		MOV C,MAXN-1(IX) : MAXN => BC.
		LXI H,0
		DSBC B		 : MAXN = or > 1 ?
		JM START2	 : IF YES THEN START
		PUSH B
		POP Y
		CALL PASS_N	 : MAXN --> N
		JMP WAVE_END	 : ELSE RETURN.
		
START2:
		LXI Y,0		: COUNTER FOR POINTS READ.
		CALL W8_4_PEN	: PEN DOWN YET?
		CALL FIRST_PR
LOOP:
		JMP ANYMORE	: DOES N := MAXN YET ?
PROCEED:
		JMP PEN_UP_YET
STILL_DOWN:
		JMP NEXT_PR
WAVE_END:
		CALL PASS_N
		POP Y		: RESTORE ORIGINAL Y FOR PASCAL/Z
		EXIT D,VBYTES

* SUBROUTINES:
* W8_4_PEN:READS DATA PORT UNTIL CONTROL BYTE = F4 : i.e. PEN IS DOWN.

W8_4_PEN:
		CALL STAT_CHK	;WAIT TILL DATA AVAILABLE
		IN DATA_PRT	;GET IT
		CPI 0F4H	;PEN DOWN ?
		JNZ W8_4_PEN	;NO : KEEP WAITING.
		RET		;YES!

FIRST_PR:
	CALL X_IN		;DISCARD THE FIRST
	CALL Y_IN		;POINT AS IT CAN
	CALL W8_4_PEN		;BE GARBAGE.
	CALL X_IN		;GET X[1]
	MOV B,XVALUE(IX)	;
	MOV C,XVALUE-1(IX)
	MOV A,D
	STA OLD_X		;SAVE IT TO COMPARE WITH NEXT X
	STAX B			;& ALSO SEND IT TO PASCAL/Z LAND.
	DCX B
	MOV A,E
	STA OLD_X+1
	STAX B
	CALL Y_IN		;GET Y[1]
	CALL PASS_Y		;& SEND IT TO PASCAL/Z LAND.
	INX Y			;INCREMENT COUNTER
	RET

* ANYMORE CHECKS WHETHER N HAS REACHED MAXN i.e. is array filled
ANYMORE:
	PUSH H
	MOV H,MAXN(IX)
	MOV L,MAXN-1(IX)
	PUSH D
	PUSH Y			;GET COUNT FROM Y
	POP D			;TO DE + COMPARE
	DSBC D			;TO MAXN.
	POP D
	POP H
	JZ WAVE_END
	JMP PROCEED

* PEN_UP_YET:READS DATA PORT,LOOKING FOR CONTROL BYTE = F3
PEN_UP_YET:
		CALL STAT_CHK	;WAIT FOR DATA
		IN DATA_PRT	;GET A BYTE
		CPI 0F4H	;CONTROL BYTE = F4?(PEN STILL DOWN)
		JZ STILL_DOWN
		JMP WAVE_END    ;EXIT IF PEN NOT DOWN

NEXT_PR:
	CALL X_IN		: GET  NEW X => DE
	PUSH D			: & SAVE IT
	LXI H,OLD_X
	MOV B,M
	INX H
	MOV C,M			: GET  OLD_X => BC
	XCHG			: MOVE NEW X => HL
	INX B
	INX B			: ADD 2 TO OLDX
	DSBC B			: NEW_X = or > (OLD_X + 2) ? 
	JM TOO_CLOSE		: IF NOT : DON`T WANT IT
	POP D			: IF SO : RESTORE NEW X
	MOV A,D
	STA OLD_X		: SAVE IT TO COMPARE WITH NEXT X
	MOV A,E
	STA OLD_X+1
	CALL PASS_X		: & SEND X & Y
	CALL Y_IN		: TO PASCAL/Z
	CALL PASS_Y		: LAND
	INX Y			: N := N + 1
	JMP LOOP
TOO_CLOSE:
	POP D			: RESTORE STACK
	CALL Y_IN		: CLEAR PORT
	JMP LOOP

* STAT_CHK :CHECKS STATUS PORT 
STAT_CHK:
		IN STAT_PRT	;DATA IN? 
		CPI STAT_RDY 
		RZ		;IF SO:GO GET IT.
		JMP STAT_CHK     ;ELSE TRY AGAIN.

* X_IN :GETS CURRENT X VALUE FROM HIPAD INTO DE
X_IN:   CALL STAT_CHK	;WAIT FOR DATA
	IN DATA_PRT	;GET 1ST BYTE (X7..X13)
	MOV D,A		;INTO D
	PUSH D
	CALL STAT_CHK
	POP D
	IN DATA_PRT	;2ND BYTE (X0..X6)
	MOV E,A		;INTO E
	SLAR E		;---|
	SLAR D		;   |JUSTIFY
	SRAR D		;   | RIGHT 
	SRAR D		;   | IN DE
	RRAR E		;---|
	RET

* Y_IN :GETS CURRENT Y VALUE FROM HIPAD INTO HL
Y_IN:   XCHG
	CALL X_IN
	XCHG
	RET

* PASS_X STORES THE 16 BIT # IN DE @ THE LOCATIONS WHOSE START
* ADDRESS'S MSB = XVALUE + (IX) + (2 * (IY) ) : i.e. at X[N]
PASS_X:
	PASS XVALUE
	RET
* PASS_Y STORES THE 16 BIT # IN HL @ THE LOCATIONS WHOSE START
* ADDRESS'S MSB = YVALUE + (IX) + (2 * (IY)) i.e. at Y[N]
PASS_Y:
	XCHG
	PASS YVALUE
	XCHG
	RET

PASS_N:			; PUT CONTENTS OF IY INTO N.
	PUSH IY
	POP H		; IY => HL.
	MOV D,N(IX)	: ADDRESS OF N
	MOV E,N-1(IX)	: => DE.
	MOV A,H
	STAX D
	DCX D
	MOV A,L
	STAX D
	RET


			END WAVE
