;************************************************************************** ; PLOTTER CONTROL SUBROUTINES FOR HP7221C ; COPYRIGHT 1981 DASOFT DESIGN SYSTEMS, INC. ; THESE PROGRAMS ARE PROTECTED BY LICENSING AGREEMENTS ; AND CANNOT BE USED OR DUPLICATED WITHOUT WRITTEN ; PERMISSION FROM DASOFT. ; rev 2.6 4/1/85 cwm ; 2.6 NOTES ; 2.6 requires the use of the flags twoex and cirk which will be ; ORGed or .phased at 1bf0h. ;~*~*~*~*~*~{* NOTE *}~*~*~*~*~*~ ; this routine was written for an unknown assembler using z80 code ; and I have never been able to assemble this code. ; *************** FOR YOUR INFORMATION ********************* ; THIS DRIVER USES THE CP/M LIST DEVICE TO SEND THE DATA VIA ; THE RS-232 LINK TO THE HP7221C. DELAYS HEREIN ARE SET FOR ; 2400 BAUD OUTPUT. IF YOU ARE GOING TO USE A DIFFERENT BAUD ; RATE, CONSULT THE TABLE BELOW AND CHANGE THE DELAY EQUATE ; FOR 9600 BAUD, XDEL2 = 52 ; 4800 26 ; 2400 13 ; 1200 7 ; 600 3 ETCETERA XDEL2 EQU 13 ;I LIKE TO BE SURE OUTFUNC EQU 5 ; SEND TO CPM LIST DEVICE ; ABOVE IS THE EQUATE TO SEND THE DATA TO THE CP/M LIST DEVICE, ; FUNCTION NUMBER 5. IF YOU WOULD LIKE IT SENT TO THE PUNCH ; DEVICE, ETCETERA, YOU MAY CHANGE THIS EQUATE. IF USING ANOTHER ; OUTPUT TECHNIQUE, YOU WILL NEED TO MODIFY THE PROGRAM SEGMENTS. ; BELOW, VARIABLES FDELAY AND SDELAY ARE SET UP FOR 2MHZ Z80 ; OPERATION. THESE NUMBERS ARE DELAY WEIGHTS FOR HOW LONG TO WAIT ; BETWEEN EACH CHARACTER SENT. AT LESS THAN 9600 BAUD OR WITH SLOWER ; PROCESSORS, YOU WILL NEED TO FIND NEW VALUES FOR THESE DELAYS ; *********************CAUTION CAUTION CAUTION************* ; DO NOT NOT NOT USE THE INSTALL PROGRAM ON THIS CONTROL ; ROUTINE, OR IMPORTANT VALUES WILL BE CHANGED FOR THE ; OTHER PLOTTER WE SUPPORT. YOU MAY USE THE TEST ROUTINE ; BY SKIPPING OVER THE INSTALLATION PART, BUT THIS SIMPLE ; DRIVER WILL NOT QUITE WRITE THE DASOFT LOGO CORRECTLY. ; SO DON'T WORRY ABOUT IT. ; SOME MAGIC DEFINED LOCATIONS USED: VERS EQU 0032H ; REV EQU 0034H ; EDIT EQU 0064H ; WBOOT EQU 0000H ; WARM BOOT ADDRESS TYPEF EQU 0002H ; BDOS PRINT COMMAND NUMBER BDOS EQU 0005H ; ADDRESS OF BDOS JUMP POINT BUFF EQU 0080H ; ADDRESS OF DISK INPUT BUFFER DMA EQU 001AH ; SET DMA ADDRESS FUNCT NUMB READF EQU 0014H ; DISK READ FUNCTION WRITEF EQU 0015H ; WRITE FILE TO DISK NUM OPENS EQU 000FH ; OPEN FILE FUNCT NUMBER CLOSES EQU 0010H ; CLOSE FILE FUNCT NUMBER FCB EQU 005CH ; FILE CONTROL BLOCK ADRS FCBDN EQU 005CH ; FCB DISK NAME FCBFN EQU 005DH ; FILE NAME FCBFT EQU 0065H ; FILE TYPE FCBEX EQU 0068H ; CURRENT EXTENT NUMBER FCBRC EQU 006BH ; EXTENT RECORD COUNT (0-128) FCBCR EQU 007CH ; CURRENT (NEXT) RECORD NUMBER FCBR0 EQU 007DH ; LSB OF 16 BIT RANDOM RECORD ADDRESS FCBR1 EQU 007EH ; MSB OF 16 BIT RANDOM RECORD ADDRESS FCBR2 EQU 007FH ; RECORD OVERFLOW FLAG TOPPTR EQU 0006H ; WAS (AD00H) STACK START 48K CLEAD EQU 0001H ; CURSOR POSITIONING STRING CODE P3LINES EQU 0003H ; PRINT THREE LINES CONTMSG EQU 000BH ; CONTINUE MESSAGE CODE CLS EQU 000CH ; CLEAR SCREEN CODE IVON EQU 000EH ; INVERSE ON CODE IVOFF EQU 000FH ; INVERSE OFF CODE CR EQU 000DH ; RETURN CHARACTER LF EQU 000AH ; LINE FEED CHARACTER BEEP EQU 0007H ; BEL CHARACTER TAB EQU 0009H ; TAB CHARACTER BS EQU 0008H ; BACK SPACE ESC EQU 001BH ; ESCAPE EOM EQU 00EEH ; END OF MESSAGE MARKER (OVERLAY FILE) EOF EQU 00FFH ; END OF FILE MARKER (OVERLAY FILE) MSCNT EQU 00F9H ; 1 MSEC SOFTWARE DELAY CONSTANT RDRL EQU 0103H ; LOADER KERNAL OR TEST PROG CLEARS EQU 0108H ; CLEAR SCREEN ROUTINE PSTRNG EQU 010EH ; PRINT AN ASCII STRING INCHNE EQU 011DH ; ROUTINE TO READ CONSOLE NO ECHO DUMP EQU 014DH ; BLOCK MOVE ROUTINE ; ***** REV 1.0 FOR HP7221C ****** ; ***** C.E.R.N (GENEVA,SWITZERLAND) MODIFIED **** ; ************************************************************** ; NOTE THAT THERE ARE SEVERAL ADAPTATIONS IN THIS PLOTTER ; DRIVER. IN PARTICULAR: ; 1) DASOFT USES PLOTTER UNITS OF 1 THOU (0.0254 MM), ; BUT THE HP7221 PLOTTER UNIT IS 0.0254 MM. THIS ; MEANS THAT THE DASOFT UNITS MUST BE CORRECTED BY ; MULTIPLYING BY A FACTOR OF 1.016 TO GET AN ACCURATE ; PLOT. ALTHOUGH DASOFT PROVIDES THE X AND Y CORRECTION ; FACTORS (XASIGN, YASIGN, XADJUST, YADJUST) AT THE ; END OF THE JUMP TABLE, WE HAVE NEVER BEEN ABLE TO ; MAKE THE Y CORRECTION WORK. SO THE CORRECTION IS ; DONE HERE IN THE PLOTTER CONTROL ROUTINE. ;============ NOTE ======== in 2.6 pcbplot both the x and y adjustments are fully functional. The y did not work in 2.5 ; cwm ; 2) DASOFT SENDS COORDINATES TO THE PLOTTER CONTROL ROUTINE ; IN THE FORM OF RELATIVE PEN MOVEMENTS. IN ORDER TO USE ; OUR UNITS CORRECTION WE HAVE HAD TO KEEP A TRACK OF THE ; ABSOLUTE COORDINATES, AND WE DRIVE THE PLOTTER IN ; ABSOLUTE MODE. THE ABSOLUTE COORDINATES ARE STORED IN ; DASOFT UNITS AND ONLY CORRECTED INTO HP7221 UNITS ; WHEN THEY ARE SENT TO THE PLOTTER. ; CHRIS F. BORE 3/3/83 ; ************************************************************* ORG 1800H ; JUMP TABLE ENTRY POINTS FOR EXTERNAL ENTRY ; PINIT AND CHGPPR, CHGPEN, MAY NEED TO BE CHAGED BY USER ; STRAIGHT TO CP/M PINIT: JP INIT PHOME: JP HOME VECTOR: JP MOVE CHGPPR: JP CHGPR CHGPEN: JP CHGPN TBLAD: DS 4 ; PLOTTER COORDINATE TABLE YASIGN: DB 0 ; SIGN OF Y CORRECTION 0=+ YADJUST:DB 65 ; MAGNITUDE OF Y CORRECTION XASIGN: DB 0 ; SIGN OF CORRECTION 0=+ XADJUST:DB 0 ; NUMBER OF GRIDS BEFRE CORRECTION X SLOW: DB 0 ; FLAG FOR DRAWING SLOW LINES ; HERE I DEFINE TWO 16 BIT NUMBERS TO HOLD THE CURRENT ; ABSOLUTE X AND Y COORDINATES. XLO: DB 0 ; LOW BYTE OF ABSOLUTE X XHI: DB 0 ; HIGH BYTE OF ABSOLUTE X YLO: DB 0 ; LOW BYTE OF ABSOLUTE Y YHI: DB 0 ; HIGH BYTE OF ABSOLUTE Y ; **********DELAYS FOR 2.5MHZ Z-80 2400 BAUD OPERATIONS **************** FDELAY: DW 0600H ; NORMAL 4MHZ (0180H) DELAY FACTOR SDELAY: DW 0C00H ; SUPER SLOW DRAW FACTOR(0300) SECND: DB 00H ; RAMP FACTOR PORT: DB 02H ; PORT NUMBER FOR OUTPUT PCTL: DB 0BH ; CONTROLL PORT NUMBER CTLCODE:DB 80H ; CONTROL CODE FOR 8255 ; ****** HOME PLOTTER COMMAND ********************** ; FOR THE HP7221C, HOME IS ACCOMPLISHED ; BY RUNNING THE PLOTTER INTO THE NEGATIVE STOPS. ; THATS RIGHT. THE PLOTTER USES 4 BYTES, X MAGNITUDE, ; XSIGN, Y MAGNITUDE, Y SIGN, SET TO NEGATIVE MAX X,Y ; DESTROYS A, NO ENTRY OR EXIT PARAMETERS ; *************************************************** ; THIS IS A KREONITE ADAPTATION, INTERFACE TO HP7221C ; HOME IS THE DEFAULT LOWER LEFT OF THE HP PLOTTER. HOME: PUSH AF PUSH BC PUSH DE PUSH HL ; **************************************************** ; HERE I ZERO THE ABSOLUTE X AND Y COORDINATES. ; **************************************************** LD HL,0 ; GET ZERO IN REGISTER PAIR HL LD (XLO),HL ; ZERO THE ABSOLUTE X COORDINATE LD (YLO),HL ; ZERO THE ABSOLUTE Y COORDINATE ; WHEN WE GET TO HERE THE ABSOLUTE X AND Y COORDINATES ARE ; SET TO ZERO. LD A,70H ; P CALL OUTCPM LD A,60H ; ' CALL OUTCPM LD A,7DH ; } CALL OUTCPM CALL DELAY2 JP BYE ; AND RETURN ; ********* CHANGE PAPER ROUTINE ******************** ; SOME PLOTTERS CAN CHANGE THEIR OWN PAPER, WHICH IS WHY ; THERE IS A USER ROUTINE FOR THIS. FOR THE HP7221C, ; IT IS UNDER 'MANUAL' CONTROL. THIS UTILITY SENDS 25 ; 'CONTROL-G' OR BELLS TO THE CONSOLE WITH A MESSAGE. PPRMSG: DB 0DH,0AH,'PLEASE CHANGE PLOTTER PAPER THEN HIT ANY KEY$' PPRMS1: DB '.....OK$' BELLS EQU BEEP CHGPR: PUSH AF PUSH BC PUSH DE PUSH HL LD DE,PPRMSG ; PRINT MESSAGE CALL PSTRNG ; CALL PRINT ROUTINE DOBELLS LD E,BELLS LD C,02 ; CPM PRINT CHARACTER FUNCTION CALL BDOS CALL INCHNE ; WAIT FOR ANSWER LD DE,PPRMS1 ; '.....OK' CALL PSTRNG ; " JP BYE ; AND RETURN ; ********* CHANGE PEN ROUTINE ***************** ; HP7221C PLOTTER CAN CHANGE THE PEN PNMSG1: DB 0AH,0DH,'CHANGE PEN' DB 0AH,0DH,' NEW PEN SIZE IS....$' PNMSG2: DB '000$' PNMSG3: DB '0$' PNMSG4: DB '1$' PNMSG5: DB '4$' ; THE PEN SIZE IS SENT IN THE ACCUMULATOR ON CALL, NO ; OTHER INPUTS, NO OUPUTS. CHGPN: PUSH AF PUSH BC PUSH DE PUSH HL PUSH AF LD DE,PNMSG1 ; PRINT MAIN MESSGE CALL PSTRNG POP AF ; GET BACK PEN NUMBER CP 0 JP Z,PEN0 CP 1 JP Z,PEN1 CP 2 JP Z,PEN2 PEN3: LD DE,PNMSG5 DB2: CALL PSTRNG ; PRINT PEN NUMBER PUSH BC PUSH DE PUSH HL PUSH AF LD A,76H CALL OUTCPM ; "V" POP AF PUSH AF ; REFRESH PEN NUMBER ADC A,41H ; SELECT PEN REFERENCE CALL OUTCPM ; PEN CHANGE POP AF POP HL POP DE POP BC JP BYE ; AND RETURN PEN2: LD DE,PNMSG4 JP DB2 ; PRINT NUMBER AND RING CHIMES PEN1: LD DE,PNMSG3 JP DB2 PEN0: LD DE,PNMSG2 JP DB2 ; THE END ; ********** PLOTTER CONTROL ROUTINES ***************** DEL: DB 0 ; DELAY PARAMETER GOXY: DB 0 PENNOW: DB 0 ; THIS ROUTINE IS BASED ON THE ASSUMPTION THAT THE DASOFT SYSTEM ; USES ONLY 45 DEGREE ANGLES, AND AS SUCH MAKES IT MUCH EASIER ; DATA IS STORED IN TBLAD AS XLOW, XHI, YLO , YHI ; WITH BIT 10 (H) AS SIGN, BIT 20(XH) PEN DOWN INTLO: DB 0 ; HIGH BYTE INTERMEDIATE STORE INTHI: DB 0 ; LOW BYTE INTERMEDIATE STORE ; HERE I DEFINE STORAGE FOR THE ABSOLUTE X AND Y COORDINATES ; IN HP7221 UNITS, AS WELL AS THE FIVE BYTES P1-P5 WHICH WILL ; BE SENT TO THE PLOTTER EVENTUALLY. XLOP: DB 0 ; LOW BYTE OF ABSOLUTE X XHIP: DB 0 ; HIGH BYTE YLOP: DB 0 ; LOW BYTE OF ABSOLUTE Y YHIP: DB 0 ; HIGH BYTE P1: DB 0 ; FIRST PLOTTER BYTE P2: DB 0 ; SECOND P3: DB 0 ; THIRD P4: DB 0 ; FOURTH P5: DB 0 ; FIVE MOVE LDA cirk ; test for circle ana a ; jnz move1 ; in this set-up, circles are at one step always lda twoex ; test for 2x ana a cnz move1 ; if flag set call, then rets and falls thru ; to move1 a second time. if not then one move. MOVE1 PUSH AF PUSH BC PUSH DE PUSH HL ; ************************************************************ ; WHEN WE GET TO HERE THE X AND Y COORDINATES ARE STORED ; IN THE TABLE STARTING AT 'TBLAD', AS FOLLOWS: ; TBLAD X LOW BYTE ; TBLAD+1 X HIGH BYTE ; TBLAD+2 Y LOW BYTE ; TBLAD+3 Y HIGH BYTE ; NOTE THAT HERE THE COORDINATES REPRESENT RELATIVE PEN ; MOVEMENTS. IN ORDER TO DRIVE THE PLOTTER ACCURATELY, ; WITH A PRECISE CORRECTION FROM DASOFT UNITS (0.0254 MM) ; TO HP7221 UNITS (0.025 MM) WE NEED TO KEEP TRACK OF THE ; ABSOLUTE COORDINATES. ; ALSO NOTE THAT THE FOUR MSB'S OF THE HIGH BYTE CONTAIN ; SOME KIND OF PLOTTER CONTROL INFORMATION. ; OUR PROBLEM IS THAT THE HP7221 PLOTTER UNIT IS EXACTLY ; 0.025 MM, WHEREAS DASOFT USES ASSUMED PLOTTER UNITS OF ; 0.0254 MM (IE 1 THOU). TO GET AN ACCURATE PLOT WE MUST ; CONVERT THE X AND Y COORDINATES INTO HP7221 UNITS AND ; WE DO THIS WITH THE SUBROUTINE 'CONVT' WHICH CONTAINS ; ITS OWN COMMENTARY. ALL WE NEED TO KNOW HERE IS THAT ; THE INPUT TO 'CONVT' SHOULD BE IN THE REGISTER PAIR ; HL AND THE RESULT IS RETURNED ALSO IN HL. ; THINGS ARE COMPLICATED BECAUSE WE NEED TO FIRST STRIP ; OFF THE PLOTTER CONTROL BITS FROM THE COORDINATES, AND ; THEN REPLACE THEM AFTER THE CONVERSION. ; ********************************************************* ; ************************************ ; FIRST WE WILL DO THE X COORDINATE ; ************************************ LD A,(TBLAD+1) ; GET THE HIGH BYTE OF... ; ..X IN THE ACCUMULATOR AND 0FH ; MASK OUT THE TOP 4 BITS... ; ..TO KEEP ONLY THE X... ; ..COORDINATE BITS LD (INTHI),A ; PUT IT IN INTERMEDIATE STORE LD A,(TBLAD) ; GET THE LOW BYTE OF X... ; ..IN THE ACCUMULATOR LD (INTLO),A ; AND PUT IT IN INTERMEDIATE STORE LD BC,(INTLO) ; GET THE X COORDINATE... ; ..IN REGISTER PAIR BC ; WHEN WE GET TO HERE WE HAVE THE 12 BIT NUMBER FOR THE ; X COORDINATE IN THE REGISTER PAIR BC, WITH THE 4 TOP ; BITS STRIPPED OFF BECAUSE THEY ONLY CONTAIN PLOTTER ; CONTROL INFORMATION. ; NOW WE NEED TO UPDATE THE CURRENT ABSOLUTE X COORDINATE. LD HL,(XLO) ; GET THE CURRENT ABSOULTE... ; ..X COORDINATE IN THE... ; ..BC REGISTER PAIR LD A,(TBLAD+1) ; GET THE BYTE WITH THE... ; ..X SIGN BIT IN IT AND 10H ; KEEP ONLY THE SIGN BIT JP NZ,XNEG ; SUBTRACT IF NEGATIVE ; IF WE GET TO HERE THE RELATIVE X IS POSITIVE AND MUST BE ; ADDED TO THE ABSOLUTE X COORDINATE. ADD HL,BC ; ADD THE MOVE TO THE... ; ..CURRENT ABSOLUTE POSITION JP XSTO ; GO TO STORE IT ; IF WE GET TO HERE THE RELATIVE X IS NEGATIVE AND MUST ; (OBVIOUSLY) BE SUBTRACTED FROM THE ABSOLUTE X COORDINATE. XNEG: OR A ; CLEAR THE CARRY SBC HL,BC ; SUBTRACT THE MOVE FROM... ; ..THE CURRENT ABSOLUTE POSITION XSTO LD (XLO),HL ; AND STORE IT AGAIN ; WHEN WE GET TO HERE WE HAVE THE CURRENT ABSOLUTE X COORDINATE ; IN BOTH THE PAIR OF MEMORY LOCATIONS (XLO/XHI) AND IN THE ; REGISTER PAIR HL. FROM NOW ON WE WILL ONLY BE CONCERNED ; WITH THE NUMBER IN HL. NOW WE HAVE ; TO CONVERT THIS NUMBER FROM DASOFT UNITS TO HP7221 ; UNITS. CALL CONVT ; CONVERT THE 12 BIT... ; ..NUMBER IN REGISTER... ; ..PAIR HL FROM DASOFT... ; ..UNITS TO HP7221 UNITS ; WHEN WE GET TO HERE HL CONTAINS THE 12 BIT X COORDINATE ; PROPERLY SCALED FOR THE HP7221 PLOTTER. ; NOW WE JUST STORE THIS COORDINATE IN THE PLOTTER ABSOLUTE ; COORDINATES LOCATIONS XLOP/XHIP. LD (XLOP),HL ; SAVE THE ABSOLUTE X... ; ..COORDINATE IN PLOTTER UNITS ; ************************************************ ; NOW WE WILL DO THE SAME FOR THE Y COORDINATE ; ************************************************ LD A,(TBLAD+3) ; GET THE HIGH BYTE OF... ; ..Y IN THE ACCUMULATOR AND 0FH ; MASK OUT THE TOP 4 BITS... ; ..TO KEEP ONLY THE Y... ; ..COORDINATE BITS LD (INTHI),A ; PUT IT IN INTERMEDIATE STORE LD A,(TBLAD+2) ; GET THE LOW BYTE OF THE... ; ..Y COORDINATE IN ACCUMULATOR LD (INTLO),A ; AND PUT IT IN INTERMEDIATE STORE LD BC,(INTLO) ; AND GET THE... ; ..Y COORDINATE IN REGISTER L ; WHEN WE GET TO HERE WE HAVE THE 12 BIT NUMBER FOR THE Y ; COORDINATE IN THE REGISTER PAIR BC, WITH THE TOP 4 BITS ; STRIPPED OFF BECAUSE THEY ONLY CONTAIN PLOTTER CONTROL INFORMATION. ; NOW WE NEED TO UPDATE THE CURRENT ABSOLUTE Y COORDINATE. LD HL,(YLO) ; GET THE CURRENT ABSOULTE... ; ..Y COORDINATE IN THE... ; ..BC REGISTER PAIR LD A,(TBLAD+3) ; GET THE BYTE WITH THE... ; ..Y SIGN BIT IN IT AND 10H ; KEEP ONLY THE SIGN BIT JP NZ,YNEG ; SUBTRACT IF NEGATIVE ; IF WE GET TO HERE THE RELATIVE Y IS POSITIVE AND MUST BE ; ADDED TO THE ABSOLUTE Y COORDINATE. ADD HL,BC ; ADD THE MOVE TO THE... ; ..CURRENT ABSOLUTE POSITION JP YSTO ; GO TO STORE IT ; IF WE GET TO HERE THE RELATIVE Y IS NEGATIVE AND MUST ; (OBVIOUSLY) BE SUBTRACTED FROM THE ABSOLUTE Y COORDINATE. YNEG: SBC HL,BC ; SUBTRACT THE MOVE FROM... ; ..THE CURRENT ABSOLUTE POSITION YSTO LD (YLO),HL ; AND STORE IT AGAIN ; NOW OUR ABSOLUTE COORDINATES CAN ONLY BE POSITIVE, SO I ; SET THE SIGN BIT IN THE Y COORDINATE TO ZERO (POSITIVE). LD A,(TBLAD+3) ; GET THE BYTE WITH THE... ; ..SIGN BIT IN IT AND 0EFH ; CLEAR THE SIGN BIT LD (TBLAD+3),A ; AND STORE IT AGAIN ; WHEN WE GET TO HERE WE HAVE THE CURRENT ABSOLUTE Y COORDINATE ; IN BOTH THE PAIR OF MEMORY LOCATIONS (YLO/YHI) AND IN THE ; REGISTER PAIR HL. FROM NOW ON WE WILL ONLY BE CONCERNED ; WITH THE NUMBER IN HL. NOW WE HAVE ; TO CONVERT THIS NUMBER FROM DASOFT UNITS TO HP7221 ; UNITS. CALL CONVT ; CONVERT THE 12 BIT... ; ..NUMBER IN REGISTER... ; ..PAIR HL FROM DASOFT... ; ..UNITS TO HP7221 UNITS ; WHEN WE GET TO HERE HL CONTAINS THE 12 BIT Y COORDINATE ; PROPERLY SCALED FOR THE HP7221 PLOTTER. ; NOW WE SAVE THE ABSOLUTE Y COORDINATE IN PLOTTER UNITS ; IN THE MEMORY LOCATIONS YLOP/YHIP. LD (YLOP),HL ; SAVE THE ABSOLUTE Y... ; ..COORDINATE IN PLOTTER UNITS ; ******************************************************** ; WHEN WE GET TO HERE WE HAVE A RECORD OF THE ABSOLUTE PEN ; POSITION IN DASOFT UNITS STORED IN MEMORY LOCATIONS ; XHI/XLO, YHI/YLO: AND ALSO WE HAVE THE ABSOLUTE PEN ; POSITION IN HP7221 UNITS STORED IN MEMORY LOCATIONS ; XHIP/XLOP, YHIP/YLOP. WE ALSO HAVE LEFT THE PEN UP/DOWN BIT ; AS DASOFT SET IT ORIGINALLY IN TBLAD+1. ; THIS IS THE END OF THE BODGED UP PLOTTER COORDINATE ; SCALING. ; CHRIS F. BORE 2/3/83. ; *********************************************************** ; HERE THE ORIGINAL PROGRAMME CHECKED FOR ZERO VECTORS ; AND RETURNED IMMEDIATELY IF THERE WERE ANY. I AM NOT ; GOING TO DO THIS BECAUSE I CANNOT BE BOTHERED. THE ; ONLY EFFECT IS THAT A ZERO VECTOR IS PLOTTED AND THIS ; IS NOT EXACTLY A DISASTER. ; HERE WE CHECK WHETHER THE PEN SHOULD BE UP OR DOWN: ; NOTE THAT WE ARE NOW BACK TO USING DASOFT'S ORIGINAL ; INFORMATION SENT IN THE TABLE 'TBLAD'. LD A,(TBLAD+1) ; CHECK PEN UP OR DOWN AND 20H LD A,70H ; GET THE ASCII CODE FOR... ; ..THE LETTER 'P' WHICH... ; ..TELLS THE PLOTTER TO... ; ..MOVE TO AN ABSOLUTE... ; ..COORDINATE WITH THE... ; ..PEN UP JR Z,PENCMD LD A,71H ; GET THE ASCII CODE FOR... ; ..THE LETTER 'Q' WHICH... ; ..TELLS THE PLOTTER TO... ; ..MOVE TO AN ABSOLUTE... ; ..COORDINATE WITH THE... ; ..PEN DOWN PENCMD CALL OUTCPM ; SET THE PEN UP OR DOWN ; ************************************************************ ; HERE WE HAVE REALLY MUCKED ABOUT WITH THE ORIGINAL ROUTINE. ; NOTE THAT DASOFT USED RELATIVE PEN MOVEMENTS, BUT IN ORDER ; TO MAKE OUR CORRECTION OF THE UNITS WE HAVE GONE TO A LOT ; OF TROUBLE TO KEEP TRACK OF THE ABSOLUTE COORDINATES. ; WHEN WE GET TO HERE WE HAVE THE ABSOLUTE DASOFT UNITS IN ; XHI/XLO, YHI/YLO: AND THE CORRECTED ABSOLUTE UNITS IN ; XHIP/XLOP, YHIP/YLOP. THESE LAST TWO PAIRS OF MEMORY LOCATIONS ; CONTAIN CORRECTED COORDINATES AS 16 BIT WORDS. ; ************************************************************ ; NOTE HERE THAT THE FORMAT IN WHICH THE COORDINATES MUST BE ; SENT TO THE HP7221 PLOTTER MAY LOOK A BIT STRANGE. WE ARE GOING ; TO SEND ABSOLUTE X AND Y COORDINATES, AND WE HAVE A CHOICE ; OF FORMATS DEPENDING ON HOW BIG OUR NUMBER IS. NOW WE CAN ; HAVE NUMBERS UP TO 16383 AND THIS REQUIRES 5 BYTE FORMAT ; (SEE HP7221 MANUAL FOR DETAILS). SINCE I AM INCLINED TO BE ; LAZY I DO NOT INTEND TO SPEND A LOT OF EFFORT IN FINDING THE ; MOST EFFICIENT FORMAT FOR SMALLER NUMBERS. ALL MY NUMBERS ; WILL THEREFORE BE SENT IN 5 BYTE FORMAT. I KNOW THIS IS ; CLUMSY BUT IF IT WORKS WHO CARES? ; NOW IF WE HAVE THE ABSOLUTE X AND Y COORDINATES AS 16 BIT ; WORDS NUMBERED FROM 0 TO 15 WITH LSB=0, THERE ARE FIVE ; BYTES TO BE SENT TO THE PLOTTER, AND THEY ARE FORMED FROM ; THE BITS OF THE COORDINATES AS FOLLOWS: ; 1) P1 IS BITS 13-10 OF X ; 2) P2 IS BITS 9-4 OF X ; 3) P3 IS BITS 3-0 OF X PLUS BITS 13-12 OF Y ; 4) P4 IS BITS 12-6 OF Y ; 5) P5 IS BITS 5-0 OF Y ; ALL OF THESE ARE ARRANGED SO THAT THEY BUTT UP AGAINST ; THE LSB END OF AN 8 BIT BYTE, AND P1 ALSO HAS BITS 7-5 ; SET AS FOLLOWS: (110). ; FIRST WE FORM P5, WHICH IS BITS 5-0 OF Y. ; WE NOTE THAT ALL OF THESE ARE IN THE LOW BYTE OF Y. LD A,(YLOP) ; GET LOW BYTE OF Y... ; ..WHICH CONTAINS BITS... ; ..5-0. AND 3FH ; KEEP ONLY BITS 5-0 LD (P5),A ; SAVE IT AS P5 ; NOW P4 IS BITS 12-6 OF Y, BUT NOW WE CROSS THE BOUNDARY ; BETWEEN THE TWO BYTES OF Y. WE CAN FORM P4 QUITE EASILY ; BY SHIFTING THE TWO BYTES OF Y LEFT TWICE, SO THAT BITS ; 12-6 END UP ALL IN THE BOTTOM OF THE HIGH BYTE. LD HL,(YLOP) ; GET BOTH BYTES OF Y RL L ; SHIFT L LEFT TO PUT... ; ..BIT 7 IN CARRY RL H ; AND PICK IT UP IN H RL L ; SHIFT L LEFT TO PUT... ; ..BIT 6 IN CARRY RL H ; AND PICK IT UP IN H LD A,H ; GET THE HIGH BYTE IN... ; ..THE ACCUMULATOR AND 3FH ; KEEP ONLY THE 6 LSB'S LD (P4),A ; SAVE IT AS P4 ; NOW P3 IS BITS 3-0 OF X PLUS BITS 13-12 OF Y. ; THIS IS QUITE COMPLICATED BECAUSE WE CROSS THE BOUNDARY ; BETWEEN X AND Y AND ALSO BITS 13-12 OF Y ARE NOT UP ; AGAINST THE TOP EDGE OF THE WORD TO START WITH. WE WILL ; DO IT THE SAME AS FOR P4 BUT WITH A SHIFT OF THE TOP BYTE ; OF Y FIRST TO MAKE IT THE SAME. LD A,(XLOP) ; STUPID Z80 CODE WON'T LOAD H ONLY! LD H,A ; GET THE LOW BYTE OF X... ; ..IN REGISTER H... LD A,(YHIP) ; (SILLY BUGGER) LD L,A ; AND THE HIGH BYTE OF Y... ; ..IN REGISTER L RL L ; SHIFT L LEFT TO ALIGN... RL L ; ..BITS 13-12 AT THE TOP EDGE ; - WHEN WE GET TO HERE WE HAVE A SIMILAR SITUATION TO WHEN ; WE STARTED WITH P4 ABOVE. RL L ; SHIFT L LEFT TO PUT... ; ..BIT 13 IN CARRY RL H ; AND PICK IT UP IN H RL L ; SHIFT L LEFT TO PUT... ; ..BIT 12 IN CARRY RL H ; AND PICK IT UP IN H LD A,H ; GET IT IN ACCUMULATOR AND 3FH ; KEEP ONLY 6 LSB'S LD (P3),A ; SAVE IT AS P3 ; NOW P2 IS BITS 9-4 OF X. AGAIN WE CROSS THE BOUNDARY ; BETWEEN THE HIGH AND LOW BYTES, AS IN THE CASE OF P4. LD HL,(XLOP) ; GET X IN HL RL L ; SHIFT L LEFT TO PUT... ; ..BIT 7 IN CARRY RL H ; AND PICK IT UP IN H RL L ; BIT 6 RL H RL L ; BIT 5 RL H RL L ; BIT 4 RL H LD A,H ; GET IT IN ACCUMULATOR AND 3FH ; KEEP ONLY 6 LSB'S LD (P2),A ; AND SAVE IT AS P2 ; NOW P1 IS BITS 13-10 OF X, BUT WITH FLAG BITS AT THE TOP. ; NOTE THAT AGAIN, AS WITH P1, WE ARE WITHIN A SINGLE BYTE. LD A,(XHIP) ; GET THE HIGH BYTE OF X... ; ..IN THE ACCUMULATOR RRA ; SHIFT IT RIGHT TO BRING... RRA ; ..BITS 13-10 TO THE BOTTOM EDGE AND 0FH ; KEEP ONLY 4 LSB'S ; - NOTE HOW I HAVE ONLY KEPT 4 BITS HERE, BECAUSE I AM GOING ; TO ADD IN THE FLAG BITS NOW IN THE TOP 4 BITS. OR 60H ; ADD FLAG BITS (110) LD (P1),A ; SAVE IT AS P1 ; WHEN WE GET TO HERE WE HAVE ALREADY SET THE PEN UP/DOWN ; MODE, AND WE HAVE ALL 5 BYTES P1-P5 READY TO SEND FOR THE ; COORDINATES. ; NOTE ONE MORE FUNNY THING. FOR EACH BYTE AFTER THE FIRST ; (P1) WHICH IS SENT TO THE HP7221, THE BYTE VALUE MUST BE ; BETWEEN 32-95. BUT BIT 5 CONTAINS DATA, SO TO KEEP THE ; BYTE VALUE IN RANGE WE HAVE TO PLAY AROUND WITH THE VALUES ; OF BYTE 5 & 6. IN FACT WE MUST ALWAYS MAKE BYTE 6 THE LOGICAL ; COMPLEMENT OF BYTE 5. THIS IS WHAT ALL THE FUNNY BUSINESS ; DOES IN THE FOLLOWING CODES, WHICH SEND THE FIVE BYTES TO HP7221. LD A,(P1) ; GET FIRST BYTE CALL OUTCPM ; AND SEND IT LD A,(P2) ; GET SECOND BYTE BIT 5,A ; TEST BIT 5 JP NZ,J1 ; LEAVE BIT 6 ZERO IF... ; ..BIT 5 IS A 1 SET 6,A ; BUT SET BIT 6 IF... ; ..BIT 5 IS A 0 J1: CALL OUTCPM ; AND SEND IT LD A,(P3) ; GET THIRD BYTE BIT 5,A ; TEST BIT 5 JP NZ,J2 ; LEAVE BIT 6 ZERO IF... ; ..BIT 5 IS A 1 SET 6,A ; BUT SET BIT 6 IF... ; ..BIT 5 IS A 0 J2: CALL OUTCPM ; AND SEND IT LD A,(P4) ; GET FOURTH BYTE BIT 5,A ; TEST BIT 5 JP NZ,J3 ; LEAVE BIT 6 ZERO IF... ; ..BIT 5 IS A 1 SET 6,A ; BUT SET BIT 6 IF... ; ..BIT 5 IS A 0 J3: CALL OUTCPM ; AND SEND IT LD A,(P5) ; GET FIFTH BYTE BIT 5,A ; TEST BIT 5 JP NZ,J4 ; LEAVE BIT 6 ZERO IF... ; ..BIT 5 IS A 1 SET 6,A ; BUT SET BIT 6 IF... ; ..BIT 5 IS A 0 J4: CALL OUTCPM ; AND SEND IT ; ************************************************************ ; THIS ENDS THE BODGED UP TRANSMISSION OF ABSOLUTE X AND Y ; COORDINATES TO THE HP7221 PLOTTER. ; CHRIS F. BORE 3/3/83. ; ************************************************************ ; ***** PLOT THE VECTOR ***** LD A,7DH ; OUTPUT TERMINATOR CALL OUTCPM CALL DELAY2 JP BYE ; AND RETURN ; ******ROUTINE TO OUTPUT A CHARACTER ON LIST DEVICE VIA CPM****** OUTCPM: PUSH AF PUSH BC PUSH DE PUSH HL LD E,A ; TRANSFER CHARACTER LD C,05 ; OUTPUT ON LIST DEVICE FLAG CALL BDOS ; GO! BYE: POP HL POP DE POP BC POP AF RET ; ; *******DELAYS DELAY1 PUSH AF PUSH BC PUSH DE PUSH HL ; NOW CHECK WHETHER FAST OR SLOW, THEN GET THE VALUE FOR ; DELAY BETWEEN STEPS LD A,(SLOW) OR A JP Z,NOTSLOW LD HL,(SDELAY) ; GET SLOW DELAY JP DL1LP NOTSLOW LD HL,(FDELAY) DL1LP DEC HL LD A,H OR L JP NZ,DL1LP JP BYE ; UNSAVE REGISTERS & RETURN DELAY2 PUSH AF PUSH BC PUSH DE PUSH HL LD A,XDEL2 LD B,A DELX2 LD A,B OR A ; CHECK FOR END OF LOOP JP Z,ENDDEL PUSH BC LD E,20H ; SPACE CHARACTER LD C,OUTFUNC CALL DDLAY POP BC DEC B JP DELX2 ENDDEL JP BYE ; UNSAVE REGISTERS & RETURN ; ****************************************************** ; HERE WE NEED TO COMPENSATE FOR THE FACT THAT DASOFT ; WORKS IN INCHES BUT THE HP7221 PLOTS IN METRIC UNITS. ; DASOFT EXPECTS 1 PLOTTER UNIT TO BE 5 THOU (.005"), ; BUT IT IS IN FACT 5*0.025 MM = 4.9212 THOU (0.0049"). ; IN OTHER WORDS WE NEED TO MULTIPLY DASOFT'S NUMBERS ; BY A FACTOR 1.016 TO GIVE THE CORRECT DISTANCES IN ; IMPERIAL UNITS. ; WE CAN MULTIPLY BY 1.016 BY MANIPULATING OUR NUMBERS ; AS FOLLOWS, NOTICING FIRST THAT .016 = 262/2^14 WITH ; AN ERROR OF ONLY 1 IN 100000. THIS IS THE APPROXIMATE ; FACTOR WHICH I HAVE USED IN ALL THAT FOLLOWS. ; THE PROCEDURE GOES LIKE THIS: ; 1) MULTIPLY (X) BY 256 WITH A SHIFT LEFT OF 8 BITS ; 2) ADD 6*(X) TO MAKE A TOTAL OF 262*(X) ; 3) DIVIDE BY 2^14 WITH A SHIFT RIGHT OF 14 BITS ; 4) ADD THIS RESULT [0.016*(X)] TO (X) ; OBVIOUSLY THINGS ARE COMPLICATED BY THE FACT THAT ; THE MULTIPLICATIONS GIVE RESULTS WHICH CAN BE BIGGER ; THAN 16 BITS. IN FACT IF WE ALLOW UP TO 12 BITS ; FOR THE DASOFT COORDINATES WE NEED 24 BITS (3 BYTES) ; TO ACCOMODATE OUR CALCULATION. SINCE THE NUMBERS ; ARE UNSIGNED THIS IS NOT AS DIFFICULT AS IT COULD BE. ; IN PARTICULAR, I HAVE USED A TRICK OF MAKING A ; SHIFT OF 8 BITS LEFT BY ADDING AN 'IMAGINARY' BYTE ; AFTER A 16 BIT REGISTER PAIR (AND CONVERSELY BY ; REMOVING THE 'IMAGINARY' BYTE FOR A SHIFT RIGHT OF ; 8 BITS). THIS 'IMAGINARY' BYTE IS NOT REALLY USED, ; BUT SUPPOSING ITS EXISTENCE HELPS TO CLARIFY WHAT ; IS HAPPENING. ; ******************************************************** ; THE NUMBER ENTERS AS UP TO 12 BITS IN REGISTERS HL. STORE: DB 0,0 ; TEMPORARY STORAGE CONVT PUSH AF ; SAVE ALL REGISTERS... PUSH BC ; ..EXCEPT HL WHICH IS... PUSH DE ; ..GOING TO BE CHANGED LD (STORE),HL ; SAVE X ; HERE WE FIRST MULTIPLY X BY 6: LD BC,(STORE) ; COPY X INTO BC ADD HL,BC ; AND ADD X... ADD HL,BC ; ..TWICE TO MAKE HL=3*X ADD HL,HL ; DOUBLE HL TO MAKE HL=6*X ; NOW WE DO THE CLEVER BIT WITH THE SHIFTS. ; IN ORDER TO MULTIPLY X BY 256 WE NEED A SHIFT LEFT OF ; 8 BITS. I DO THIS BY SUPPOSING AN 'INVISIBLE' NULL ; BYTE TO BE ADDED ON THE END OF THE BC REGISTER PAIR. ; THE NEW BC(0) REGISTER TRIPLET IS A 24 BIT WORD AND ; I NEED TO ADD THE CONTENTS OF HL TO THIS TRIPLET. ; BUT OF COURSE I WILL NOT BE INTERESTED IN THE LOW ; BYTE OF HL, BECAUSE THIS ONLY AFFECTS THE IMAGINARY ; NULL BYTE. THUS I CAN ADD THE HIGH BYTE ONLY TO THE ; REGISTER PAIR BC - GOOD, EH? LD L,H ; GET HIGH BYTE OF HL... ; ..IN LOW BYTE OF HL LD H,0 ; CLEAR HIGH BYTE OF HL ADD HL,BC ; ADD (256*X) IN BC TO... ; ..(6*X) IN HL ; WHEN WE GET HERE THE REGISTER TRIPLET HL(0) CONTAINS ; A 24 BIT NUMBER WITH THE VALUE OF (262*X). NOW I DO ; ANOTHER CLEVER SHIFT, THIS TIME TO THE RIGHT, OF 8 ; BITS. I DO THIS JUST BY LOPPING OFF THE 'INVISIBLE' ; NULL BYTE ON THE END OF HL, LEAVING ME WITH THE HL ; REGISTER PAIR CONTAINING A NUMBER (262*X/2^8). ; UNFORTUNATELY THIS IS NOT ENOUGH THIS TIME SO I AM ; OBLIGED TO MAKE A FURTHER SHIFT OF 6 TO THE RIGHT. ; BUT THIS IS NOT TOO DIFFICULT BECAUSE I AM NOW IN ; ONLY A 16 BIT WORD, NOT A 24 BIT ONE. LD B,6 ; REGISTER B WILL COUNT... ; ..THE SHIFTS DONE SHIFT: OR A ; THIS CLEARS THE CARRY SRL H ; SHIFT THE HIGH BYTE... ; ..OF HL RIGHT AND... ; ..PUT THE LSB IN CARRY RR L ; SHIFT THE LOW BYTE... ; ..OF HL RIGHT AND... ; ..RECOVER THE CARRY... ; ..INTO THE MSB DEC B ; COUNT THE SHIFTS JP NZ,SHIFT ; CONTINUE IF NOT FINISHED ; WHEN WE GET TO HERE WE HAVE THE NUMBER (0.016*X) IN THE ; REGISTER PAIR HL AS A 16 BIT NUMBER - ALL I NEED IS TO ; ADD X TO MAKE (1.016*X). LD BC,(STORE) ; RECOVER X ADD HL,BC ; HL=(1.016*X) ; NOW WE HAVE ONLY TO RETRIEVE ALL THE REGISTERS (EXCEPT ; FOR THE HL REGISTER PAIR OF COURSE!) POP DE ; RETRIEVE ALL REGISTERS... POP BC ; ..EXCEPT HL OF COURSE! POP AF RET ; RETURN ; THIS IS THE END OF THE BODGED UP MULTIPLICATION ; (THANK GOD!) ; CHRIS F. BORE 1/3/83. ; ********************************************************** ; ******* PLOTTER INITIALIZE ROUTINE *************** INIT: PUSH AF PUSH BC PUSH DE PUSH HL LD HL,INIMSG ; POINTS TO INITIALZATION STRING LD B,7 SLOOP LD A,(HL) CALL OUTCPM INC HL ; NEXT BYTE DJNZ SLOOP CALL DELAY2 JP BYE ; AND RETURN INIMSG: DB 1BH,2EH,28H,7EH,5FH,76H,'B' ; ESC . ( ~ _ AND PEN 2 NEG: DEFS 1 AXIS: DEFS 1 TEMP: DEFS 2 BNUM: DEFS 1 ; *************************************************************** ; THIS IS THE ERROR HANDLING ROUTINE ERR: PUSH AF PUSH BC PUSH DE PUSH HL LD DE,ERRMSG CALL PSTRNG JP DOBELLS ERRMSG DB 0AH,0DH,' OUT OF RANGE$' DDLAY PUSH BC LD B,1 LD C,20 LP1 DEC C JR NZ,LP1 DJNZ LP1 POP BC RET org 1bf0h twoex db 00 ; 2.6 flag cirk db 00 ; also END END