home *** CD-ROM | disk | FTP | other *** search
- * PROCEDURE profile(VAR x,y : INT_ARRAY;
- * VAR n : INTEGER;
- * dc : byte;
- * maxn : INTEGER;
- * VAR penup : BOOLEAN);
-
- * A PASCAL/Z EXTERNAL ROUTINE TO FILL ARRAYS X AND Y USING A HOUSTON HIPAD
- * DIGITIZER FOR INPUT.ASSUMES THAT THE HIPAD IS IN STREAM MODE AND SETUP
- * FOR PARALLEL BINARY METRIC TRANSMISSION.
- * POINT COLLECTING STARTS WHEN THE PEN GOES DOWN.(i.e.CONTROL BYTE = 0F4H)
- * A POINT IS REJECTED IF (ABS(dx) + ABS(dy)) IS LESS THAN dc UNITS FROM THE
- * PRECEDING POINT (ONE UNIT = 0.1mm).
- * THE PROCEDURE ENDS IF :
- * 1 : THE PEN COMES UP ,
- * 2 : MAXN POINTS HAVE BEEN READ,
- * OR 3 : MORE THAN min# POINTS HAVE BEEN READ AND A POINT
- * IS ACQUIRED CLOSER THAN closed TO THE FIRST POINT.
- * THUS THE ARRAYS WILL HOLD COORDINATES OF POINTS ON THE PERIMETER OF A
- * CLOSED PROFILE.
-
- vbytes EQU 12 # OF BYTES ON STACK
- xhi EQU 19
- xlo EQU 18 OFFSETS TO (IX) FOR ADDRESS OF POINTERS
- yhi EQU 17
- ylo EQU 16 TO TRANSMITTED VARIABLES.
- nhi EQU 15
- nlo EQU 14
- dc EQU 12
- maxnhi EQU 11
- maxnlo EQU 10
- penup EQU 9
-
- min# EQU 30
- closed EQU 5 ( 1 = 0.1mm )
- FALSE EQU 0
- TRUE EQU NOT FALSE
-
- STAT_RDY EQU 0F7H STATUS PORT DATA AVAILABLE CODE
- STAT_PRT EQU 00AH ADDRESS OF STATUS PORT
- DATA_PRT EQU 008H " " DATA "
-
- NAME profile
- ENTRY profile
-
- 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
- MOV H,ARG(IX) ; GET BASE ADDRESS OF
- MOV L,ARG-1(IX) ; ARRAY => HL
- CALL passxy
- POP H
- ENDMAC
-
- invert: MACRO arg
- PUSH P
- MOV A,arg
- NEG
- MOV arg,A
- POP P
- ENDMAC
-
- profile:
- ENTR D,2,0
- JMP START
- old_x: DS 2
- old_y: DS 2
- x1: DS 2
- y1: DS 2
- start:
- PUSH Y : SAVE IY FOR PASCAL/Z
- MOV B,maxnhi(IX) : GET VALUE OF
- MOV C,maxnlo(IX) : MAXN => BC.
- LXI H,0
- STC
- CMC
- DSBC B : MAXN = or > 1 ?
- JC START2 : IF YES THEN START
- PUSH B
- POP Y
- CALL PASS_N : ELSE MAXN --> N
- JMP done : and RETURN.
- START2:
- MOV H,penup(ix) : initialise penup to FALSE
- MOV L,penup-1(ix)
- MVI M,FALSE
- 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
- done:
- 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. UNTIL THE PEN IS DOWN.
- 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: * GETS THE INITIAL X,Y PAIR
- CALL X_IN DISCARD THE FIRST
- CALL Y_IN POINT AS IT CAN
- CALL W8_4_PEN BE GARBAGE.
- CALL X_IN X[1] => DE
- CALL Y_IN Y[1] => HL
- PUSH H SAVE Y[1]
- MOV B,xhi(IX) ;
- MOV C,xlo(IX)
- MOV A,D
- STA OLD_X ;SAVE IT TO COMPARE WITH NEXT X
- STA x1
- STAX B ;& ALSO SEND IT TO PASCAL/Z LAND.
- DCX B
- MOV A,E
- STA OLD_X+1
- STA x1+1
- STAX B
- MOV B,yhi(IX)
- MOV C,ylo(IX)
- POP H Y[1] => HL
- MOV A,H
- STA old_y ;SAVE IT TO COMPARE WITH NEXT y
- STA y1
- STAX B ;& ALSO SEND IT TO PASCAL/Z LAND.
- DCX B
- MOV A,L
- STA old_y+1
- STA y1+1
- STAX B
- LXI Y,1 : COUNTER FOR POINTS READ.
- RET
-
- ANYMORE: * N = MAXN ? (i.e. IS BUFFER FULL ?)
- PUSH H
- MOV H,maxnhi(IX)
- MOV L,maxnlo(IX)
- PUSH D
- PUSH Y ;GET COUNT FROM Y
- POP D ;TO DE + COMPARE
- STC
- CMC
- DSBC D ;TO MAXN.
- POP D
- POP H
- JZ done
- JMP proceed
-
- PEN_UP_YET: * READ DATA PORT : IS CONTROL BYTE = F3 ?
- CALL STAT_CHK ;WAIT FOR DATA
- IN DATA_PRT ;GET A BYTE
- CPI 0F4H ;CONTROL BYTE = F4?(PEN STILL DOWN)
- JZ STILL_DOWN
- MOV H,penup(ix) : set penup TRUE
- MOV L,penup-1(ix)
- MVI M,TRUE
- JMP done ;and EXIT IF PEN NOT DOWN
-
- NEXT_PR: * GETS ALL POINTS AFTER (X[1],Y[1])
- 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
- CALL absdiff : abs(dx) => A
- PUSH p : save abs(dx) for later
- LXI H,old_y :
- MOV B,M : get last y value
- INX H : into BC
- MOV C,M :
- CALL y_in : new y => HL
- PUSH H
- POP D : copy y to DE
- CALL absdiff : abs(dy) => A
- POP B : abs(dx) => B
- ADD B : (abs(dx) + abs(dy)) => A
- CC overflow
- MOV C,dc(IX)
- SUB C : > dc ?
- JNC point_ok
- POP D : if not : too close ! so fix stack
- JMP loop
- point_ok:
- INX Y : N := N + 1
- MOV A,D : IF SO : y => old_y
- STA old_y
- MOV A,E
- STA old_y+1
- pass yhi : and y => y[i]
- XCHG : y => HL
-
- POP D : RESTORE X
- MOV A,D
- STA old_x : SAVE IT TO COMPARE WITH NEXT X
- MOV A,E
- STA old_x+1
- pass xhi : x => x[i]
- * n.b. we now have y in HL,X in DE & n in IY: have we >= min# points?
- PUSH H : save y
- PUSH IY
- POP B : n => BC
- LXI H,min#
- STC
- CMC
- DSBC B
- POP H
- JNC loop : no! so keep going.
- * yes! so see if circle can be closed : i.e.are we close enough to (x1,y1) ?
- LDA y1
- MOV B,A
- LDA y1+1
- MOV C,A : y[1] => BC
- CALL absdiff : abs(y[1] - y[i]) => A
- PUSH p : " " " => stack
- XCHG : x[i] => HL
- LDA x1
- MOV B,A
- LDA x1+1
- MOV C,A : x[1] => BC
- CALL absdiff : abs(X[1] - Y[i]) => A
- POP B : abs(y[1] - y[i]) => B
- ADD B : abs(distance from (x[1],y[1])) => A
- CC overflow
- MOV C,A : into C.
- MVI A,closed : close enough to end?
- SUB C
- JNC done : yes!
- JMP loop : no!
-
- absdiff: * arg1 in HL,arg2 in BC : abs(diff) => A
- BIT 7,H
- JNZ hlneg
- BIT 7,B
- JNZ subtract
- bothpos:
- PUSH H
- STC
- CMC
- DSBC B
- JC bcbigger
- POP B
- JMP subdone
- bcbigger:
- POP H
- CALL switch
- subtract:
- STC
- CMC
- DSBC B
- JMP subdone
- hlneg:
- BIT 7,B
- JNZ negate
- CALL switch
- JMP subtract
- negate:
- invert H
- invert L
- invert B
- invert C
- JMP bothpos
- switch:
- PUSH H
- PUSH B
- POP H
- POP B
- RET
- subdone:
- MOV A,H
- ORA A
- JNZ overflow
- MOV A,L
- RET
-
- overflow:
- MVI A,07FH * largest +ve 8bit #
- RET
-
- STAT_CHK: * CHECKS STATUS PORT
- IN STAT_PRT ;DATA IN?
- CPI STAT_RDY
- RZ ;IF SO:GO GET IT.
- JMP STAT_CHK ;ELSE TRY AGAIN.
-
- X_IN: * GET X VALUE FROM HIPAD INTO DE
- 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: * GET Y VALUE FROM HIPAD INTO HL
- XCHG
- CALL X_IN
- XCHG
- RET
-
- PASS_N: ; PUT CONTENTS OF IY INTO N.
- PUSH IY
- POP H ; IY => HL.
- MOV D,nhi(IX) : ADDRESS OF N
- MOV E,nlo(IX) : => DE.
- MOV A,H
- STAX D
- DCX D
- MOV A,L
- STAX D
- RET
-
- passxy: * base address in HL ,value in DE ,N in IY.
- PUSH D
- PUSH B
- PUSH Y
- DCX Y ;
- DADY Y ; OFFSET = 2 * (Y - 1)
- PUSH Y
- POP B ; OFFSET --> BC
- stc
- cmc
- DSBC B ; ADDRESS OF ARRAY[N] = HL-OFFSET
- XCHG ; ADDRESS => DE : value => HL
- MOV A,H
- STAX D
- DCX D
- MOV A,L
- STAX D
- POP Y
- POP B
- POP D
- RET
-
- END profile
-
-