home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG035.ARK
/
DISTPLUS.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
11KB
|
318 lines
; 30 AUG; FIXED EAST-SIDE ERROR IN 'DIST'.. MOSHELL.
;
* WHERE * TYE SHULTZ / 3 FEB 79 / VERSION 2.1
*
* 'WHERE' RETURNS VIA 'OUTPARM' THE X,Y LOCATION OF THE
; CENTER OF GRAVITY OF THE OBJECT NAMED BY FIRST PARAM.THE
* PIXEL COORDINATES ARE PLACED IN THE NEXT TWO PARAMETERS BY 'OUTPAR'.
*
* SYSTEM SUBROUTINES: INPARM, OBJR, OUTPARM.
*
* ALL REGISTERS ARE RESTORED.
*
CTRGRAVX EQU 2
INPARM EQU 5030H
OUTPARM EQU 5033H
OBJR EQU 5006H
*
ORG 2E50H
WHERE: MVI H,0 ;
CALL INPARM ; GET OBJECT # INTO D.
MOV D,E
MVI E,CTRGRAVX ; POINT E AT CTR.OF GRAV. X COORD.
CALL OBJR ; GET FIRST X INTO A.
XCHG
MOV E,A
CALL OUTPARM ; PUT X INTO SECOND PARAMETER.
XCHG
INR E ; POINT E AT FIRST PIXEL Y COORD.
CALL OBJR ; GET Y INTO A.
XCHG
MOV E,A
CALL OUTPARM ; PUT IT IN THE THIRD PARAMETER.
RET
***********************************************************************
* *
* DISTANCE OPERATOR *
* VERSION 1.1 *
* MAR. 26, 1979 *
* TYE SHULTZ *
* *
* THIS ROUTINE FINDS THE DISTANCE BETWEEN THE TWO OBJECTS *
* SPECIFIED IN THE FIRST TWO PARAMETERS FOLLOWING THE OPCODE. *
* THE DISTANCE FOUND IS PLACED IN THE THIRD PARAMETER. *
* *
* THERE ARE TWO MAJOR PHASES TO THIS ROUTINE: *
* 1) FIND THE MINIMUM AND MAXIMUM X COORDINATE AND Y COORD *
* IN EACH OF THE OBJECTS AND SAVE THEM IN 8 CONSECUTIVE *
* BYTES. *
* 2) USING THE MINIMUMS AND MAXIMUMS FOUND IN PHASE I, FIND *
* THE DISTANCE BETWEEN THE TWO OBJECTS AND PLACE IT IN *
* THE THIRD PARAMETER. THE ALGORITHM FOR THIS IS DESCRIBED *
* BELOW (SEE PHASE II). *
* *
* SUBROUTINES CALLED -- *
* INPARM - RETURNS THE NEXT PARAMETER IN THE PROGRAM QUEUE *
* IN REGISTERS D AND E (16 BIT PARAMS) OR IN E (8 *
* BIT PARAMS). *
* OUTPARM - PLACES THE 16 BIT VALUE IN D,E OR THE 8 BIT VALUE *
* IN E INTO THE NEXT PARAMETER IN THE PROGRAM *
* QUEUE. IF THE VALUE IS IN E ONLY, D MUST *
* BE ZERO. *
* OBJR - RETURNS A BYTE FROM AN OBJECT IN REGISTER A. THE *
* NUMBER OF THE DESIRED OBJECT MEST BE IN D AND THE *
* NUMBER OF THE DESIRED BYTE MUST BE IN E. *
* OBJW - PUTS THE CONTENTS OF REGISTER A INTO A BYTE OF *
* OF AN OBJECT. REGISTERS ARE AS IN OBJR. *
* SCANNER - SCANS THE PIXELS BYTES OF AN OBJECT AND *
* RETURNS THE MINIMUM AND MAXIMUM X AND Y *
* COORDINATES IN THE OBJECT. WHEN SCANNER IS *
* CALLED, REGISTERS D AND E MUST HAVE THE OBJECT *
* NUMBER AND THE NUMBER OF THE BYTE WHICH CONTAINS *
* THE Y COORD OF THE FIRST PIXEL (CURRENTLY THE *
* 5TH BYTE OF THE OBJECT). REGISTERS BC AND HL *
* MUST HAVE THE X,Y COORDS OF THE FIRST PIXEL. *
* *
***********************************************************************
*
INPARM EQU 5030H
OUTPARM EQU 5033H
OBJR EQU 5006H
PIXEL1X EQU 4
;
;
ORG 2E70H
DIST: MVI A,1 ;SET OBJECT FLAG TO 1 INITIALLY. WHEN AN OBJECT
STA OBJFLAG ;HAS BEEN SCANNED, OBJFLAG IS DECREMENTD BY 1. IF
;IT IS THEN NON-NEGATIVE, THE NEXT OBJECT IS
;SCANNED. OTHERWISE, PHASE II BEGINS.
LXI H,OBJ1XMAX ;GET THE ADDRESS OF THE FIRST OF THE 8
PUSH H ;BYTES THAT WILL HOLD THE MIN AND MAX X AND
;Y COORDS.
;
;
************
*
* PHASE I -- GET THE NUMBER OF THE OBJECT SPECIFIED BY THE NEXT
* PARAMETER IN THE QUEUE AND INITIALIZE THE MINS AND MAXIMUMS
* FOR THAT OBJECT. CALL THE SCANNER TO RETURN THE ACTUAL
* MINIMUMS AND MAXIMUMS AND SAVE THEM. THEN CHECK IF ANOTHER
* OBJECT REMAINS TO BE SCANNED. IF ONE DOES REMAIN, CONTINUE
* PHASE I AT THE TOP; OTHERWISE GO ON TO PHASE II.
;
;
PHASE1: CALL INPARM ;GET THE NUMBER OF THE NEXT OBJECT INTO D
MOV D,E ;AND THE BYTE NUMBER OF THE FIRST PIXEL X
MVI E,PIXEL1X ;COORD INTO E.
CALL OBJR ;GET THE VALUE OF THE FIRST PIXEL X COORD INTO
MOV B,A ;REGISTERS B AND H (INITIAL MIN AND MAX).
MOV H,A ;THEN POINT REGISTER E AT THE FIRST PIXEL Y
INR E ;COORD, GET THE Y VALUE, AND INITIALIZE THE
CALL OBJR ;MINIMUM AND MAXIMUM Y COORD
MOV C,A ;REGISTER C AND L.
MOV L,A
CALL SCANNER ;SCAN THE OBJECT FOR THE ACTUAL MINIMUM AND
;MAXIMUM X AND Y (X MIN IN B, MAX IN H - Y
;MIN IN C AND MAX IN L).
;
; SAVE THE MINIMUM AND MAXIMUM VALUES FOR THE CURRENT OBJECT.
;
XCHG ;SAVE THE MAX X AND Y IN DE. THEN GET THE ADDRESS
POP H ;OF THE FIRST OF THE FOUR BYTES WHICH WILL
MOV M,D ;HOLD THE MINS AND MAXES. SAVE THE MAX X.
INX H ;
MOV M,B ;SAVE THE MIN X.
INX H
MOV M,E ;SAVE THE MAX Y.
INX H ;
MOV M,C ;SAVE THE MIN Y.
INX H ;LEAVE HL POINTING AT THE NEXT BYTE TO HOLD
;A MAX X (IF THERE IS ANOTHER OBJECT TO BE
;SCANNED).
;
; CHECK IF ANOTHER OBJECT NEEDS TO BE SCANNED. IF ONE DOES, GO BACK
; TO THE START OF PHASE I. OTHERWISE, GO ON TO PHASE II.
;
LDA OBJFLAG ;GET THE END OF PHASE I FLAG AND DECREMENT IT.
DCR A ;IF THE RESULT IS NEGATIVE, BOTH OBJECTS HAVE
JM PHASE2 ;BEEN SCANNED --> GO TO PHASE II. OTHERWISE,
STA OBJFLAG ;SAVE THE FLAG AND THE ADDRESS OF THE BYTE
PUSH H ;BYTE WHICH WILL RECEIVE THE MAX X OF THE
JMP PHASE1 ;SECOND OBJECT AND CONTINUE PHASE I.
;
;
*****************
*
* PHASE II -- THIS PHASE DETERMINES THE DISTANCE BETWEEN THE TWO
* OBJECTS AND PLACES THAT DISTANCE IN THE NEXT PARAMETER
* IN THE QUEUE. TO DETERMINE THE DISTANCE BETWEEN THE TWO
* OBJECTS, THIS VERSION FIRST FINDS THE DISPLACEMENTS
* BETWEEN THE OBJECTS IN THE X AND Y DIRECTIONS. IF THE
* OBJECTS OVERLAP IN EITHER (OR BOTH) DIRECTIONS, A
* DISPLACEMENT OF -1 IS ASSIGNED IN THAT DIRECTION. THE
* LARGER OF THE TWO DISPLACEMENTS IS THEN CHOSEN AS THE
* DISTANCE BETWEEN THE OBJECTS. IF BOTH DISPLACEMENTS ARE
* -1, A DISTANCE OF 0 IS CHOSEN.
*
*****************
;
;
*
* THIS SECTION DETERMINES THE DISPLACEMENT OF THE TWO OBJECTS IN THE X
* DIRECTION AND EXITS WITH THAT DISPLACEMENT IN REGISTER H.
*
;
PHASE2: LDA OBJ1XMAX ;CHECK IF THE MAXIMUM X OF THE FIRST OBJECT
MOV B,A ;IS <= THE MINIMUM X OF THE SECOND OBJECT.
LDA OBJ2XMIN ;IF IT IS, GET THE X DISPLACEMENT INTO A AND
SUB B ;JUMP TO THE END OF THIS SECTION. OTHERWISE,
JM XTEST2 ;JUMP TO THE NEXT TEST.
JMP SECTEND
;
XTEST2: LDA OBJ2XMAX ;CHECK IF THE MAX X OF THE SECOND OBJECT IS
MOV B,A ; <= THE MINIMUM X OF THE FIRST OBJECT.
LDA OBJ1XMIN ;IF IT IS, GET THE X DISPLACEMENT INTO A AND
SUB B
JP SECTEND ;JUMP TO THE END OF THIS SECTION. OTHERWISE,
XRA A ;THE OBJECTS OVERLAP AND A DISPLACEMENT OF
DCR A ; -1 IS SAVED.
SECTEND: MOV H,A ;SAVE THE DISPLACEMENT FOUND FOR USE IN THE THIRD
;SECTION.
;
;
*
* THIS SECTION DETERMINES THE DISPLACEMENT OF THE TWO OBJECTS IN THE Y
* DIRECTION AND EXITS WITH THE DISPLACEMENT FOUND IN REGISTER A.
*
;
;
LDA OBJ1YMAX ;LOGIC IS THE SAME AS THE LAST SECTION.
MOV B,A
LDA OBJ2YMIN
SUB B
JP GETDIST
;
LDA OBJ2YMAX
MOV B,A
LDA OBJ1YMIN
SUB B
JP GETDIST
;
XRA A
DCR A
;
;
;
*
* THIS SECTION CHOOSES THE LARGER OF THE TWO DISPLACEMENTS FOUND PREVIOUSLY
* AND SETS THE NEXT PARAMETER IN THE QUEUE TO THIS DISTANCE. IF
* BOTH DISPLACEMENTS = -1, THE DISTANCE BETWEEN THE TWO
* OBJECTS IS ZERO.
*
;
GETDIST: CMP H ;IF THE TWO DISPLACEMENTS ARE EQUAL, GO CHECK
JZ TSTOUCH ;IF THEY ARE BOTH = -1. IF THE Y DISPLACEMENT
JP SAVYDIST ;(IN A) IS GREATER, GO SAVE IT.
MOV E,H ;ELSE SAVE THE X DISPLACEMENT AND GO EXIT
JMP ENDIST ;THIS SECTION.
;
TSTOUCH: ANA A ;CHECK IF THE Y DISPLACEMENT IS -1. IF NOT,
JP SAVYDIST ;GO SAVE IT AS THE DISTANCE. IF IT IS,
XRA A ;SET IT TO 0 AND FALL THROUGH.
SAVYDIST: MOV E,A ;SAVE THE Y DISPLACEMENT (OR A ZERO IF
;BOTH DISPLACEMENTS WERE -1.
ENDIST: XRA A ;MOVE A ZERO INTO D AND PUT THE DISTANCE INTO
MOV D,A ;THE NEXT PARAMETER.THEN RETURN CONTROL TO EXEC.
PUSH D
CALL OUTPARM
POP D
;
; SET THE ZERO FLAG IF DISTANCE IS ZERO.CLEAR IT OTHERWISE.
ZFLAG EQU 40H
NOZFLAG EQU 0BFH
FLAGS EQU 114H
;
XRA A
CMP E ;IF E IS ZERO,
JZ YESZERO
NOZERO: LDA FLAGS
ANI NOZFLAG
STA FLAGS
RET
YESZERO:LDA FLAGS
ORI ZFLAG
STA FLAGS
RET
;
;
;
*************************************************************************
* *
* SCANNER -- THIS ROUTINE SCANS THROUGH THE OBJECT, COMPARING EACH *
* X AND Y COORD TO THE MINIMUM AND MAXIMUM X AND Y FOUND *
* SO FAR. ON ENTRY, BC AND HL MUST HAVE THE X,Y OF THE *
* FIRST PIXEL. DE MUST HAVE THE NUMBER OF THE OBJECT *
* TO BE SCANNED AND THE NUMBER OF THE BYTE WHICH HAS *
* THE Y OF THE FIRST PIXEL. *
* *
*************************************************************************
;
;
SPECODE EQU 0FFH
ENDFLAG EQU 80H
;
SCANNER: INR E ;CHECK IF THE NEXT BYTE OF THE OBJECT IS A
CALL OBJR ;IS A SPECIAL CODE (HEX FF). IF IT IS,
CPI SPECODE ;JUMP TO A ROUTINE TO CHECK IF THE END
JZ TESTEND ;OF THE OBJECT HAS BEEN REACHED. THIS ROUTINE
;BUMPS REG E TO THE NEXT PIXEL AND RETURNS
;TO THE TOP OF THE SCANNER IF THE END WASN'T
;REACHED.
CMP B ;CHECK IF THE NEX X IS A NEW MIN OR MAX.
JM NEWXMIN ;IF IT'S A NEW MIN, GO SAVE IT AND CHECK FOR
CMP H ;A NEW Y MIN OR MAX. ELSE DO THE SAME FOR A NEW
JM CHECKY ;X MAX. IF IT'S NOT A NEW MIN OR MAX X,
;GO CHECK THE NEXT Y.
NEWXMAX:MOV H,A
JMP CHECKY
NEWXMIN:MOV B,A ;SAVE THE NEW MINIMUM X.
CHECKY: INR E ;POINT E AT THE NEXT BYTE (A Y COORD).
CALL OBJR
CMP C
JM NEWYMIN
CMP L
JM SCANNER
MOV L,A ;SAVE A NEW Y MAX.
JMP SCANNER
NEWYMIN: MOV C,A ;SAVE A NEW Y MIN.
JMP SCANNER
;
;
; THIS ROUTINE CHECKS IF THE BYTE FOLLOWING A SPECIAL CODE BYTE IS AN
; END OF OBJECT FLAG (HEX 80). IF IT IS, A RETURN FROM THE SCANNER
; IS EXECUTED. IF NOT, CONTROL RETURNS TO THE TOP OF THE SCANNER.
;
TESTEND: INR E
CALL OBJR
CPI ENDFLAG
JNZ SCANNER
RET
;
;
*********************************************************************
*
* DATA AREA FOR DISTANCE OPERATOR.
*
*********************************************************************
;
;
OBJ1XMAX DB 0H
OBJ1XMIN DB 0H
OBJ1YMAX DB 0H
OBJ1YMIN DB 0H
OBJ2XMAX DB 0H
OBJ2XMIN DB 0H
OBJ2YMAX DB 0H
OBJ2YMIN DB 0H
OBJFLAG DB 1