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
/
DOODLE.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
14KB
|
580 lines
;7 SEPT; FULL-MESSAGE,PATHMAKE - SPACE .
;
**************************************************************************
* *
* DOODLE *
* -A PART OF THE 'FELIX' ANIMATION SYSTEM. U OF TENNESSEE.
* MUKESH & LOVELACE 2/79 ... MODS BY MOSHELL 3/79 *
*
* *
* THIS ROUTINE DOODLES AN OBJECT ON THE SCREEN AND SAVES THE *
* PIXELS BY CALLING 'OBJW'. WHEN TERMINATED BY CTRL/C, THE CORRECT
* 'CENTER OF GRAVITY' IS CALCULATED AND INSERTED AT HEAD
* OF OBJECT. INITIAL COLOR IS SET BY INPUT CURSOR COLOR.INITIAL
* ORIENTATION IS ZERO. FURTHER COLORS ARE SET BY INSERTING CORRECT
* SPECIAL CODES INTO THE OBJECT BEING CREATED.
* CTRL/N 'CLOSES'CURRENT OBJECT,RESTARTS PROGRAM.
* CTRL/C 'CLOSES' OBJECT, RETURNS TO CP/M.
* TYPING 'Z' CLEARS THE SCREEN,DOESN'T CHANGE OBJECTS.
*
* *
**************************************************************************
*
* CALLS: OBJW,PUT,CP/M (I/O)
*
* THE TABLE OF EQUATES:
*
*
*
*
UP EQU 'I' ;COMMAND ASCII VALUES:
DOWN EQU ','
LEFT EQU 'J'
RIGHT EQU 'L'
UPLEFT EQU 'U'
UPRIGHT EQU 'O'
DOWNLEFT EQU 'M'
DOWNRGT EQU '.'
*
RED EQU 'R'
GREEN EQU 'G'
BLUE EQU 'B'
CYAN EQU 'C'
YELLOW EQU 'Y'
PURPLE EQU 'P'
WHITE EQU 'W'
BLACK EQU '#'
NOCOLOR EQU '0'
*
HI$INTEN EQU '!'
*
BINRED EQU 01H ;BINARY VALUES OF COLORS
BINBLUE EQU 04H
BINGREEN EQU 02H
BINCYAN EQU 06H
BINYELLW EQU 03H
BINPRPL EQU 05H
BINWHITE EQU 07H
BINBLACK EQU 00H
*
CIREAL EQU 5027H ;WE HAVE A LOCAL 'CI'0TO GRAB CTRL/C...
DISPOFF EQU 5057H
DISPON EQU 5054H
BACKBUF EQU 5092H
CO EQU 502AH
PRINT EQU 502DH
GETW EQU 5003H
PUTW EQU 5000H
OBJR EQU 5006H
CR EQU 0DH
LF EQU 0AH
OBJW EQU 5009H
*
BIOS EQU 5H
CLEAR EQU 5021H
ONBUF EQU 5090H
;
ORG 100H
LXI SP,4000H ;SAFE PLACE,WE THINK.
CALL SURVIVAL ;MAKE SURE FELIX UTILS ARE THERE.
LHLD ONBUF
SHLD ONBSTASH ;POINT 'PUT'&'GET' AT BACKBUF.
LHLD BACKBUF
SHLD ONBUF
CALL DISPON ;TURN ON THE SCREEN,AND CLEAR.
SUB A
CALL CLEAR ;FILL SCREEN WITH BLANK.
;
OBJECT1 LXI H,MSG1 ;OUTPUT STARTING MESSAGE - PROMPT
* FOR OBJECT #
CALL PRINT ;NEXT, GET INPUT CHARACTER AFTER
CALL CI ;PRINTING MSG.
CALL CONVRT ;CONVERT THE ASCII TO BINARY &
JC OBJECT1 ;IF ILLEGAL, REPEAT. ELSE
STA OBJNO ;STORE IN MEMORY.
*
*
* FOUND CORRECT (CONFIRMED) OBJECT #. INITIALIZE CERTAIN FLAGS, BYTES,
* ET. AL.
*
SUB A ;ZERO OUT A
STA BYTENO ;BYTE # IS 0
*
MVI A,20H ;START CURSOR IN CNTR OF SCREEN.
*
MOV B,A ;INIT X COORD
MOV C,A ; & Y COORD.
MVI A,0FFH ;FIRST COLOR IS WHITE.
STA COLOR ;INIT COLOR BYTE
*
* THIS IS THE TOP OF A HUGE LOOP. CONTROL IS BROUGHT HERE IF THE CURSOR
* HAS BEEN MOVED INTO A NEW PIXEL. INITIALLY, THIS IS SO.
*
NEWPIXEL CALL GETW ;FIND OUT WHAT THE EXISTING VALUE
* OF PIXEL IS,
STA BKGND ;AND PUT THIS IN MEMORY FOR LATER.
*
* THIS POINT IS THE ACTUAL POINT ON ANY OTHER COMMAND.
*
FLASHER MVI D,0FH ;SET UP TO OUTPUT WHITE IN PIXEL
CALL PUTW ;THIS IS THE BLINKING CURSOR.
CALL DELAY ;DELAY A BIT BEFORE CHANGING
MVI D,BINBLACK ;TO BLACK
CALL PUTW
*
* NOW SEE IF THERE IS A CHARACTER INPUT
*
PUSH H
PUSH D
PUSH B
MVI C,11 ;CONSOLE STATUS READY?
CALL BIOS
POP B
POP D
POP H
ANI 01 ;CHECK READY BIT IN A.
JNZ GETCOMMD
*
* NO CHARACTER INPUT YET.
*
CALL DELAY ;DELAY SOME & THEN
JMP FLASHER ;REPEAT WHOLE PROCESS.
*
* A CHARACTER HAS BEEN FOUND ON INPUT.
*
GETCOMMD CALL CI ;ASCII CHAR IN A
*
LXI H,FLASHER ;TOP OF GRAND LOOP - FLASHING CURSOR
PUSH H ;PUSH TO REDUCE CODE SPACE LATER
* ON MULTIPLE RETURNS.
*
* ALL THE MOVES:
*
LXI H,MOVPROCS ;PUSH THIS LABEL FOR COMMON JUMP IN MOVE
PUSH H ;PROCESSING SEGMENTS.
*
CPI UP ;COMPARE SUCCESSIVELY & JUMP TO
JZ MOVEUP ;HANDLING CODE.
CPI DOWN
JZ MOVEDOWN
CPI LEFT
JZ MOVELEFT
CPI RIGHT
JZ MOVRIGHT
CPI UPLEFT
JZ MOVUPLFT
CPI UPRIGHT
JZ MOVUPRGT
CPI DOWNLEFT
JZ MOVDNLFT
CPI DOWNRGT
JZ MOVDNRGT
*
* ALL THE COLORS HANDLED SEPARATELY.
*
POP H ;POP EARLIER WRONG LABEL.
LXI H,STORCOLR ;PUSH LABEL FOR COMMON JUMP ON PROC.
PUSH H ;DIFFERENT COLORS.
*
CPI RED
JZ COLRED
CPI BLUE
JZ COLBLUE
CPI GREEN
JZ COLGREEN
CPI CYAN
JZ COLCYAN
CPI YELLOW
JZ COLYELLW
CPI PURPLE
JZ COLPRPL
CPI WHITE
JZ COLWHITE
CPI BLACK
JZ COLBLACK
*
CPI NOCOLOR ;TURN OFF COLOR DEPOSIT.
JZ TRNOFFCL
*
POP H ;COMMON POINT NO MORE NECESSARY.
*
* INTENSITY HIGH CHANGE.
*
CPI HI$INTEN
JZ INTENS
*
* MOVE HANDLING CODES:
*
MOVEUP SUB A ;DELX=0, DELY=1
STA DELX
INR A
STA DELY
RET
*
MOVEDOWN SUB A ;DELX=0, DELY=-1
STA DELX
DCR A
STA DELY
RET
*
MOVELEFT SUB A ;DELX=-1, DELY=0
STA DELY
DCR A
STA DELX
RET
*
MOVRIGHT SUB A ;DELX=1, DELY=0
STA DELY
INR A
STA DELX
RET
*
MOVUPLFT MVI A,01H ;DELX=-1, DELY=1
STA DELY
DCR A
DCR A
STA DELX
RET
*
MOVUPRGT MVI A,01H ;DELX=1, DELY=1
STA DELX
STA DELY
RET
*
MOVDNLFT MVI A,0FFH ;DELX=-1, DELY=-1
STA DELX
STA DELY
RET
*
MOVDNRGT MVI A,01H ;DELX=1, DELY=-1
STA DELX
DCR A
DCR A
STA DELY
RET
*
* THIS IS THE COMMON POINT FOR ALL MOVES. BY EXECUTING THE RETURN,
* AT THE END OF EACH SEPARATE SEGMENT OF CODE, A JUMP IS TAKEN TO THIS
* POINT.
*
MOVPROCS LXI H,INTENBYT ;POINT HL AT INTENSITY BYTE
MOV A,M ;PICK UP THAT BYTE
INX H ;INCREMENT HL TO POINT TO COLOR BYTE
ORA M ;(ARRANGED SUCH). OR THE INTENSITY WITH
MOV D,A ;COLOR & SETTLE IN D (COPY STILL IN A).
CPI 80H ;SEE IF LESS THAN THIS #. CARRY FLAG SET
JC PUTCOLOR ;IF THIS IS TRUE.
*
* HERE, RESTORE BACKGROUND COLOR, FOUND AT THE TIME OF ENTRY OF CURSOR
* INTO PIXEL.
*
LDA BKGND ;GET BACKGROUND COLOR
MOV D,A ;PUT IN D & PUT OUT THE
CALL PUTW ;PIXEL.
MOV A,C ;PUT THE Y COORD IN ACC FOR CONTINUITY.
JMP INCCOORD ;INCREMENT COORDS FOR MOVE.
*
* A COLOR TO BE OUTPUT IN COORD POSITION
*
PUTCOLOR CALL PUTW ;OUTPUT PIXEL WITH COLOR IN D.
*
* IF IT IS BYTE # 0, THEN WRITE OUT COLOR AND THEN 0 AND THEN COORDS.
*
LDA BYTENO ;GET BYTE # IN A
CPI 0H ;SET ZERO FLAG FOR LATER...
MOV E,A ;MOVE BYTE # TO D. FLAG IS SET FOR CHECK
LXI H,OBJNO ;POINT HL AT OBJ # BYTE FOR LATER.
MOV A,D ;PUT COLOR IN A
MOV D,M ;GET OBJECT # IN D
JNZ COLCHNG ;FLAG SET BY EARLIER COMPARISON TESTED:
CALL OBJW ;BYTE 0 IS BEING WRITTEN - COLOR
INR E ;INCREMENT THE BYTE #
SUB A ;ZERO A FOR 2ND BYTE
CALL OBJW ;WRITE 00 INTO BYTE 2
INR E ;SAVE 2 BYTES IN OBJECT FOR
INR E ;'CENTER OF GRAVITY'.
INR E ;INC. BYTE #
LDA COLOR ;MAKE THE OLD COLOR THE SAME
STA OLDCOLOR ;AS THE NEW COLOR.
JMP OUTCOORD ;THEN, OUTPUT THE COORDS.
*
* THIS IS HOW OBJECT IS FORMATTED, SEQUENTIALLY, STARTING WITH BYTE 0:
*
* COLOR :ORIENTATION:X-CTR-OF-GRAV:Y-CTR-OF-GRAV: X1 : Y1 : ... ETC
* UNTIL AN 'X-COORD' IS :FF: THEN THE NEXT BYTE IS A NEW COLOR.
*
*
* CHECK HERE IF THERE IS A CHANGE IN COLOR: BYTE # IN E, OBJECT # IN D.
*
COLCHNG LXI H,OLDCOLOR ;POINT HL AT OLD COLOR FOR
CMP M ;COMPARISON WITH COLOR IN A
JZ OUTCOORD ;IF SAME, BRANCH.
MOV H,A ;ELSE, SAVE NEW COLOR IN H
MVI A,0FFH ;WRITE OUT FF IN OBJECT LIST
CALL OBJW
INR E ;INCREMENT THE BYTE NUMBER
MOV A,H ;RESTORE COLOR IN A
CALL OBJW ;AND WRITE OUT THE COLOR
INR E ;INC. BYTE #
STA OLDCOLOR ;MAKE OLDCOLOR=COLOR.
*
* NEXT OUTPUT COORDINATES X & Y IN BC PAIR TO OBJECT.
*
OUTCOORD MOV A,B ;OUTPUT X COORD
CALL OBJW
INR E
MOV A,C ;OUTPUT Y COORD AFTER INCREMENTING BYTE#
CALL OBJW
INR E ;INC. BYTE #.
LXI H,BYTENO ;POINT HL AT BYTE# TO SAVE LATEST VALUE.
MOV M,E ;SAVED.
;
;CHECK TO SEE IF WE SHOULD ABEND BECAUSE OF "FULL OBJECT".
;
PUSH PSW
MVI A,251 ;LAST LEGIT SPOT IN OBJECT.
CMP E ;(A-E);CARRY=BORROW IFF E>251.
JNC STILLOK
;
;OBJECT IS FULL.
;
MVI E,252 ;GET 4 FINAL BYTES TO WORK WITH.
CALL WINDUP ;DO C-OF-G,ENDMARK,PATH-LOCATIONS.
LXI H,FULLMSG
CALL PRINT
JMP OBJECT1
FULLMSG:DB 'THIS OBJECT IS FULL.SORRY...',CR,LF,'$'
STILLOK:POP PSW
*
* HERE INCREMENT COORDS BY ADDING DELX & DELY TO B,C.
*
INCCOORD LXI H,DELY ;A CONTAINS Y COORD.
ADD M ;ADD DELY
MOV C,A ;PUT BACK IN C
MOV A,B ;GET X COORD IN A
DCX H ;POINT H AT DELX (ARRANGED SO)
ADD M ;ADD DELX
MOV B,A ;PUT BACK IN B
POP H ;DUMB POP SO AS NOT TO EAT STACK.
JMP NEWPIXEL
*
* COLOR HANDLING CODE:
*
COLRED MVI A,BINRED ;PUT RED CODE IN COLOR
RET
*
COLBLUE MVI A,BINBLUE ;PUT BLUE CODE IN COLOR
RET
*
COLGREEN MVI A,BINGREEN ;PUT GREEN CODE IN COLOR
RET
*
COLCYAN MVI A,BINCYAN ;PUT CYAN CODE IN COLOR
RET
*
COLYELLW MVI A,BINYELLW ;PUT YELLOW CODE IN COLOR
RET
*
COLPRPL MVI A,BINPRPL ;PUT PURPLE CODE IN COLOR
RET
*
COLWHITE MVI A,BINWHITE ;PUT WHITE CODE IN COLOR
RET
*
COLBLACK MVI A,BINBLACK ;PUT BLACK CODE IN COLOR
RET
*
TRNOFFCL MVI A,80H ;PUT TURN-OFF-COLOR CODE IN COLOR
*
* HERE, THE ACCUMULATOR CONTAINS CODE FOR VARIOUS COLORS OR 80 FOR TURN-
* OFF.
*
STORCOLR STA COLOR
RET ;THIS TAKES IT BACK TO FLASHER.
*
* SET HIGH INTENSITY
*
INTENS LDA INTENBYT ;INTENSITY BIT OF COLOR NIBBLE.
XRI 08H ;FLIP THE BIT
STA INTENBYT
RET
*
* DATA AREA
*
ONBSTASH DW 0 ;TO HOLD 'ONBUF'ADDR WHILE WE USE BACKBUF.
MSG1 DB CR,LF,'ENTER OBJECT # > $'
*
INTENBYT DB 0 ;INTENSITY OF COLOR
COLOR DB 0 ;ENTERED COLOR
OLDCOLOR DB 0FFH ;OLD COLOR BEFORE COLOR CHANGE (IF ANY)
DELX DB 0 ;X INCREMENT FOR MOVE
DELY DB 0 ;Y INCREMENT FOR MOVE
BYTENO DB 0 ;BYTE # TO BE WRITTEN OUT
OBJNO DB 0 ;OBJECT # BEING WRITTEN
BKGND DB 0
* THIS SUBROUTINE PRODUCES A DELAY, BY EXECUTING A LOOP OF NOPS,
* WITHIN ANOTHER LOOP. BOTH LOOPS COUNT DOWN FROM 255.
*
DELAY PUSH PSW ;SAVE A AND FLAGS
PUSH D ; " DE PAIR
MVI A,044H ;SET UP COUNT DOWN VALUE IN A
MOV D,A ;PUT IN D, THE OUTER LOOP COUNTER &
LOOP1 MOV E,A ;PUT IN E, THE INNER LOOP COUNTER.
LOOP2 NOP ;DELAY --- WASTE
NOP ; TIME
NOP
DCR E ;DECREMENT INNER LOOP COUNTER
JNZ LOOP2 ;IF NOT 0, REPEAT; ELSE
DCR D ;DROP OUT OF LOOP & DECREMENT OUTER LOOP CTR,
JNZ LOOP1 ;& IF NOT 0, START INNER LOOP AGAIN.
POP D ;ELSE, RESTORE DE PAIR &
POP PSW ;A & FLAGS &
RET ;RETURN.
* SUBROUTINE TO CONVERT AN ASCII CHARACTER INPUT TO NUMERIC (HEX) IF
* SUCH A CHARACTER. THE CARRY FLAG IS SET ON RETURN IF THIS IS NOT SO.
* INPUT IS THE ASCII CHAR IN THE ACCUMULATOR.
* OUTPUT IS THE BINARY VALUE IN A IF LEGAL.
*
CONVRT SUI '0' ;CHAR - '0'
JC ERROR ;IF < 0, ERROR
ADI 0E9H ;ADD '0'-'G'.
JC ERROR ;IF > F, ERROR
ADI 6 ;INC BASE FOR A-F
JP ATHRUF ;IF +VE, ONE OF A-F
ADI 7 ;ELSE, MAYBE 0-9
JC ERROR ;IF > 9, ERROR
ATHRUF ADI 10 ;CORRECT THE BASE
ORA A ;CLEAR CARRY
RET
*
* ERROR CODE
ERROR STC
RET
;
; LOOK FOR CTRL/C OR CTRL/N,TERMINATION COMMANDS.
;
CI: CALL CIREAL ;WE GO GET A CHARACTER VIA CP/M.
CPI 'Z' ;CLEAR SCREEN?
JNZ CTRLN
SUB A
CALL CLEAR
JMP CI
CTRLN: CPI 0EH ;CTRL/N?(NEXT OBJECT REQUEST).
JNZ CTRLC
CALL WINDUP ;CLOSE THIS OBJECT.
JMP OBJECT1
CTRLC: CPI 03H ;CTRL/C? (END OF DOODLING).
RNZ
CALL WINDUP
CALL DISPOFF
LHLD ONBSTASH
SHLD ONBUF ;CORRECT POINTERS WE MESSED WITH.
JMP 0H ;GOTO CP/M.
;
; WINDUP: PUTS ENDCODE ON OBJECT,EVALUATES CTR-OF-GRAVITY.
;
WINDUP: MVI A,0FFH
LDA OBJNO
MOV D,A ;SELECT OBJ. FOR FINAL WRITEOUT.
MVI A,0FFH
CALL OBJW
INR E
MVI A,80H
CALL OBJW
;
; CENTER - OF - GRAVITY CALCULATION: FIND MAX,MIN X,Y
; SET CNTRX=(MAXX+MINX)/2, LIKEWISE Y.
;
MVI B,0FFH ;B HAS MIN-X
MOV H,B ;H HAS MIN-Y
MVI C,0H ;C HAS MAX-X
MOV L,C ;L HAS MAX-Y ;NOTE:UNSIGNED COMPARES USED
; ;IN ALL THIS ROUTINE.
MVI E,4 ;START WITH FIRST PIXEL-PLACE IN OBJECT.
COGTOP: CALL OBJR
CPI 0FFH ;SPECIAL CODE?
JZ SPECIAL
;
; COMPUTE MAX AND MIN VALUES
;
CMP B
JNC XMAX ;IF (A-B)>=0 THEN B<=A.LEAVE IT.
MOV B,A ;NEW MINX WAS FOUND.
XMAX: CMP C
JC YMIN
MOV C,A ;NEW MAXX WAS FOUND.
YMIN: INR E ;GO LOOK AT THIS PIXEL'S Y.
CALL OBJR
CMP H
JNC YMAX
MOV H,A ;NEW MINY WAS FOUND.
YMAX: CMP L
JC MAXBOT
MOV L,A ;NEW MAXY.
MAXBOT: INR E
JMP COGTOP
;
; WAS THIS AN ENDMARKER?
;
SPECIAL:INR E
CALL OBJR
INR E
CPI 80H ;ENDMARKER?
JNZ COGTOP ;GO ROUND SMORE;T'WASNT.
;
; CALCULATE C-OF-GRAVITY NOW;WE:RE DONE.
;
MVI E,2 ;WHERE TO PUT IT.
MOV A,B
ADD C
STC
CMC ;GIVE ME A HI-BIT ZERO
RAR ;TO COVER WHEN I DIVIDE BY 2
CALL OBJW ;AND PUT IT IN AS X-CTR-OF-G.
INR E
MOV A,H
ADD L
STC
CMC
RAR
CALL OBJW ;PUT OUT Y-CTR-OF-G.
;
;WE PREPARE TWO BYTES AT THE END OF THE OBJECT
;FOR 'PATH' TO STORE INFO IF THIS OBJECT EVER
; MOVES ALONG A PATH.
;
XRA A
MVI E,254 ;NULL OBJECT'S LAST TWO BYTES
CALL OBJW
INR E ;FOR USE BY PATH.
CALL OBJW
;
RET
;
*
; 16 JULY 79 : MOSHELL
;
;TACK ON CODE FOR ROUTINES THAT EXPECT THE 'FELIX' UTILITY
;PACKAGE TO BE IN RESIDENCE. CRIES 'HELP HELP' (ACTUALLY
;IN A DIGNIFIED WAY) WHEN THE DISPATCH TABLE
;AT 5000H IS MISSING. CALLS CPM BIOS...JUMPS TO WARM BOOT
;IF THE TABLE ISN'T THERE.
;
;THIS HAS NO ORG BECAUSE IT'S TACKED ON TO STUFF.
;
CPM EQU 0
SURVIVAL:LDA 5000H ;WHERE 'FELIX' STARTS.
CPI 0C3H ;IS IT A JUMP?
JNZ BAD ;IF NOT WE'RE WITHOUT UTILITIES.
LDA 5003H
CPI 0C3H ;IS THERE ANOTHER ONE?
RZ ;IF SO WE ASSUME ALL'S WELL.
BAD: LXI D,TEXT
MVI C,9 ;CALL FOR TEXT-PRINT
CALL BIOS
JMP CPM
TEXT: DB 'PLEASE LOAD THE FELIX UTILITIES BY '
DB 'TYPING "FELIX" FIRST.',0DH,0AH,'$'
END