.TITLE GDGIGI - GIGI DRIVER .IDENT /VERS20/ .SBTTL HOW TO CUSTOMIZE THIS PACKAGE .ENABLE LC ; This file contains the GIGI driver for DIGLIB. ; DIGLIB is a "device independant" graphics library. ; THIS PACKAGE IS CONDITIONAL ASSEMBLED. THE CONDITIONALS ; AND THEIR RESPECTIVE MEANINGS ARE LISTED BELOW. ; ;1) SET THE SYMBOL "OS" TO: ; 1 ==> RT11 ; 2 ==> TSX ; 3 ==> RSX11M (IMPLIES F4P/F77) .IF NDF OS OS = 3 .ENDC .SBTTL DEFINATIONS, ECT. .IF NE OS-3 .MCALL .PRINT, .TTYIN JSW = 44 SPCTT = 50000 ;ENABLE LOWER CASE AND TT SPECIAL .IFF .MCALL QIOW$, DIR$ .ENDC ;NE OS-3 .GLOBL GDAID, GDGAID F0 = %0 ;FLOATING PT. REG. 0 FOR RSX11M BUFSIZ = 72. CR = 15 ;CARRAIGE RETURN LF = 12 ;LINE FEED FF = 14 ;FORM-FEED ESC = 33 ;ESCAPE ;ERROR MACRO DEFINATION .MACRO ERROR TEXT JSR R0,ERROR1 .ASCIZ @TEXT@ .EVEN .ENDM ERROR .PSECT GDGIGI ;WE ARE RELOCATABLE .SBTTL ENTRY POINT GDGIGI:: TST (R5)+ ;SKIP ARG COUNT MOV @(R5)+,R0 ;GET FUNCTION TO PERFORM BLE 1$ ;ITS A BADDY ASL R0 ;MAKE WORD OFFSET ADD #DSPTBL-2,R0 ;R0 ==> ADDRESS OF PROCESSING ROUTINE CMP R0,#TBLEND ;SEE IF UNSUPPORTED FUNCTION BGE 1$ ;YES JMP @(R0)+ ;NO, DISPATCH TO ROUTINE 1$: ERROR DSPTBL: .WORD INIT, BGNPLT, MOVE, DRAW, ENDPLT, RLSDEV .WORD GETCHR,SETCOL,GIN TBLEND: .SBTTL INIT AND BGNPLT ; ;INITIALIZE - FUNCTION 1 ; INIT: .IF EQ OS-2 ;IF BLOODY TSX, THEN MOV #ON,R0 ;TELL TSX TO LEAVE OUR TTY I/O ALONE EMT 375 .IFTF MOV 2(R5),R4 ;R4 ==> YA(1) CLR (R4)+ ;YA(1) = 0.0 CLR (R4) ; MEANS NO ERRORS ON INIT. JSR PC,DOINIT JSR R4,INSEND ;INIT. GIGI .ASCIZ "S(I0N0)W(I7RP1)""\""PrSM0" .EVEN RTS PC .IFT ON: .BYTE 1,120 .ENDC ;EQ OS-2 ; ;BGNPLT - FUNCTION 2 ; BGNPLT: JSR PC,DOINIT ;KILL ANY LEFT OVER GRAPHICS JSR R4,INSERT ;REQUEST A GRAPHICS ERASE .ASCIZ "W(I7)S(EI0)W(I7R)" .EVEN RTS PC .SBTTL MOVE AND DRAW ; ;MOVE - FUNCTON 3 ; MOVE: JSR R4,INSERT ;DO A GIGI "POSITION" .ASCIZ "P" .EVEN BR DOXY ; ;DRAW - FUNCTION 4 ; DRAW: JSR R4,INSERT ;DO A GIGI "VECTOR" .ASCIZ "V" .EVEN DOXY: JSR PC,MAKINT ;CONVERT SCREEN CM COORD. TO GDU DOXYNS: MOV BINPTR,R4 ;GET A POINTER INTO THE BUFFER MOVB #'[,(R4)+ ;INSERT THE BRACKET FOR SYNTAX MOV NEWX,R1 ;GET X JSR PC,BINASC ;CONVERT TO ASCII AND INSERT MOVB #',,(R4)+ ;INSERT A COMMA FOR SYNTAX MOV NEWY,R0 ;GET Y ASL R0 ;TIMES 2 FOR GIGI MOV #480.,R1 ;INVERT Y COORDINATE SUB R0,R1 ;Y(GIGI) = 480 - Y(REAL) JSR PC,BINASC ;MAKE ASCII AND INSERT IT MOVB #'],(R4)+ ;INSERT RIGHT BRACKET FOR SYNTAX ADD #3,BUFCNT ;ADD IN SYMTAX CHARACTERS MOV R4,BINPTR ;RESTORE BUFFER POINTER CMP BUFCNT,#BUFSIZ-14. ;SEE IF ENOUGH ROOM LEFT FOR NEXT TIME BLO 1$ ;YES, JUST EXIT JSR PC,PLTMT1 ;NOT ENOUGH ROOM FOR NEXT TIME, SO EMPTY 1$: RTS PC ;ALL DONE NOW BINASC: CLR R2 ;ZERO CHARACTER COUNT 1$: CLR R0 ;ZERO HIGH PART FOR DIVIDE DIV #10.,R0 ;GET NEXT LEAST SIG. DIGIT ADD #60,R1 ;CONVERT REMAINDER TO ASCII MOVB R1,-(SP) ;SAVE IT ON STACK INC R2 ;COUNT DIGITS MOV R0,R1 ;PLACE QUOTIENT FOR NEXT DIVIDE BNE 1$ ;GO DO NEXT DIGIT IF ANYTHING THERE ADD R2,BUFCNT ;ACCOUNT FOR CHARS WE WILL INSERT 2$: MOVB (SP)+,(R4)+ ;INSERT A DIGIT INTO THE BUFFER SOB R2,2$ ;INSERT ALL THE DIGITS RTS PC .SBTTL ENDPLT AND RLSDEV ; ;END OF PLOTTING (FLUSH BUFFER) - FUNCTION 5 ; ENDPLT: CMP BUFCNT,#3 ;SEE IF ANYTHING TO FORCE OUT BLOS 9$ ;NOPE JSR PC,PLTMT1 ;FORCE OUT LAST BUFFER MOV #BUFST,BINPTR ;ZERO BUFFER CLR BUFCNT JSR R4,INSEND ;SEND AN ERASE LINE COMMAND TO GIGI .ASCIZ "[2K" .EVEN 9$: RTS PC ; ;RELEASE DEVICE - FUNCTION 6 ; RLSDEV: JSR PC,PLTMTY ;FORCE OUT LAST IN BUFFER CLR BUFCNT ;ZERO BUFFER MOV #BUFST,BINPTR JSR R4,INSEND ;RELEASE GIGI TO JUMP SCROLL .ASCIZ "PrSM1" .EVEN .IF EQ OS-2 MOV #OFF,R0 EMT 375 .IFTF RTS PC .IFT OFF: .BYTE 0,120 .ENDC ;EQ OS-2 .SBTTL GETCHR - GET CHARACTERISTICS ; ;GET DEVICE CHARACTERISTICS - FUNCTION 7 ; GETCHR: MOV (R5)+,R4 ;R4 ==> OUTPUT ARRAY MOV #CHRTBL,R0 ;R0 ==> OUR CHARACTERISTICS MOV #CWORDS,R1 ;R1 = NUMBER OF WORDS TO MOVE 1$: MOV (R0)+,(R4)+ ;MOVE CHARACTERISTICS SOB R1,1$ RTS PC CHRTBL: .FLT2 8.0 .FLT2 25.5667 ;X AXIS LENGTH IN CM. .FLT2 15.9333 ;Y AXIS LENGTH IN CM. XGUPCM: .FLT2 30.0 ;X AXIS RESOLUTION IN ; GRAPHICS UNITS PER CM. YGUPCM: .FLT2 15.0 ;Y AXIS RESOLUTION IN ; GRAPHICS UNITS PER CM. .FLT2 7.0 ;7 FOREGROUND COLORS .FLT2 133.0 ;RASTER, BACKGROUND WRITE, GIN AVAILABLE .FLT2 1.0 ;NEEDS EVERY LINE FILLED CWORDS = <.-CHRTBL>/2 .SBTTL SELECT COLOR ; ;SELECT COLOR - FUNCTION 8 ; SETCOL: JSR PC,GETINT ;GET COLOR NUMBER CMP R1,#7 ;SEE IF LEGAL COLOR NUMBER BHI COLERR ;YES MOVB CMAP(R1),COLNUM ;MAP FOREGROUND COLOR NUMBER TO GIGI ;COLOR NUMBER JSR R4,INSEND ;INSERT CHANGE COLOR COMMAND .ASCII "W(I" COLNUM: .BYTE 0 .ASCIZ ")" .EVEN RTS PC CMAP: .BYTE '0,'7,'2,'4,'1,'6,'3,'5 .EVEN COLERR: ERROR .SBTTL GIN COMMAND COMMON ; ;GRAPHICS INPUT WITH PICK CHARACTER - FUNCTION 8 ; GIN: JSR R4,INSERT ;MOVE TO LAST CURSOR POSITION .ASCIZ "P" .EVEN MOV GINX,NEWX ;SET X=GINX MOV GINY,NEWY ;SET Y TO GINY JSR PC,DOXYNS ;SEND TO GIGI JSR PC,PLTMTY ;EMPTY THE CURRENT BUFFER JSR PC,GETLIN ;GET THE RESPONSE MOV (R5)+,R4 ;R4 ==> ARRAY FOR CHAR,X,Y JSR PC,GINCHR ;GET GIN CHARACTER STRUCK .IF EQ OS-3 ;RSX11M FOR FPU SETF SETI LDCIF R0,F0 ;FLOAT R0 INTO F0 STF F0,(R4)+ ;PLACE CHARACTER FIRST IN ARRAY .IFF ;NO FPU JSR PC,FLOAT ;FLOAT THE NUMBER MOV R0,(R4)+ ;PLACE IT FIRST IN THE ARRAY MOV R1,(R4)+ .ENDC ;EQ OS-3 MOV R4,UNXADD ;SHOW WHERE TO STORE X IN CM. ADD #4,R4 ;FIGURE OUT WHERE Y IN CM. GOES MOV R4,UNYADD ;SHOW WHERE TO STORE Y IN CM. JSR PC,UNPACK ;GET IX MOV R0,GINX ;SAVE IX JSR PC,UNPACK ;GET IY MOV #480.,R1 ;CONSTANT FOR CONVERTING Y(GIGI) TO Y(REAL) SUB R0,R1 ;Y(REAL) = 480 - Y(GIGI) ASR R1 ;DOWN TO GIGI'S REAL RESOLUTION MOV R1,GINY ;SAVE IY MOV #UNSCR5,R5 ;PREPARE TO UNSCALE IX,IY TO X,Y JSR PC,GDGAID ;CALL FTN TO UNSCALE JSR PC,DOINIT ;INIT THE GRAPHICS BUFFER RTS PC ;AND DONE UNSCR5: .WORD 6 .WORD GINX,GINY,XGUPCM,YGUPCM UNXADD: .WORD 0 UNYADD: .WORD 0 .SBTTL GIGI GIN SPECIFICS .IF NE OS-3 ;RT11 AND TSX GETLIN: JSR R4,INSEND ;SEND THE GIN COMMAND .ASCIZ "R(P(I))" .EVEN MOV #BUFST,R1 ;INPUT TO OUR OUTPUT BUFFER MOV @#JSW,-(SP) ;SAVE JSW BIS #SPCTT,@#JSW ;INHIBIT ECHO BY RT-11 1$: .TTYIN ;GET A CHARACTER CMPB R0,#LF ;SEE IF LF? BEQ 2$ ;YES, GOT RESPONSE NOW MOVB R0,(R1)+ ;NO, PUT CHARACTER IN BUFFER BR 1$ ;GO GET NEXT CHARACTER 2$: CLRB (R1)+ ;SHOW END OF INPUT MOV (SP)+,@#JSW ;RESTORE JSW MOV #BUFST,R3 ;R3 ==> GIN CHARACTER RTS PC .IFF ;RSX11M GETLIN: MOV #BUFST,QDPB+Q.IOPL ;SET BUFFER START ADDRESS MOV #12.,QDPB+Q.IOPL+2 ;SET EXPECTED NUMBER OF BYTES MOV #IO.RPR!TF.RNE,QDPB+Q.IOFN ;READ AFTER PROMPT ;WITH NO ECHO MOV #PROMPT,QDPB+Q.IOPL+6 ;SET PROMPT ADDRESS MOV #PRSIZE,QDPB+Q.IOPL+10 ;SET PROMPT SIZE MOV #'+,QDPB+Q.IOPL+12 ;VFC = NORMAL MOV #5,QDPB+Q.IOLU ;MAKE SURE LUN=5 DIR$ #QDPB ;EXECUTE THE READ AFTER PROMPT BCS RDERR ;VERY BAD CMPB IOSB,#IS.SUC ;MAKE SURE READ WORKED BNE RDERR ;WE FAILED, SORRY. MOV #BUFST,R3 ;R3 ==> GIN CHARACTER RTS PC ;AH, THE SWEET SMELL OF SUCCESS RDERR: ERROR PROMPT: .ASCII "PpR(P(I))""\" PRSIZE = . - PROMPT .EVEN .ENDC ;NE OS-3 GINCHR: MOVB (R3)+,R0 ;GET GIN CHARACTER INC R3 ;PASS "[" BIC #177600,R0 ;MAKE 7 BIT ASCII CMPB R0,#'[ ;SEE IF NO PICK CHARACTER FROM GIGI BNE 1$ ;NOPE MOV #CR,R0 ;YES, SO SET TO CR WHICH GIGI REMOVED DEC R3 ;BACKUP TO X 1$: RTS PC ;DONE UNPACK: CLR R0 ;ZERO VALUE 1$: MOVB (R3)+,R2 ;GET NEXT DIGIT SUB #60,R2 ;MAKE NUMBER FROM ASCII BLO 9$ ;NOT ASCII, MUST BE DONE CMP R2,#9. ;SEE IF OTHER TERMINATOR BHI 9$ ;YES, ALL DONE ASL R0 ;OLD X2 MOV R0,-(SP) ;SAVE X2 ASL R0 ;X4 ASL R0 ;X8 ADD (SP)+,R0 ;X10 ADD R2,R0 ;ADD IN NEW DIGIT BR 1$ ;GO GET MORE DIGITS IF ANY 9$: RTS PC ;ALL DONE .SBTTL MAKINT SUBROUTINE MAKINT: MOV (R5)+,XADD ;PASS X ARG ON MOV (R5)+,YADD ;PASS Y ARG ON MOV #SCLR5,R5 ;PREPARE TO CALL A FTN CALC. ROUTINE JSR PC,GDAID RTS PC SCLR5: .WORD 6 XADD: .WORD 0 YADD: .WORD 0 .WORD XGUPCM .WORD YGUPCM IXADD: .WORD NEWX IYADD: .WORD NEWY GETINT: MOV (R5)+,R4 ;POINT TO FLOATING VALUE GETIN2: .IF EQ OS-3 ;FPU SETF SETI LDF (R4)+,F0 ;GET FLOATING VALUE STCFI F0,R1 ;PLACE 16 LSB IN R1 RTS PC ;THATS IT .IFF ;NO FPU MOV (R4)+,R0 ;GET HIGH PART MOV (R4)+,R1 ;GET LOW PART MOV R0,R3 ;COPY EXPONENT MOV R0,-(SP) ;SAVE SIGN ALSO BIC #177600,R0 ;GET MANTISSA (ALMOST) BIS #200,R0 ;RESTORE HIDDEN BIT TO MANTISSA ASL R3 ;ALIGN EXPON. IN HIGH BYTE SWAB R3 ;PUT IN LOW BYTE BIC #177400,R3 ;GET ONLY EXPON. SUB #200,R3 ;TAKE OUT EXCESS 200 FROM EXPON. BLE 2$ ;IF <0 THEN NUMBER <1 SUB #24.,R3 ;COMPUTE RIGHT SHIFT COUNT CMP R3,#8. ;SEE IF > 2**32 -1 BGE 2$ ;IF THAT BIG, USE ZERO ASHC R3,R0 ;SHIFT RIGHT PROPER NUMBER OF BITS TST (SP)+ ;SEE IF MINUS BPL 1$ COM R0 ;NEG. D.P. INTEGER NEG R1 ADC R0 ;PROPAGE CARRY 1$: RTS PC ;AND DONE 2$: CLR R1 ;RETURN 0 CLR R0 TST (SP)+ ;FORGET STUFF ON STACK RTS PC FLOAT: MOV R0,R1 ;PREPARE TO FLOAT BEQ 9$ ;ALL DONE SIZE ITS ZERO CLR R0 ;ZERO HIGH PART MOV R2,-(SP) ;SAVE R2 MOV #46000,R2 ;R2=EXPONENT OF 24 BIT NUMBER 1$: SUB #200,R2 ;WHACK DOWN EXPONENT AS WE NORMALIZE ASL R1 ;SHIFT LOW LEFT ROLB R0 ;SHIFT HIGH LEFT BPL 1$ ;NOPE, KEEP ON SHIFTING BIC #177600,R0 ;KILL MSB BIS R2,R0 ;MAKE FLOATING PT. EXP + MANTISSA MOV (SP)+,R2 ;RESTORE R2 9$: RTS PC ;DONE .ENDC ;EQ OS-3 .SBTTL UTILITY ROUTINES ; ;CALL PLTMTY ; ;THIS ROUTINE EMPTIES THE GRAPHICS BUFFER PLTMTY: CMP BUFCNT,#3 ;MAKE SURE SOMETHING TO SEND BLOS EXIT PLTMT1: MOV BINPTR,R1 ;SET INPUT POINTER IN R1 MOVB #ESC,(R1)+ ;INSERT "EXIT REGIS" SEQUENCE MOVB #'\,(R1)+ ADD #2,BUFCNT ;ACCOUNT FOR 2 EXTRA CHARS. .IF NE OS-3 ;RT AND TSX CLRB (R1)+ ;ZERO BYTE TERMINATES WITH CR/LF .PRINT #BUFST ;DO THE I/O NOW .IFF ;RSX11M JSR PC,DOQIO ;SEND TO THE TERMINAL .ENDC ;NE OS-3 DOINIT: MOV #BUFST,R1 ;GET A POINTER TO THE BUFFER MOVB #ESC,(R1)+ ;INSERT GIGI GRAPHICS START SEQUENCE MOVB #'P,(R1)+ MOVB #'p,(R1)+ MOV R1,BINPTR ;RESTORE TO START OF BUFFER MOV #3,BUFCNT ;SET BUFCNT TO 3 FOR

EXIT: RTS PC ;AND DONE .IF NE OS-3 ;RT AND TSX ERROR1: .PRINT ;MAKE .PRINT CALL TRAP 300+63. ;GIVE FORTRAN ERROR MESSAGE .IFF ;RSX11M ERROR1: CLR -(SP) ;2ND WORK OF MESSAGE BLOCK MOV R0,-(SP) ;SET ADDRESS OF TEXT MOV SP,R0 ;R0 ==> MSG BLOCK CLR R1 ;SIGNAL NOT AN ERROR YET JSR PC,$ERRLG ;TYPE OUR MESSAGE CMP (SP)+,(SP)+ ;CLEAN UP THE STACK TRAP +341 ;GIVE NON-FTN4PLUS ERROR MESSAGE .ENDC ;NE OS-3 INSERT: CLR INFLG ;SHOW INSERT BR PUT INSEND: MOV R4,INFLG ;SHOW INSEND PUT: MOV R1,-(SP) ;SAVE R1 MOV BINPTR,R1 ;GET POINTER TO BUFFER 1$: MOVB (R4)+,(R1)+ ;INSERT A CHAR BEQ 2$ ;BRANCH ON END OF STRING INC BUFCNT ;ADD UP CHARS CMP BUFCNT,#BUFSIZ-1 ;CHECK FOR TOO MANY BMI 1$ ;NOPE ERROR 2$: DEC R1 ;BACK UP TO REAL CHAR MOV R1,BINPTR ;RESTORE POINTER MOV (SP)+,R1 ;RESTORE R1 TST INFLG ;SEE IF WE SHOULD SEND ALSO BEQ EVNOUT ;NOPE JSR PC,PLTMT1 ;SEND BUFFER EVNOUT: INC R4 ;MAKE R4 EVEN BIC #1,R4 RTS R4 .IF EQ OS-3 .SBTTL QIO DRIVER DOQIO: MOV #BUFST,QDPB+Q.IOPL ;SET BUFFER ADDRESS MOV BUFCNT,QDPB+Q.IOPL+2 ;SET BYTE COUNT MOV #'+,QDPB+Q.IOPL+4 ;SET TO NORMAL VFC MOV #IO.WAL,QDPB+Q.IOFN ;SET TO WRITE PASS ALL MOV #5,QDPB+Q.IOLU ;SET LUN=5 (TI:) DIR$ #QDPB ;EXECUTE THE QIO BCS WRTERR ;OOPS TSTB IOSB ;MAKE SURE TRANSFER WORKED BMI WRTERR ;OOPS RTS PC ;WHEW, WE DID IT UNDER RSX WRTERR: ERROR QDPB: QIOW$ IO.WAL,0,24.,0,IOSB,0, IOSB: .BLKW 2 .ENDC ;EQ OS-3 .SBTTL VARIABLES AND BUFFER NEWX: .WORD 0 NEWY: .WORD 0 GINX: .WORD 768./2 GINY: .WORD 240./2 INFLG: .WORD 0 BINPTR: .WORD BUFST ;MUST BE INITIALIZED TO "BUFST" BUFCNT: .WORD 0 BUFST: .BLKB BUFSIZ .END