.TITLE CHARS - CHARACTER ROUTINES ; ; ; .MCALL CALL,RETURN,RECALL,ENTER,LEAVE .MCALL EXCHR,ERROR ; ; ; .SBTTL >CHINIT ; ; CHINIT - INITIALISE FOR CHARACTER GENERATION ; ; SHOULD BE CALLED WHENEVER KEY TABLES ARE INVALIDATED ; ; ENTRY: CALL CHINIT ; ; EXIT: ALL REGISTERS ARE PRESERVED ; CHINIT::MOV #100000,CHKEY RETURN .SBTTL >CHSET - INITIALISE CHARACTER TABLES ; ; CHSET - INITIALISE CHARACTER TABLES ; ; CHSET IS CALLED BEFORE ANY CHARACTER PROCESSING. ; IT GENEREATES THE VARIOUS TABLES AND CONSTANTS ; REQUIRED BY CHGEN. (IF THE PREVIOUS CALL TO CHSET ; HAD THE SAME PARAMETERS AS THE CURRENT ONE, NO GENERATION ; IS PERFORMED. ; ; ENTRY: MOV #TABLE,R0 ; CALL CHSET ; ; EXIT: ALL REGISTERS ARE RESTORED ; ; FORMAT: TABLE HAS EIGHT FULLWORD ENTRIES, ; THE FIRST OF WHICH IS A KEY (SEE BELOW). ; THE NEXT THREE ARE ANGLES, IN UNITS OF ; 1/2**15 OF A CIRCLE. (THEY MUST BE ; POSITIVE.) EG. 90 DEGREES IS OCTAL 20000. ; THE THREE ANGLES ARE, IN ORDER: ; ANNOTATION - THE ANGLE OF THE CHARACTER STRING WITH ; RESPECT TO A HORIZONTAL LINE ; ORIENTATION - THE ANLGE OF INDIVIDUAL CHARACTERS WITH ; RESPECT TO THE CHRACTER STRING ; SLANT - THE ANGLE OF THE 'VERTICAL' EDGE OF A ; CHARACTER WITH RESPECT TO A LINE ; PERPENDICULAR TO THE BOTTOM OF THE CHARACTER ; ; THE REST ARE DISTANCES IN PDF UNITS. IN ORDER: ; WIDTH - THE WIDTH OF A CHARACTER ; HEIGHT - THE HEIGHT OF A CHARACTER ; HSEP - THE HORIZONTAL SPACING BETWEEN CONSECUTIVE ; CHARACTERS ; VSEP - THE VERTICAL SPACING BETWEEN VERTICALLY ; ADJACENT CHARACTERS. ; ; THE TABLE MUST START WITH A KEY WORD - ; IF THE VALUE OF THE KEYWORD IS POSITIVE, ONLY ; IT IS CHECKED FOR PARAMETER SIMILARITY. ; IF IT IS NEGATIVE, BOTH IT AND THE FULL TABLE ; ARE CHECKED. (NORMALLY ITS VALUE WILL BE -1, ; IF IT IS NEGATIVE. ; THE SAVED KEY IS INITIALIZED TO -32768 IN ; CHINIT TO INDICATE TABLE UNRELIABILITY ; AT STARTUP.) ; ; ; FIRST CHECK IF WE HAVE TO DO ANYTHING ; CHSET:: CMP (R0),CHKEY ;KEY FIRST BNE DFKEY ;DIFFERENT TST (R0) ;IF KEY POSITIVE, ALL CHECKING BPL 1$ ;IS FINISHED CMP 2(R0),CHANN BNE DFANN CMP 4(R0),CHORNT BNE DFORNT CMP 6(R0),CHSLNT BNE DFSLNT CMP 10(R0),CHWD BNE DFWD CMP 12(R0),CHHT BNE DFHT CMP 14(R0),CHHS BNE DFHS CMP 16(R0),CHVS BNE DFVS 1$: RETURN ;MADE IT THROUGH ALL THE CHECKS ; ; DFKEY: MOV (R0),CHKEY DFANN: MOV 2(R0),CHANN DFORNT: MOV 4(R0),CHORNT DFSLNT: MOV 6(R0),CHSLNT DFWD: MOV 10(R0),CHWD DFHT: MOV 12(R0),CHHT DFHS: MOV 14(R0),CHHS DFVS: MOV 16(R0),CHVS .SBTTL > COMPUTE SINES AND COSINES ; ; ENTER R0,R1,R2,R3,R4,R5 ;NEED TO SAVE REGISTERS NOW ; ; COMPUTE SINES AND COS'S ; .MACRO SC X ;COMPUTE SINE AND COS MOV R0,SCP1 ;SET UP NUMERATOR FOR TRIG RTNS CALL ISIN ;COMPUTE SINE MOV R0,SIN'X ;STASH IT AWAY CALL ICOS ;AND COSINE MOV R0,COS'X MOV SCP1,R0 ;RESTORE R0 .ENDM ; ; MOV #SCPARM,R5 ;POINT AT PARAMETER LIST MOV CHANN,R0 SC A ;ANNOTATION MOV CHORNT,R0 SC O ;ORIENTATION ADD CHANN,R0 BVC 1$ BIC #100000,R0 1$: SC AO ;ANN+ORNT ADD CHSLNT,R0 BVC 2$ ;NO OVERFLOW BIC #100000,R0 ;OVERFLOW, JUST WRAP AROUND 2$: SC AOS ;ANN+ORNT+SLANT .SBTTL > COMPUTE SPACING PARAMETERS ; ; COMPUTE COMMON SUB-EXPRESSION ; .ENABL LSB MOV COSO,R4 ;COS(ORNT) MUL CHHS,R4 ;HSEP*COS(ORNT) MOV SINO,R2 ;SIN(ORNT) MUL CHVS,R2 ;VSEP*SIN(ORNT) ADD R3,R5 ;HSEP*COS(ORNT)+VSEP*SIN(ORNT) ADC R4 ;.. ADD R2,R4 ;.. MOV R4,R2 ;AND SAVE ANOTHER COPY MOV R5,R3 ;.. ; ; COMPUTE DELTA X AND DELTA Y ; MOV R5,R0 ;THIS TAKES COS(ANN), A SINGLE PRECISION MUL COSA,R4 ;NUMBER WITH BINARY POINT AFTER BIT 16 MUL COSA,R0 ;AND MULTIPLIES IT BY T (IN R4/R5), A BPL 1$ ADD COSA,R5 ADC R4 DEC R4 1$: ADD R0,R5 ;DOUBLE PRECISION NUMBER ALSO WITH ADC R4 ;BINARY POINT AFTER BIT 16, PRODUCING ROL R1 ;A TRIPLE PRECISION RESULT WITH BINARY ROL R5 ;POINT AFTER BIT 31. ITH THEN SHIFTS ROL R4 ;THIS RESULT LEFT TWO BITS, PUTTING THE ROL R1 ;BINARY POINT AFTER BIT 33, I.E. ROL R5 ;BETWEEN WORD 2 AND WORD 1. THIS ROL R4 ;IS ROUNDED TO A DOUBLE PRECISION ROL R1 ;NUMBER WITH THE BINARY POINT BETWEEN ADC R5 ;WORD 1 AND WORD 0 ADC R4 MOV R5,CHDELX ;FRACTION PART MOV R4,CHDELX+2 ;INTEGER PART MOV R3,R0 ;THIS TAKES SIN(ANN), A SINGLE PRECISION MUL SINA,R2 ;NUMBER WITH BINARY POINT AFTER BIT 16 MUL SINA,R0 ;AND MULTIPLIES IT BY T (IN R2/R3), A BPL 2$ ADD SINA,R3 ADC R2 DEC R2 2$: ADD R0,R3 ;DOUBLE PRECISION NUMBER ALSO WITH ADC R2 ;BINARY POINT AFTER BIT 16, PRODUCING ROL R0 ;A TRIPLE PRECISION RESULT WITH BINARY ROL R3 ;POINT AFTER BIT 31. ITH THEN SHIFTS ROL R2 ;THIS RESULT LEFT TWO BITS, PUTTING THE ROL R0 ;BINARY POINT AFTER BIT 33, I.E. ROL R3 ;BETWEEN WORD 2 AND WORD 1. THIS ROL R2 ;IS ROUNDED TO A DOUBLE PRECISION ROL R0 ;NUMBER WITH THE BINARY POINT BETWEEN ADC R3 ;WORD 1 AND WORD 0 ADC R2 MOV R3,CHDELY ;FRACTION PART MOV R2,CHDELY+2 ;INTEGER PART .DSABL LSB .SBTTL > COMPUTE GRID CO-ORDINATES ; ; COMPUTE X AND Y OFFSETS ; .MACRO MULT X,Y,Z,N MOV Y,R4 .IF NB N NEG R4 .ENDC MUL X,R4 ;NOW SHIFT SO BINARY POINT IS BETWEEN WORDS CLC ROL R5 ROL R4 MOV R5,Z ;AND SAVE MOV R4,Z+2 .ENDM ; MULT CHWD,COSAO,X1 MULT CHHT,SINAO,Y1 MULT CHWD,SINAOS,X2,NEG MULT CHHT,COSAOS,Y2 ; ; ; FILL IN GRID VECTORS ; .MACRO FILL VEC,?L1,?L2 CLR V'VEC ;FIRST CO-ORDINATE ALWAYS 0 MOV #2,R0 ;START WITH ELEMENT 1 MOV #16,R1 ;NUMBER OF ELEMENTS EXCEPT FIRST L1: MOV VEC+2,R4 ;HIGH ORDER WORD OF OFFSET MUL R0,R4 MOV VEC,R2 ;LOW ORDER WORD MUL R0,R2 BPL L2 ADD R0,R5 ADC R4 DEC R4 L2: ADD R2,R5 ;PRODUCING TRIPLE WORD RESULT ADC R4 ROL R3 ;ROUND OFF ADC R5 ;TO DOUBLE WORD ADC R4 ADD #14,R5 ;THEN ROUNDING BIAS FOR DIVIDE ADC R4 DIV #30,R4 ;ACTUALLY DIVIDE BY 12., BUT MULTIPLIED MOV R4,V'VEC(R0) ;BY EXTRA TWO. ADD #2,R0 ;(SINCE R0 IS AN INDEX) SOB R1,L1 ;LOOP FOR REST OF VECTOR .ENDM ; FILL X1 FILL X2 FILL Y1 FILL Y2 .SBTTL > COMPUTE CHARACTER BOX ; ; COMPUTE MAXIMUM AND MINIMUM X AND Y GRID CO-ORDINATES ; .ENABL LSB MOV VX1,R0 MOV VX1+<2*16>,R1 CMP R0,R1 BLOS 1$ EXCHR R0,R1 1$: MOV VX2,R2 MOV VX2+<2*16>,R3 CMP R2,R3 BLOS 2$ EXCHR R2,R3 2$: ADD R2,R0 MOV R0,CHXMIN ADD R3,R1 MOV R1,CHXMAX MOV VY1,R0 MOV VY1+<2*16>,R1 CMP R0,R1 BLOS 3$ EXCHR R0,R1 3$: MOV VY2,R2 MOV VY2+<2*16>,R3 CMP R2,R3 BLOS 4$ EXCHR R2,R3 4$: ADD R2,R0 MOV R0,CHYMIN ADD R3,R1 MOV R1,CHYMAX LEAVE RETURN .DSABL LSB .SBTTL > VARIABLES ; ; ; PARAMETER LIST FOR ISIN AND ICOS ; SCPARM: .WORD 2 .WORD SCP1 .WORD SCP2 ; SCP1: .BLKW 1 SCP2: .WORD 20000 ; ; ; SINES AND COSINES ; SINA: .BLKW 1 COSA: .BLKW 1 SINO: .BLKW 1 COSO: .BLKW 1 SINAO: .BLKW 1 COSAO: .BLKW 1 SINAOS: .BLKW 1 COSAOS: .BLKW 1 ; ; ; GRID SIZES ; X1: .BLKW 2 X2: .BLKW 2 Y1: .BLKW 2 Y2: .BLKW 2 ; .SBTTL >CHGEN ; ; CHGEN - GENERATE A CHARACTER ; ; ENTRY: MOV X,R0 ; MOV Y,R1 ; MOV CHAR,R2 ; MOV #DATA,R3 ;DATA AREA PASSED ON TO USER PROGGS ; MOV #PT0,R4 ; MOV #PT1,R5 ;PLOT BLOCKS ; CALL CHGEN ; ; EXIT: ALL REGISTERS RESTORED ; ; EXTERNAL REFERENCES: THIS ROUTINE USES LOCATIONS ; PXLAT,PDTEST,PDMOVE,PDDRAW SET UP BY ; PDPARS ; CHGEN:: ENTER R2,R3 MOV R0,XBASE MOV R1,YBASE ;CHARACTER BASE CO-ORDINATES ; ; ASK TEST SUBROUTINE WHETHER WE SHOULD BOTHER WITH THIS ; CHARACTER ; MOV CHXMAX,R0 ;MAXIMUM X CO-ORD ADD XBASE,R0 ;RELOCATED MOV CHYMAX,R1 ;AND MAXIMUM Y CO-ORD ADD YBASE,R1 ;RELOCATED CALL @PDXLAT ;SET IT UP IN A POINT BLOCK MOV CHXMIN,R0 ;MIMUM X CO-ORD ADD XBASE,R0 ;RELOCATED MOV CHYMIN,R1 ;AND MINIMUM Y CO-ORD ADD YBASE,R1 ;RELOCATED EXCHR R4,R5 CALL @PDXLAT ;IN A POINT BLOCK CALL @PDTEST ;TEST IT BCS CGRET ;NO GO ; ; PROCESS CHARACTER ; BIC #-200,R2 ;TURN OFF HIGH BITS BIT #100,R2 ;IS IT CHARACTER OF SOME FORM? BEQ 1$ ;NO BIC #140,R2 ;YES, FLUSH REST OF ZONE BITS 1$: ASL R2 ;AND CONVERT IT TO AN INDEX MOV PDCTAB(R2),INDEX ;GET VECTOR ADDRESS CLR R2 ;MARK AS STRAIGHT LINE MOVE: MOV #CMOVE,MOVDRW ;SET UP AS MOVE NEXT: CLR R3 ;PREPARE FOR BISB BISB @INDEX,R3 ;GET NODE INC INDEX ;STEP POINTER MOV R3,R0 ;SPLIT NODE ASH #-4,R0 ;X CO-ORD BEQ CONTRL DRAW: MOV R3,R1 BIC #-20,R1 ;Y CO-ORD BEQ CHERR ;MUST BE > 0 ASL R0 ;MAKE CO-ORDS ASL R1 ;..INTO INDICES MOV VX1-2(R0),-(SP) ADD VX2-2(R1),(SP) MOV VY1-2(R0),-(SP) ADD VY2-2(R1),(SP) MOV (SP)+,R1 ;Y GRID CO-ORD ADD YBASE,R1 ;RELOCATE MOV (SP)+,R0 ;X GRID CO-ORD ADD XBASE,R0 ;RELOCATE EXCHR R4,R5 CALL @PDXLAT ;STUFF IN POINT BLOCK CALL @MOVDRW ;MOVE OR DRAW CLR R3 ;GET NEXT NODE BR NEXT ; CONTRL: JMP CONTAB(R3) ;CONTROL CONTAB: BR MOVE BR TYPEM1 BR TYPE0 BR TYPE1 CGRET: LEAVE MOV XBASE,R0 MOV YBASE,R1 RETURN ; CHERR: ERROR ; CMOVE: CALL @PDMOVE MOV #CDRAW,MOVDRW RETURN ; CDRAW: MOV 2(SP),R3 ;GET BACK R3 WE ENTERED WITH JMP @PDDRAW ; TYPEM1: MOV #-1,R2 BR NEXT ; TYPE0: CLR R2 BR NEXT ; TYPE1: MOV #1,R2 BR NEXT ; .SBTTL > VARIABLES ; XBASE: .BLKW 1 ;X CO-ORDINATE OF CHARACTER BASE YBASE: .BLKW 1 ;Y CO-ORDINATE OF CHARACTER BASE ; MOVDRW: .BLKW 1 ;ADDRESS OF EITHER CMOVE OR CDRAW ; INDEX: .BLKW 1 ;POINTER TO CHARACTER DEFINITION VECTOR .SBTTL >CHVEC ; ; CHVEC - GENERATE A VECTOR OF CHARACTERS ; ; ENTRY: MOV X,R0 ; MOV Y,R1 ; MOV #PT0,R4 ; MOV #PT1,R5 ; ; CALL CHVEC ; ; CHVEC IS A CO-ROUTINE AND WILL RECALL ; ITS CALLER TO GET EACH NEW CHARACTER ; WHICH SHOULD BE PLACED IN R2. IT WILL CONTINUE ; RECALLING FOREVER, CALLER SHOULD EXIT WHEN ; THERE ARE NO MORE CHARACTERS ; ; ; ; FIRST, OFFSET BY STARTING POSITION OF CHARACTER ; WITHING CHARACTER GRID ; CHVEC:: SUB VX1+4,R0 SUB VX2+4,R0 SUB VY1+4,R1 SUB VY2+4,R1 ; ; INITIALIZE FRACTION PART OF BASE ADDRESS ; CLR XFRAC CLR YFRAC ; ; PLOT CHARACTERS ; VECLUP: RECALL ;GET A CHARACTER CALL CHGEN ;GENERATE IT ADD CHDELX,XFRAC ;UPDATE POSITION (DOUBLE WORD) ADC R0 ADD CHDELX+2,R0 ADD CHDELY,YFRAC ADC R1 ADD CHDELY+2,R1 BR VECLUP ;AND CONTINUE .BLKW 1 ;POINTER TO CHARACTER DEFINITION VECTOR .SBTTL > VARIABLES ; ; XFRAC: .BLKW 1 ;LOW ORDER (FRACTION0 WORD OF POSITION YFRAC: .BLKW 1 ;SAME FOR Y .SBTTL >CHARACTER TABLES ; ; KEY ; CHKEY: .BLKW 1 ; ; ANGLES ; CHANN: .BLKW 1 ;ANNOTATION ANGLE CHORNT: .BLKW 1 ;ORIENTATION ANGLE CHSLNT: .BLKW 1 ;SLANT ANGLE ; ; SIZES ; CHWD: .BLKW 1 ;WIDTH CHHT: .BLKW 1 ;HEIGHT CHHS: .BLKW 1 ;HORIZONTAL SEPARATION CHVS: .BLKW 1 ;VERTICAL SEPARATION ; ; GRID VECTORS ; VX1: .BLKW 17 VX2: .BLKW 17 VY1: .BLKW 17 VY2: .BLKW 17 ; ; ; CHARACTER BOX ; CHXMIN: .BLKW 1 CHXMAX: .BLKW 1 CHYMIN: .BLKW 1 CHYMAX: .BLKW 1 ; ; ; SPACING PARAMETERS ; CHDELX: .BLKW 2 CHDELY: .BLKW 2 ;; ; .END