; POLISH.MAC --- POLISH INTERPRETER SOURCE FILE ; POLISH.MAC --- POLISH INTERPRETER SOURCE FILE ; ; POLISH INTERPRETER ; ------ ----------- ; ; ; ROBERT L. SHARP ; ; 7073 JASPER DRIVE ; MIDDLETOWN, MARYLAND 21769 ; ; ; COPYRIGHT (C) 1980 BY ROBERT L. SHARP ; ; ;********************************************************** ; ; ; A POLISH INTERPRETER HAS BEEN DEVELOPED TO RUN ON EITHER ; AN LSI-11 OR PDP-11 WITH LIMITED MEMORY. THE INTERPRETER ; EXCEPTS COMMANDS WHICH PROVIDE MANIPULATION OF INTEGERS, ; FLOATING POINT NUMBERS AND INTEGER COLUMNS OF DATA. ; COMMANDS WITHIN THE INTERPRETER ALLOW IF, FOR, CASE, AND ; ASSIGNMENT STATEMENTS. COMMAND SUBROUTINES MAY ALSO BE ; BUILT AND USED RECURSIVELY. THE MAIN EMPHASIS OF THE ; INTERPRETER IS THE PROVISION FOR PERFORMING OPERATIONS ON ; COLUMNS OF DATA INTERACTIVELY. SUCH OPERATIONS AS ; STANDARD ARITHMETIC AND SMOOTHING ARE PROVIDED. THE ; INTERPRETER MAKES EXTENSIVE USE OF THE STACK FOR MOST ; OPERATIONS. ; ; ; INTRODUCTION ; ------------ ; ; THE ORIGINAL OBJECTIVE OF THE POLISH INTERPRETER WAS TO ; DESIGN A SIMPLE COMMAND LANGUAGE WHICH OPTIMIZED THE USE OF ; MEMORY. IN SEARCH FOR A CONVENIENT WAY TO STORE THE COMMAND ; IN MEMORY , IT WAS DECIDED TO HAVE A LIST OF ADDRESSES ; WHICH POINTED TO SUBROUTINES TO BE EXECUTED. THIS IS ; SIMILAR TO THE CONCEPT USED BY THE FLOATING POINT MATH ; PACKAGE (FPMP) IN THE POLISH MODE. BY ALSO INCLUDING THE ; ADDRESS OF VARIABLES IN THE ADDRESS LIST, VARIABLES COULD ; BE USED BY A COMMAND FROM EITHER THE STACK OR THE ADDRESS ; LIST. ; ; A PROGRAMMING LANGUAGE DEVELOPED AFTER THE ADDITION OF ; CONTROL STRUCTURES AND ARITHMETIC OPERATIONS. A PROG ; OPERATOR WAS INTRODUCED TO ALLOW THE SAVING OF ADDRESS ; LISTS IN MEMORY FOR LATER RECALL. THIS PROVIDED A SUBROUTINE ; FACITLITY. ONE OF THE GOALS OF THE LANGUAGE WAS TO PROVIDE ; EASY MANIPULATION OF COLUMNS OF DATA, ALONG WITH INTEGERS ; AND FLOATING POINT NUMBERS. ; ; ; ; ; SUMMARY OF COMMANDS: ; ------- -- --------- ; ;********************************************************* ; ; CHANGE HISTORY ; ------ ------- ; ; 11/03/79 - ADDED COMMENTS TO CODE. ; ; 11/05/79 - ADD DEFAULT TERMINATOR FOR VARIABLE LENGTH ; OPERANDS, SUCH AS PRINT & LIST COMMANDS. ; MAY BE USED ONLY ON INTERACTIVE CMD LINES. ; ; 11/12/79 - ADDED INDIRECT FILE FOR INPUT. ; ; 11/17/79 - ADDED PRINT FILE FOR OUTPUT ; ; ; ;******************************************************** ; ; ; PROBLEMS AND CHANGES ; -------- --- ------- ; ; - LABEL TR4: NEED TO ADD CONVERSION FOR FLOATING POINT. ; ; - PRINT FLT-VAR DOES NOT WORK. ; ; - DUMP LEFT DOES NOT WORK. ; ; ;******************************************************** ; ; POLISH INTERPERTER FOR THE PDP-11 COMPUTER ; ; ; ;********************************************************* ; RT11 = 1 ; ; .IFDF RT11 .MCALL ..V2..,.PRINT,.TTYIN,.TTYOUT,.EXIT .MCALL .CSIGEN .MCALL .LOOKUP,.READW,.WRITW,.CLOSE,.SETTOP ..V2.. .ENDC ; .GLOBL $IR,$RI,ROWS .GLOBL INAREA,BLOCK,ERROR,RDERR,READ1,GETCOL .GLOBL ONE,TWO,THREE,FOUR,FIVE ; LABEL CONSTANRS ; ; ; ; SYMBOLIC CONSTANTS SECTION ; ERRWD = 52 ;RT-11 ERROR WORD RMON = 54 ;POINTER TO START OF RESIDENT USR = 266 ;OFFSET FROM RESIDENT TO PTR ;WHERE USR WILL START MATHLENGTH = 64.*2 ;BYTES OF MATH STACK MAXMEM = 60.*1024.-2 K1WORDS = 2*1024. K4WORDS = 8.*1024. BUFFER = 3*K4WORDS ; DYNAMIC MEMORY BUFFER SIZE INCHN = 11 ;DX1: INPUT CHANNEL INDCHN = 3 ;INDIRECT FILE CHANNEL PRTCHN = 0 ;PRINT FILE CHANNEL BLANK = 40 ; BLANK CHARACTER CR = 15 ; CARRIAGE RETURN LF = 12 ; LINE FEED ITEMADD = 2 LABELA = 4 LABELB = 6 COLTYPE = 1 INTTYPE = 2 FLTTYPE = 3 CHRTYPE = 4 CMDTYPE = 5 POLTYPE = 6 DATTYPE = 7 BINTYPE = 8. RETURN = 134 ; JMP @(R4)+ INSTRUCTION R0 = %0 ;REGISTER DEFINITIONS R1 = %1 R2 = %2 R3 = %3 R4 = %4 R5 = %5 SP = %6 PC = %7 ; ; ; COMPUCOLOR II COLOR CODES ; BLACK = 16. RED = 17. GREEN = 18. YELLOW = 19. BLUE = 20. MAGENTA = 21. CYAN = 22. WHITE = 23. ; ; ; RT-11 TERMINAL ADDRESSES ; RCSR = 177560 ;RECEIVER STATUS REGISTER RBUF = 177562 ;RECEIVER BUFFER XCSR = 177564 ;TRANSMITTER STATUS REGISTER XBUF = 177566 ;TRANSMITTER BUFFER ; ;----------> LOCAL MACRO DEFINITIONS <-------------------- ; ; ; THE CMD MACRO IS USED TO DEFINE COMMAND DESCRIPTOR BLOCKS. ; .MACRO CMD .NAME,.CALL .WORD .+10 .WORD .CALL .ASCII ".NAME" .ENDM ; ; THE VAR MACRO IS USED TO DEFINE INTEGER VARIABLE BLOCKS. ; .MACRO VAR .NAME,.VAR,.VALUE .WORD .+14 .WORD .VAR .ASCII ".NAME" .WORD INTTYPE .VAR: .WORD .VALUE .ENDM ; ; ; ; ; MACROS TO PROVIDE DIRECT CONTROL OF THE CONSOLE ; WHICH WILL BYPASS THE RT-11 TT: HANDLER. ; ; $TTYOPEN WILL READY DIRECT CONSOLE I/O. ; .MACRO $TTYOPEN TSTB @#XCSR ;IS OUTPUT IN PROGRESS BPL .-4 ;YES, THEN WAIT CLR @#XCSR ;TURN OFF THE INTERRUPT .ENDM ; ; $TTYOUT WILL OUTPUT THE BYTE IN R0 TO THE CONSOLE. ; .MACRO $TTYOUT .CHAR .IIF NB <.CHAR>, MOVB .CHAR,%0 TSTB @#XCSR ;IS OUTPUT IN PROGRESS BPL .-4 ;YES, THEN WAIT MOVB %0,@#XBUF ;OUTPUT BYTE .ENDM ; ; $TTYCLOSE WILL RE-ENABLE RT-11 INTERUPTS FOR TT: ; .MACRO $TTYCLOSE TSTB @#XCSR ;IS OUTPUT IN PROGRESS BPL .-4 ;YES, THEN WAIT MOV #100,@#XCSR ;ENABLE INTERRUPT .ENDM ; ; $DELAY WILL RESULT IN AN EXECUTION DELAY USING A LOOP. ; .MACRO $DELAY MOV TTYWAIT,R0 SOB R0,. .ENDM ; ; ;******************************************************** ; ; COMMON LINK AREA TO ALLOW AN ADDITIONAL DICTIONARY ; AND POLISH ROUTINES TO BE LINKED WITH THIS MODULE. ; .CSECT COMMON ; NEWMEM: .WORD ENDPOL ;ADDRESS OF DYNAMIC STORAGE ADDMEM: .WORD ENDPOL ;ADDRESS OF ADD ON DICTIONARY ; .CSECT POLISH ; ;********************************************************** ; ; MISC. DATA STORAGE AREA ; BEGCOL: .WORD ENDPOL ;START OF COLUMN STORAGE ENDMEM: .WORD ENDPOL ; END OF ALLOCATED AREA ; (NULL POINTER) MEMTOP: .WORD ENDPOL+BUFFER ; END OF DYNAMIC MEM BUF AREA LOWBUF: .WORD ENDPOL+BUFFER ;LOW ADDRESS OF BUF POOL BUFS: .WORD 0 ;NUMBER OF BUFFERS ALLOCATED ;RADIN: .WORD 0,0,0 ;RAD50 CONVERSION AREA PRTBUF: .WORD 0 ;PRINT BUFFER ADDRESS INDBUF: .WORD 0 ;INDIRECT BUFFER ADDRESS PRTON: .WORD 0 ;PRINT FILE ON FLAG PRTCHARS: .WORD 0 ;COUNT CHARS IN PRINT BUFFER PRTPTR: .WORD 0 ;POINTS TO NEXT CHAR IN PRT BUF PRTCNT: .WORD 0 ;COUNTS PRINT BLOCKS DEXT: .RAD50 "CMD" ;DEFAULT EXTENSION AREA .RAD50 "LST" ;DEFAULT FOR PRINT FILE .WORD 0,0 INDFLAG:.WORD 0 ;INDIRECT FLAG INDCNT: .WORD 0 ;INDIRECT FILE BLOCK COUNT INDBYTES:.WORD 0 ;INDIRECT FILE BYTE COUNT INDPOINTER:.WORD 0 ;INDIRECT FILE POINTER TTYWAIT:.WORD 100000 ;WAIT PERIOD FOR TTYOUT PLTWAIT:.WORD 5000 ;WAIT PERIOD FOR PLOTS IN: .RAD50 "DX1" ;DATA IS STORED ON FLOPPY 1 .WORD 0,0,0 RANGESCALE: .FLT2 1.0 ;RANGE FOR PLOTS MINSCALE: .WORD 0 MAXX: .WORD 127. MAXY: .WORD 127. CLINE: .BLKB 136. ;COMMAND LINE PARMBLK:.BLKB 40. ;PARAMETER BLOCK FOR CLINE RLEVEL: .WORD 0 ; TEMP: .BLKW 2 ; TEMPORARY STORAGE AREA INAREA: .BLKW 10 ;RT-11 EMT AREA ; ; STANDARD MESSAGES FOR CONSOLE AND ERROR MESSAGES: ; ; MSG1: .BYTE CYAN ;CONSOLE PROMPT MSG .ASCII /CMD>/ .BYTE YELLOW,0 ; CNVERR: .BYTE RED .ASCII "CONVERSION ERROR" .BYTE GREEN,0 ; ; ERR1: .BYTE RED .ASCII "ROWS MUST BE GREATER THEN ZERO" .BYTE GREEN,0 ; OUTOFMEM:.BYTE RED .ASCII /OUT OF MEMORY/ ;ERROR MESSAGE .BYTE GREEN,0 ; .IFDF RT11 OPNERR: .BYTE RED .ASCII /OPEN ERROR/ .BYTE GREEN,0 ; RDERR: .BYTE RED .ASCII /READ ERROR/ .BYTE GREEN,0 .ENDC .EVEN ; ; THE MATH STACK IS USED TO HOLD ALL POLISH MATHEMATICAL ; CALCULATIONS FOR BOTH INTEGER AND FLOATING POINT OPERATIONS ; THE STACK IS POINTED TO BY THE R5 REGISTER, WHICH SHOULD ; BE SAVED IN ANY SUBROUTINE THAT WOULD LIKE TO USE R5 FOR ; SOMETHING ELSE. ; MATHSTACK: .BLKB MATHLENGTH ; ; ; ; ;********************************************************** ; ; DICTIONARY OF COMMANDS AND VARIABLE NAMES STORAGE AREA ; DICTIONARY: CMD PUSH,PUSH CMD CPUS,CPUSH CMD ,POP CMD CADD,CADD CMD CSUB,CSUB CMD CMOV,CMOV CMD CMUL,CMUL CMD CDIV,CDIV CMD CDOW,CDOWN CMD MOVE,MOVE CMD FPUS,FPUSH CMD FPOP,FPOP CMD ,SET CMD PROG,PROG CMD ,END CMD DECL,DECLARE CMD DIFF,DIFF CMD ,FOR CMD NEXT,NEXT CMD RESE,SRESET CMD ,GEN CMD ,INT CMD ,FLT CMD FREE,FREE CMD <++ >,ADDFL CMD <-- >,SUBFL CMD <** >,MULFL CMD ,DIVFL CMD <+ >,ADDI CMD <- >,SUBI CMD <* >,MULI CMD ,DIVI CMD PRIN,PRINT CMD DUMP,DUMP CMD ,PUT CMD ,GET CMD INTE,INTEGER CMD FLOA,FLOAT CMD ,IF CMD CASE,CASE CMD LIST,LIST CMD HALT,HALTCPU CMD EXIT,EXIT CMD FDEC,FDECLARE CMD CDEC,CDECLARE CMD TTYO,TTYOUT CMD DELA,DELAY CMD SCAL,SCALE CMD LINE,LINE CMD READ,READ ; LENGTH = .-DICTIONARY ; ; ; PREDEFINED VARIABLE STORAGE AREA ; ---------- -------- ------- ---- ; ; VARIABLES: .WORD .+10 .WORD 0 .ASCII /$ / .WORD .+14 .WORD .+10 .ASCII /GT / BINTYPE BGT .+4 .WORD .+14 .WORD .+10 .ASCII /LT / BINTYPE BLT .+4 .WORD .+14 .WORD .+10 .ASCII /EQ / BINTYPE BEQ .+4 .WORD .+14 .WORD .+10 .ASCII /NE / BINTYPE BNE .+4 .WORD .+14 .WORD .+10 .ASCII /GE / BINTYPE BGE .+4 .WORD .+14 .WORD .+10 .ASCII /LE / BINTYPE BLE .+4 MEMDUMP: VAR LEFT,LEFT,0 VAR COLS,COLS,0 VAR ROWS,ROWS,0 VAR FIRS,FIRSTROW,0 VAR LAST,LASTROW,0 VAR BLOC,BLOCK,0 VAR ,PRT ;PRT FLAG FOR TERM OUTPUT VAR ZERO,ZERO,0 VAR ,ONE,1 VAR ,TWO,2 VAR THRE,THREE,3 VAR FOUR,FOUR,4 MEMLINK:ENDPOL FIVE .ASCII /FIVE/ INTTYPE FIVE: .WORD 5 LENGTH = .-VARIABLES LENGTH = .-DICTIONARY ; ;************************************************************* ; ; CONTROL PROGRAM SECTION ; ; ; COMMAND DECODING ; ------- -------- ; ; THE POLISH INTERPRETER IS AN INTERACTIVE PROGRAMMING LANGUAGE ; THAT ALLOWS A USER TO ENTER OPERATOR AND OPERANDS THAT MAY BE ; DIRECTLY EXECUTED. THE MAIN CONTROL LOOP OF THE INTERPRETER ; IS IMPLEMENTED AS FOLLOWS: ; ; ; MAIN: MOV #1000,SP ;SET UP THE STACK JSR PC,SETUP MAIN1: JSR PC,GETLINE ;READ CONTROL LINE MOV #PARMBLK,R4 JSR PC,TRANSLATE ;TRANSLATE CLINE TO PARMBLK MOV #PARMBLK,R4 RETURN ;EXECUTE POLISH CODE LENGTH = .-MAIN ; ; THE NORMAL INTERPRETATION LOOP STARTS BY READING A LINE OF ; INPUT FROM THE CONSOLE TERMINAL WITH THE GETLINE ROUTINE. ; THE INPUT LINE IS THEN TRANSLATED INTO A LIST OF ADDRESSES ; BY THE TRANSLATE ROUTINE. THIS LIST OF ADDRESSES IS STORED ; IN PARMBLK WHICH IS POINTED TO BY R4. THE JMP @(R4)+ ; INSTRUCTION (SAME AS RETURN INST.) STARTS EXECUTION AT ; THE FIRST ADDRESS IN THE LIST. EXECUTION CONTINUES FROM ; ONE ADDRESS IN THE LIST TO THE NEXT BY HAVING EACH ; ROUTINE TO RETURN WITH THE JMP @(R4)+ OR RETURN INSTRUCTION ; THE LAST ADDRESS IN THE LIST OF ADDRESSES IS MAIN1, WHICH ; RETURNS CONTROL TO THE INTERPRETATION LOOP. THE FUNCTION OF ; THE TRANSLATE ROUTINE IS TO SEARCH A LIST OF NAMES FOR A ; MATCH AND TO PUT THE CORRESPONDING ADDRESS IN THE PARMBLK. ; ; ; ; ; ;----------------> ERROR HANDLER <------------------------ ; ; THE ERROR HANDLER IS JUMPED TO WHEN AN ABORT CONDITION ; OCCURS. UPON ENTRY R0 HAS THE ADDRESS OF AN ERROR ; MESSAGE TO PRINT ON THE CONSOLE. CONTROL IS RETURNED ; TO THE BEGINNING OF POLISH WHICH RESETS ALL OF STORAGE. ; ; ERROR: JSR PC,TERMOUT BR MAIN ; ;------------> TRANSLATE COMMAND LINE <------------------- ; ; THE TRANSLATE SUBROUTINE IS USED TO SCAN THE COMMAND ; LINE (CLINE) AND TO LOOK FOR NAMES (COMMANDS AND ; VARIABLES) WHICH ARE FOUND IN THE DICTIONARY BY THE ; GETVAR SUBROUTINE. IF IT IS AN INTEGER NUMBER THEN IT ; IS CONVERTED TO BINARY AND STORED IN THE PARAMETER ; BLOCK. ALSO IF IT IS A FLOATING POINT NUMBER (MUST ; HAVE A PERIOD), ITS BINARY 2 WORDS IS STORED IN THE ; PARAMETER BLOCK. IF IT IS A CHARACTER STRING WHICH ; STARTS WITH THE SINGLE QUOTE ' CHARACTER, THEN THE ; CONTENTS OF THE STRING IS STORED IN THE PARAMETER ; BLOCK UP TO THE NEXT QUOTE CHARACTER. THE LAST BYTE ; IS SET TO ZERO FOR THE END OF STRING MARKER. ; THE LAST ADDRESS THAT IS STORED INTO THE PARAMETER ; BLOCK IS MAIN1: WHICH IS THE RETURN TO THE POLISH ; INTERPRETER LOOP. ; ; TRANSLATE: MOV R5,-(SP) ;SAVE MATH POINTER MOV #CLINE,R3 ;R3 -> COMMAND LINE TR1: TSTB (R3) ;END OF LINE? BEQ TR7 ;YES, THEN EXIT CMPB #BLANK,(R3)+ ;SKIP OVER BLANKS BEQ TR1 DEC R3 ;BAKUP POINTER CMPB (R3),#'' ;IS IT A QUOTE CHARACTER? BNE 2$ ;NO INC R3 ;YES, THEN IT IS A CHAR STR. 8$: MOVB (R3)+,(R4)+ ;MOVE STRING TO PARMBLK. CMPB (R3),#'' ;END OF STRING? BNE 8$ ;NO, THEN CONTINUE INC R3 ;SKIP QUOTE CHAR CLRB (R4)+ ;MARK END OF STRING BIT #1,R4 ;IS IT EVEN (WORD BOUNDARY) BNE 2$ ;YES CLRB (R4)+ ;NO, CLEAR ODD BYTE 2$: CMPB (R3),#'9 ;IS IT A DIGIT? BGT TR6 ;NO CMPB (R3),#'0 BLT TR6 ;NO MOV R3,R1 ;R1 USED FOR . SEARCH TR3: CMPB (R1)+,#'. ;IS IT FLOATING POINT BEQ TR4 ;YES IT IS CMPB (R1),#BLANK ;END OF FIELD? BNE TR3 ;LOOK AT NEXT CHARACTER BR TR5 ;MUST BE AN INTEGER TR4: CLR (R4)+ ;DEFAULT TO ZERO FOR CLR (R4)+ ;FLOATING POINT NUMBER BR TR1 ;GET NEXT FIELD TR5: JSR PC,CTOI ;CONVERT TO BINARY BR TR1 ;GET NEXT FIELD TR6: JSR PC,GETVAR ;LOOK FOR VARIABLE BR TR1 ;GET NEXT FIELD TR7: MOV #MAIN1,(R4) ;PUT IN RETURN ADDRESS MOV #MAIN1,2(R4) ;EXTRA ONE FOR SAFETY MOV (SP)+,R5 ;RESTORE MATH POINTER RTS PC ;RETURN LENGTH =.-TRANSLATE ; ;*********************************************************** ;; ; UTILITY SUBROUTINE SECTION ; SETUP: MOV #MATHSTACK+MATHLENGTH,R5 ;SETUP MATH POINTER MOV ADDMEM,MEMLINK ;LINK IN ADD ON DICTIONARY MOV NEWMEM,R0 ;R0 = DYNAMIC MEMORY ADDRESS MOV R0,BEGCOL MOV R0,ENDMEM MOV @#RMON,R1 ;START OF RMON TO R1 MOV USR(R1),R0 ;POINT TO LOWEST USR WORD TST -(R0) ;POINT TO HIGHEST WD NOT IN USR .SETTOP ;AND ASK FOR IT MOV R0,MEMTOP ;HIGHEST ADDRESS AVAIABLE MOV R0,LOWBUF ;START BUFFER POOL AT TOP JSR PC,RELEASE .IFDF RT11 .LOOKUP #INAREA,#INCHN,#IN ;OPEN DX1: FLOPPY BCC 3$ ;ERROR? TSTB @#ERRWD ;ERROR, WHATS WRONG? BEQ 3$ ;FILE ALREADY OPEN MOV #OPNERR,R0 ;DX1: OPEN ERROR JMP ERROR ;START ALL OVER .ENDC 3$: RTS PC ; ;-------------> GET A COLUMN <------------------------- ; ; ; GETCOL: MOV R5,-(SP) ;SAVE MATH POINTER CMP @0(R4),#RETURN ;IS MEM FOR THE COL ALLOCATED BNE GETC4 ;YES, THEN EXIT TST ROWS ;IS ROWS ZERO? BNE 1$ ;NO, THEN IT IS OK MOV #ERR1,R0 ;ERROR: ROWS IS ZERO JMP ERROR ;ABORT WITH ERROR 1$: MOV (R4),R2 ;R2 -> DESCRIPTOR BLOCK MOV BEGCOL,R5 ;R5 -> START OF DYNAMIC STORAGE 2$: TST (R5) ;END OF LIST? BEQ 3$ ;YES, THEN ALLOCATE NEW COL TST ITEMADD(R5) ;IS ITEM EMPTY? BEQ GETC2 ;YES, THEN USE IT MOV (R5),R5 ;LOOK AT NEXT ITEM BR 2$ ;CONTINUE WITH NEXT ITEM 3$: MOV R5,R0 ;R0 = R5 + ROWS + 10. ADD ROWS,R0 ADD ROWS,R0 ADD #10.,R0 MOV R0,(R5)+ ;FORWARD LINK MOV R2,(R5)+ ;ADD. OF DESCRIPTOR VALUE CLR (R5)+ ;CLEAR LABEL CLR (R5)+ MOV #DATTYPE,(R5)+ ;TYPE = 7 MOV R5,(R2) ;DESC VALUE = COLUMN ADDRESS MOV #COLTYPE,-2(R2) ; DESC BLK IS COL TYPE ADD ROWS,R5 ;SKIP TO END OF COL ADD ROWS,R5 CLR (R5) ;INSERT NULL POINTER MOV R5,ENDMEM ;GET NEW MAX MEM USED MOV LOWBUF,R0 ;R0 = MAX MEM IN SYSTEM SUB R5,R0 ;R0 = MEM LEFT IN DYNAMIC AREA ASR R0 ;CONVERT TO WORDS MOV R0,LEFT ;UPDATE MEM LEFT VAR ADD ROWS,R5 ADD ROWS,R5 ADD #10.,R5 CMP R5,LOWBUF ;ROOM FOR ANOTHER COL? BLO GETC3 ;YES MOV #OUTOFMEM,R0 ;ERROR: OUT OF MEMORY JMP ERROR ;START ALL OVER GETC2: ADD #10.,R5 ;R5->DATA COL MOV R5,(R2) ;GET COL ADDRESS SUB #10.,R2 ;R2->LABEL DESC BLOCK MOV R2,-8.(R5) ;GET RELINK ADDRESS GETC3: INC COLS GETC4: MOV (SP)+,R5 ;RESTORE MATH POINTER RTS PC LENGTH = .-GETCOL ; ;--------------> GET A VARIABLE <---------------------- ; ; GETVAR: MOV #4,R1 MOV #TEMP,R0 GETV1: CMPB #BLANK,(R3) BEQ GETV2 MOVB (R3)+,(R0)+ SOB R1,GETV1 GETV1A: CMPB (R3)+,#BLANK BNE GETV1A DEC R3 BR GETV3 GETV2: MOVB #BLANK,(R0)+ SOB R1,GETV2 GETV3: MOV TEMP,R0 MOV TEMP+2,R1 MOV #DICTIONARY,R2 ;R2 -> DESCRIPTOR BLOCK GETV4: TST (R2) ;END OF DICTIONARY? BEQ GETV7 ;YES. CMP LABELA(R2),R0 ;CHECK 1ST 2 CHAR OF VAR BNE GETV5 ; NO MATCH CMP LABELB(R2),R1 ;CHECK 2ND 2 CHAR OF VAR BEQ GETV6 ; MATCH FOUND GETV5: MOV (R2),R2 ;LINK TO NEXT DICT. BLK BR GETV4 ;CHECK NEXT DICTIONARY BLK GETV6: MOV ITEMADD(R2),(R4)+ ;GET ADDRESS FIELD RTS PC ; THEN RETURN ; END OF DICTIONARY FOUND, ALLOCATE NEW VARIABLE GETV7: MOV R2,(R2) ;WORD 1 = LINK TO NEXT VAR ADD #12.,(R2)+ MOV R2,(R2) ADD #8.,(R2)+ ;WORD 2 = ADDRESS OF VAR MOV R0,(R2)+ ;WORD 3 = 1ST 2 CHARS MOV R1,(R2)+ ;WORD 4 = 2ND 2 CHARS MOV #INTTYPE,(R2)+ ;WORD 5 = TYPE FIELD MOV R2,(R4)+ ;GET ADD. OF DESC BLK MOV #RETURN,(R2)+ ;WORD 6 = VARIABLE ; NOTE THAT THE JMP @(R4)+ INSTRUCTION IS STORED IN THE ; DATA FIELD OF THE DESCTIPTOR BLOCK. THIS IS IN CASE THE ; USER ACCIDENTLY TYPES IN AN INVALID COMMAND OR TRIES TO ; EXECUTE A NEW VARIABLE, IT WILL DO NO HARM AND JUST ; RETURN TO THE CMD> LEVEL. IF IT IS INDEED A VALID ; VARIABLE, THEN THE INT COMMAND WILL INITIALIZE THE ; DATA FIELD PROPERLY. CLR (R2) ;CLEAR NEXT LINK FIELD MOV R2,ENDMEM ;SAVE NEW ENDMEM MOV R2,BEGCOL ;SAVE NEW BEGMEM MOV LOWBUF,R0 SUB R2,R0 MOV R0,LEFT ;MEM LEFT = LOWBUF - ENDMEM ADD #12.,R2 CMP R2,LOWBUF ;ANY MEMORY LEFT? BLO GETV12 ;YES MOV #OUTOFMEM,R0 ;NO -- ERROR JMP ERROR GETV12: RTS PC LENGTH = .-GETVAR ; ;--------------> PRINT CLINE ON CONSOLE <--------------- ; ; CPRINT: MOV #CLINE,R0 LPRINT: TPRINT: .IFDF RT11 TST PRT ;DO OUTPUT ONTO TERMINAL? BNE 1$ ;NO .PRINT ;PRINT ON TERMINAL 1$: TST PRTON ;DO OUTPUT TO FILE? BEQ 9$ ;NO MOV R1,-(SP) ;SAVE R1 MOV R0,R1 ;R1 -> PRINT LINE 2$: MOVB (R1)+,R0 ;GET CHARACTER TO PRINT BEQ 5$ ;DONE, YES JSR PC,PRTSAVE ;PUT CHAR INTO FILE BR 2$ ;GET NEXT CHARACTER 5$: MOVB #CR,R0 JSR PC,PRTSAVE ;PUT CARRIAGE RETURN IN FILE MOVB #LF,R0 JSR PC,PRTSAVE ;PUT LINE FEED IN PRINT FILE MOV (SP)+,R1 ;RESTORE R1 9$: ; .ENDC ; .IFDF PTS TSTB @#177564 BPL TPRINT MOVB (R0)+,@#177566 BNE PRINT .ENDC RTS PC ; ;---------> TERMOUT PRINTS CHAR ON TERMINAL <-------------- ; ; THE TERMINAL OUT SUBROUTINE IS USED TO PRINT A CHARACTER ; ON THE TERMINAL IF THE PRT FLAG IS ON. ALSO IF THE PRTON ; FLAG IS ON, THEN THE CHARACTER IS WRITTEN TO THE PRINT FILE. ; TERMOUT: TST PRT ;DO OUTPUT ONTO TERMINAL BNE 1$ ;NO .TTYOUT ;PRINT ON TERMINAL 1$: TST PRTON ;DO OUTPUT TO FILE? BEQ 9$ ;NO JSR PC,PRTSAVE ;PUT CHARACTER INTO FILE 9$: RTS PC ;RETURN ; ;----------> PRTSAVE WILL SAVE CHAR IN PRINT FILE <--------- ; ; THE PRTSAVE SUBROUTINE IS USED TO BUILD UP THE PRINT ; BUFFER ONE CHARACTER AT A TIME AND THEN TO WRITE IT TO ; DISK WHEN IT GETS FULL. ; PRTSAVE: MOV R1,-(SP) ;SAVE R1 MOV PRTPTR,R1 ;GET ADDRESS TO STORE CHAR MOVB R0,(R1)+ ;STORE CHAR INTO BUFFER MOV R1,PRTPTR ;SAVE NEW POINTER INC PRTCHARS ;COUNT CHARACTERS IN BUFFER CMP PRTCHARS,#512. ;IS BUFFER EMPTY? BLT 9$ ;NO CLR PRTCHARS ;YES .WRITW #INAREA,#PRTCHN,PRTBUF,#256.,PRTCNT BCC 2$ ;NO ERROR MOV #RDERR,R0 JMP ERROR ;PRINT ERROR MESSABE 2$: MOV PRTBUF,PRTPTR ;RESET PRINT POINTER INC PRTCNT ;COUNT BLOCKS 9$: MOV (SP)+,R1 ;RESTORE R1 RTS PC ;RETURN ; ; ; ;---------------> GET A LINE FROM CONSOLE <------------- ; ; GETLINE: .IFDF RT11 MOV #MSG1,R1 ;R1 -> MSG1 BUFFER 1$: MOVB (R1)+,R0 ;GET CHAR TO PRINT JSR PC,TERMOUT ;PRINT CMD> PROMPT TSTB (R1) ;END OF BUFFER? BNE 1$ ;NO MOV #CLINE,R1 ;R1 -> CLINE BUFFER 2$: JSR PC,TTYIN ;READ INPUT CHARACTER CMPB R0,#'@ ;INDIRECT CHARACTER? BEQ GETLINE ;YES CMPB #LF,R0 ;WAS LAST CHARACTER A LINE FEED BNE 2$ ;NO, GET NEXT CHARACTER. CLRB -(R1) ;CLEAR LF CHAR MOVB #BLANK,-(R1) ;BLANK CR CHAR CMPB CLINE,#'* ;COMMENT LINE? BEQ GETLINE ;THEN IGNORE IT MOVB #GREEN,R0 ;USE GREEN FOR PRINT-OUTS JSR PC,TERMOUT ; ; THIS SECTION OF CODE IS USED TO TURN ON & OFF THE PRINT FILE. ; CMPB CLINE,#'= ;TURN PRINT FILE OFF? BNE 8$ ;NO CLR PRTON ;YES ASR PRTCHARS ;CHANGE IT TO WORD COUNT .WRITW #INAREA,#PRTCHN,PRTBUF,PRTCHARS,PRTCNT BCC 6$ ;NO WRITE ERROR MOV #RDERR,R0 JMP ERROR ;PRINT ERROR MESSAGE 6$: .CLOSE #PRTCHN ;CLOSE THE PRINT FILE BR GETLINE ;READ NEXT COMMAND LINE 8$: CMPB -(R1),#'= ;START PRINT FILEZ? BNE 19$ ;NO CLR PRTCHARS ;YES CLR PRTCNT ;RESET CHARACTER COUNTER INC R1 ;POINT TO BLANK CHAR. CLRB (R1) ;LAST BYTE MUST BE ZERO MOV SP,R1 ;SAVE SP .CSIGEN ENDMEM,#DEXT,#CLINE ;OPEN PRINT FILE BCC 10$ ;OPEN ERROR? MOV #OPNERR,R0 ;YES JMP ERROR ;PRINT ERROR MESSAGE 10$: MOV R1,SP ;RESTORE SP JSR PC,ALLOC ;GET A BUFFER MOV R0,PRTBUF ;SAVE BUFFER ADDRESS MOV R0,PRTPTR ;SAVE NEXT CHAR POINTER INC PRTON ;TURN ON PRINT FILE FLAG BR GETLINE ;GET NEXT COMMAND LINE 19$: RTS PC ;RETURN .ENDC ; .IFDF PTS MOV #MSG1,R0 ;R0 -> MSG1 BUFFER JSR PC,TPRINT ;PRINT CMD> PROMPT MOV #CLINE,R0 GETL1: TSTB @#177560 BPL GETL1 MOVB @#177562,R1 BIC #177600,R1 MOVB R1,(R0)+ GETL2: TSTB @#177564 BPL GETL2 MOVB R1,@#177566 CMPB R1,#CR BNE GETL1 CLRB (R0) ;NULL LAST LINK POINTER MOVB #BLANK,-(R0) GETL3: TSTB @#177564 BPL GETL3 MOVB #LF,@#177566 RTS PC .ENDC ; ; ;---------------> TTYIN CHAR FROM CONSOLE OR FILE <---------- ; ; ; THE TTYIN SUBROUTINE WILL NORMALLY READ INPUT CHARACTERS ; FROM THE RT-11 TTYIN CONSOLE. IF THE INDIRECT COMMAND IS ; TYPED IN AS: @FNAME WILL RESULT IN ALL FURTHER INPUT BEING ; TAKEN FROM THE NAMED INPUT FILE ON DX0: WITH AN EXTENSION ; OF .CMD AND A DEFAULT FILE NAME OF BOOTUP.CMD IF IT IS ; THE FIRST INDIRECT REFERENCE NAD THERE IS NO FILE NAME. ; THE INPUT CHARACTERS ARE TAKEN FROM THE INPUT FILE UNTIL ; AN @ SYMBOL IS READ FROM THE FILE, AT WHICH TIME CONTROL ; WILL RETURN TO THE CONSOLE. ALL OUTPUT WILL BE ECHOED TO ; THE TERMINAL. ; TTYIN: MOV R2,-(SP) ;SAVE REGISTERS TSTB INDFLAG ;INDIRECT MODE? BNE 10$ ;YES .TTYIN ; JSR PC,TERMIN ;GET CHARACTER MOVB R0,(R1)+ CMPB R0,#'@ ;START INDIRECT MODE? BNE 19$ ; NO MOV R1,-(SP) ;SAVE R1 FOR LATER INC INDFLAG ;TURN ON INDIRECT MODE 4$: .TTYIN ; JSR PC,TERMIN ;GET CHARACTER MOVB R0,(R1)+ CMPB R0,#CR ;END OF LINE? BNE 4$ ; YES .TTYIN ; JSR PC,TERMIN ;GET REMAINING CHARS CLRB -(R1) ;MARK END OF FILE NAME MOV (SP)+,R1 ;RESTORE R1 MOV SP,R2 ;SAVE SP .CSIGEN ENDMEM,#DEXT,R1 ;OPEN INDIRECT FILE BCC 20$ ;FILE WAS FOUND MOV #OPNERR,R0 ;PRINT OPEN ERROR MSG JMP ERROR 20$: MOV R2,SP ;RESTORE SP JSR PC,ALLOC ;GET INDIRECT BUFFER MOV R0,INDBUF ;SAVE ITS ADDRESS CLR INDCNT ;RESET BLOCK COUNTER CLR INDBYTES ;FORCE READ NEXT TIME THRU MOVB #'@,R0 ;FORCE NEW LINE FOR GETLINE: BR 19$ ;THEN EXIT 8$: MOV #512.,INDBYTES ;RESET BYTE COUNTER MOV INDBUF,INDPOINTER .READW #INAREA,#INDCHN,INDBUF,#256.,INDCNT BCC 9$ ;END OF FILE? NO DEC R1 ;WIPE OUT THE @ SIGN MOVB #'@,R0 BR 11$ ;CLOSE THE FILE 9$: INC INDCNT ;POINT TO NEXT BLOCK 10$: DEC INDBYTES ;BUFFER EMPTY? BLT 8$ ;YES, GET NEXT BLOCK MOV INDPOINTER,R2 ;R2 => INDIRECT BUFFER MOVB (R2)+,R0 ;GET CHARACTER MOVB R0,(R1)+ ; FOR RETURN CMPB R0,#'@ ;END OF INDIRECT MODE? BNE 12$ ; NO 11$: CLR INDFLAG ;YES DEC R1 ;WIPE OUT THE @ SIGN JSR PC,BUFRELEASE ;RELEASE THE MEMORY SPACE .CLOSE #INDCHN ;CLOSE THE INDIRECT FILE BR 19$ ; AND EXIT 12$: JSR PC,TERMOUT ;PRINT IT MOV R2,INDPOINTER 19$: MOV (SP)+,R2 ;RESTORE R2 RTS PC ; ;------------> TERMIN READS CHAR FROM TERMINAL <------------ ; TERMIN: .TTYIN ;GET CHARACTER FROM RT-11 TST PRTON ;DO OUTPUT TO FILE? BNE 9$ ;NO JSR PC,PRTSAVE ;PUT CHAR INTO FILE 9$: RTS PC ;RETURN ; ; ; ;-----------> ALLOC A BUFFER <-------------------------------- ; ; THE ALLOC SUBROUTINE IS USED TO ALLOCATE A BUFFER FROM THE ; TOP OF MEMORY AND THE BUFFER SIZE IS 256. WORDS. THE ; BUFFER ADDRESS IS RETURNED IN R0. IF ROOM FOR BUFFERS IS ; EMPTY THEN AN ERROR RETURN IS TAKEN. ; ALLOC: INC BUFS ;KEEP TRACK OF BUFFER COUNT MOV LOWBUF,R0 ;GET CURRENT BUFFER ADDR. SUB #512.,R0 ;GET A BUFFER MOV R0,LOWBUF ;SAVE NEW BUFFER ADDRESS CMP R0,ENDMEM ;IS ANY MEMORY LEFT? BHI 1$ ;YES MOV #OUTOFMEM,R0 ;NO JMP ERROR ;PRINT ERR MSG 1$: RTS PC ;RETURN ; ;----------> BUFRELEASE TO RELEASE A BUFFER <---------------- ; ; THE BUFRELEASE SUBROUTINE IS USED TO RELEASE A BUFFER FROM ; THE BUFFER POOL AT THE TOP OF MEMORY. THE BUFRELEASE ; SHOULD BE MATCHED WITH THE PREVIOUS ALLOC AS THOUGH ; IT WAS A STACK. ; BUFRELEASE: DEC BUFS ;KEEP COUNT OF NUMBER OF BUFS ADD #512.,LOWBUF ;RELEASE THE LAST BUFFER RTS PC ;RETURN ; ; ;----------------> RADCONVERT SUBROUTINE <----------------- ; ; THE RADCONVERT SUBROUTINE IS USED TO CONVERT SIX CHARACTERS ; STORED AT "RADIN" FROM ASCII TO RAD50 FORMAT STORED IN TWO ; WORDS POINTED TO BY R4. ONLY THE LETTERS A TO Z MAY BE ; CONVERTED TO RAD50 BY THIS SUBROUTINE. ; ; ;RADCONVERT: ; MOV #RADIN,R1 ;R1 -> INPUT CHARACTERS ; MOV #RADIN+3,R5 ;ADDRESS OF 2ND WORD TO PACK ;1$: CLR R3 ;SUM=0 ;2$: CLR R2 ;R2=0 ; MOVB @R1,R2 ;GET CHARACTER ; BICB #300,R2 ;CLEAR LEADING BITS ; ADD R2,R3 ;SUM=SUM+TRANSLATED CHAR ; CLRB (R1)+ ;CLEAR CHAR OUT ; CMP R1,R5 ;IS R1 RELEASE ALL DYNAMIC MEMORY <----------- ; ; RELEASE:JSR PC,RELCOLS MOV NEWMEM,R0 MOV R0,BEGCOL MOV R0,ENDMEM CLR ROWS ;ROWS = 0 CLR COLS MOV #BUFFER/2,LEFT CLR (R0) RTS PC ; CTOI: MOV R2,-(SP) MOV R5,-(SP) ;SAVE MATH POINTER MOV #PUSHINT,(R4)+ CLR R5 CTOI3: CMPB #BLANK,(R3) BEQ CTOI4 MOVB (R3)+,R2 BIC #177600,R2 SUB #'0,R2 MUL #10.,R5 ADD R2,R5 BR CTOI3 CTOI4: MOV R5,(R4)+ MOV (SP)+,R5 ;RESTORE MATH POINTER MOV (SP)+,R2 RTS PC LENGTH = .-CTOI ; ; THE ICON SUBROUTINE WILL CONVERT AN INTEGER NUMBER ; TO AN ASCII FIELD WITH THE $ICO ROUTINE. ; ; R0 = FIELD START LOCATION ; R1 = VALUE TO CONVERT ; ; JSR PC,ICON ; ICON: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R0,-(SP) ;FIELD START LOCATION MOV #8.,-(SP) ;FIELD LENGTH MOV R1,-(SP) ;VALUE TO CONVERT JSR PC,$ICO ;CONVERT VALUE MOV (SP)+,R3 ;RESTORE REGISTERS MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ADD #8.,R0 ;SKIP FIELD RTS PC ;RETURN ; ; $OCO OCTAL TO ASCII CONVERSION ; $ICO INTEGER TO ASCII CONVERSION ; ; CALLING SEQUENCE: ; ; PUSH FIELD START ; PUSH FIELD LENGTH ; PUSH VALUE ; JSR PC,$ICO (OR $OCO) ; ERROR WILL BE RETURNED WITH C BIT SET ON ; NO REGISTERS ARE DESTROYED ; $OCO: MOV #OCT$25-REL$25,R0 ;POINT TO OCTAL TABLE BR GO$25 $ICO: MOV #DEC$25-REL$25,R0 ;POINT TO DECIMAL TABLE GO$25: MOV R4,-(SP) MOV 8.(SP),R3 ;GET FIELD START MOV 6.(SP),R2 ;GET FIELD LENGTH BGE LPS$25 ;JUMP IF LENGTH NOT NEGATIVE CLR R2 CLR 6(SP) LPS$25: MOV 4.(SP),R4 ;GET VALUE TO BE CONVERTED MOV #BLANK,-(SP) ;CLEAR SIGN CMP R0,#OCT$25-REL$25 ;CHECK IF DOING OCTAL BEQ POS$25 ;YES, GIVE MAGNITUDE RESULT TST R4 ;TEST SIGN BGE POS$25 ;JUMP IF + NEG R4 ;GET ABSOLUTE VALUE MOV #'-,@SP ;SAVE - POS$25: CLR -(SP) ;SET FENCE ADD PC,R0 REL$25: TST$25: TST @R0 BEQ MOV$25 ;JUMP IF ALL POWERS DONE CLR R1 SUB$25: SUB @R0,R4 ;SEE IF CURRENT POWER WILL GO AGAIN BLO BAC$25 INC R1 ;BUMP DIGIT BR SUB$25 BAC$25: ADD (R0)+,R4 ;TOO MUCH, BACK UP TST R1 BNE NZE$25 ;JUMP IF DIGIT NOT 0 TST @SP BEQ TST$25 ;JUMP IF NO NON-ZERO DIGITS YET NZE$25: ADD #60,R1 ;CONVERT TO ASCII MOV R1,-(SP) BR TST$25 MOV$25: ADD R2,R3 ;POINT TO FIELD END ADD #60,R4 ;CONVERT LEAST SIGNIFICANT DIG. MOVB R4,-(R3) DCR$25: DEC R2 BLE FUL$25 ;JUMP IF COUNT EXHAUSTED MOVB (SP)+,-(R3) ;MOVE DIGIT BNE DCR$25 ;JUMP IF NOT THE FENCE MOVB (SP)+,@R3 ;MOVE OUT THE SIGN FIL$25: DEC R2 BEQ DNE$25 ;JUMP IF FIELD FILLED MOVB #BLANK,-(R3) ;MOVE IN LEADING BLANKS BR FIL$25 FUL$25: TST (SP)+ BNE ERR$25 ;NUMBER TOO BIG FOR FIELD CMP #BLANK,(SP)+ BNE STS$25-4. ;JUMP IF NO ROOM FOR - DNE$25: MOV (SP)+,R4 MOV (SP)+,4(SP) ;MOVE RETURN UP TST (SP)+ ;FLUSH VALUE ROL (SP)+ ;FLUSH FLAG AND SET C FOR ERR RTS PC ;RETURN ERR$25: TST (SP)+ BNE ERR$25 TST (SP)+ ;FLUSH SIGN MOV 8.(SP),R3 STS$25: MOV #'*,(R3)+ ;FILL FIELD WITH * DEC 6(SP) BGT STS$25 ;JUMP IF MORE TO DO COM 6(SP) ;FLAG ERROR BR DNE$25 DEC$25: .WORD 10000. .WORD 1000. .WORD 100. .WORD 10. .WORD 0 OCT$25: .WORD 100000 .WORD 10000 .WORD 1000 .WORD 100 .WORD 10 .WORD 0 LENGTH = .-$OCO ; ;-----------> INTEGER TO REAL CONVERSION <------------- ; ; ; THE $IR SUBROUTINE IS EXTRACTED FROM THE FPMP-11 BOOK ; ON PAGE 113 (DEC-11-NFPMA-C-D). THIS SUBROUTINE ; IS USMD(TO CONVERT AN INTEGER ON THE MATH STACK ; (POINTED TO BY R5) TO A FLOATING POINT NUMBER ; ON THE MATH STACK. ; ; ; ; $IR: MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 CLR -(R5) ;MAKE ROOM FOR RESULT MOV 2(R5),R1 ;GET INTEGER ARGUMENT BGT 1$ ;NO BEQ 9$ ;IS IT ZERO. NEG R1 ;GET ABSOLUTE VALUE 1$: ROL -(R5) ;SAVE SIGN MOV #220,R2 ;GET MAX POSSIBLE EXP +1 CLRB 4(R5) ;CLEAR LOWEST ORDER FRACT. 2$: ROL R1 ;LOOK FOR NORMAL BIT BCS 3$ ;J]MP IF FOUND DEC R2 ;DECREASE EXPONENT BR 2$ ;TRY AGAIN 3$: MOVB R1,5(R5) ;SAVE LOW ORDER FRACTION CLRB R1 BISB R2,R1 ;COMBINE EXP & HIGH ORDER FRAC SWAB R1 ROR (R5)+ ;GET SIGN ROR R1 ;INSERT SIGN IN RESULT RORB 3(R5) MOV R1,(R5) ;OUTPUT RESULT 9$: MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R1 ;RESTORE R1 RTS PC ;RETURN ; ;------------> REAL TO INTEGER CONVERSION <----------------- ; ; ; THE $RI ROUTINE IS USED TO CONVERT A FLOATING POINT ; NUMBER ON THE MATH STACK (POINTED TO BY R5) TO A ; INTEGER NUMBER ON THE MATH STACK. ; REFERENCE: FPMP11 MANUAL PAGE 135. ; $RI: MOV R1,-(SP) ;SAVE R1 MOV R3,-(SP) ;SAVE R3 MOV R2,-(SP) ;SAVE R2 CLR R2 ;CLEAR WORK SPACE INC R2 ;SETUP NORMAL BIT MOV (R5)+,R1 ;GET REAL ARGUMENT ROL (R5) ;GET SIGN ROL R1 ;AND ROL -(R5) ;SAVE IT MOVB R1,R3 ;GET HIGH ORDER FRACTION CLRB R1 SWAB R1 ;GET EXPONENT SUB #201,R1 BLT 8$ ;JUMP IF IT IS TOO SMALL BEQ 3$ CMP #15.,R1 BLT 6$ ;JUMP IF IT IS TOO BIG SWAB R3 ;FORM 16 BITS OF HIGH ORD FRAC CLRB R3 BISB 3(R5),R3 1$: ASHC R1,R2 2$: NEG R2 ;MAKE - BVS 5$ ;JUMP IF POSSIBLE NEGMAX BGT 6$ ;JUMP IF MORE THEN 15 BITS 3$: ROR (R5)+ ;GET SIGN BCS 4$ ;JUMP IF - NEG R2 ;- RESULT 4$: MOV R2,(R5) ;STORE INTEGER RESULT BR 9$ 5$: ROR (R5)+ BCS 4$ ;OK IF RESULT TO BE - 6$: TST -(R5) ;FAKE SIGN MOV #CNVERR,R0 ;ERROR 3, 22 JMP ERROR ;PRINT ERROR MESSAGE 8$: CLR R2 ;ANSWER IS ZERO BR 3$ 9$: MOV (SP)+,R2 ;RESTORE REGISTERS MOV (SP)+,R3 MOV (SP)+,R1 RTS PC ;RETURN ; ; ; ;------------> PRINT A VARIABLE <------------------------- ; ; ; THE PRTITEM SUBROUTINE IS USED \O PRINT THE VARIABLE ; NAME FOLLOWED BY A EQUAL SIGN AND THE VALUE OF ; THE VARIABLE. THE VARIABLE MAY BE EITHER AN INTEGER OR ; A FLOATING POINT NUMBER. ; ; R0 = ADDRESS OF FIELD IN PRINT BUFFER ; R2 = ADDRESS OF VARIABLE ; ; JSR PC,PRTITEM ; PRTITEM:CMP -2(R2),#FLTTYPE ;IS IT PRINTABLE? BGT PRTI3 ;NO, EXIT MOV R2,R3 ;R3 -> VARIABLE LABEL SUB #6,R3 MOV #4,R1 ;R1 = LENGTH OF VAR. LABEL PRTI1: MOVB (R3)+,(R0)+ ;MOVE LABEL TO PZT(LINE SOB R1,PRTI1 MOVB #BLANK,(R0)+ ;FOLLOW WITH SPACE AND MOVB #'=,(R0)+ ;EQUAL SIGN AND SPACE MOVB #BLANK,(R0)+ MOV -2(R2),R3 ;R3 = VARIABLE TYPE CODE MOV (R2)+,R1 ;R1 = INTEGER VARIABLE CMP R3,#INTTYPE ;IS IT AN INTEGER? BNE PRTI2 ;NO JSR PC,ICON ;CONVERT INTEGER BR PRTI3 PRTI2: CMP R3,#FLTTYPE ;IS IT FLOATING TYPE? BNE PRTI3 ;NO MOV (R2)+,R2 ;GET FLOATING VALUE PRTI3: CLRB (R0) ;CLEAR END OF FIELD RTS PC ;RETURN LENGTH = .-PRTITEM ; ;*********************************************************** ; ; POLISH INTERPERTIVE PROGS ; DIFF: MOV R4,-(SP) MOV PC,R4 CMP (R4)+,(R4)+ RETURN CSUB END LENGTH = .-DIFF ; ; ;************************************************************ ; ; POLISH COMMAND ROUTINES SECTION ; SRESET: JSR PC,RELEASE RETURN ; EXIT: .IFDF RT11 .CLOSE #INCHN .EXIT .ENDC ; HALTCPU:HALT RETURN ; FOR: MOV (R4)+,R0 MOV R0,-(SP) MOV @(R4)+,R1 MOV @(R4)+,-(SP) MOV @(R4)+,-(SP) MOV R1,(R0) MOV R4,-(SP) RETURN ; NEXT: MOV 6(SP),R0 ADD 2(SP),(R0) CMP (R0),4(SP) BGT NEXT1 MOV (SP),R4 RETURN NEXT1: ADD #8.,SP RETURN LENGTH =.-FOR ; GEN: JSR PC,GETCOL MOV @(R4)+,R0 MOV ROWS,R3 MOV #1,R1 ;START COUNT AT ONE GEN1: MOV R1,(R0)+ INC R1 SOB R3,GEN1 RETURN ; INT: MOV (R4)+,R2 TST (R4)+ ;SKIP "PUSH" COMMAND MOV (R4)+,(R2) RETURN ; PUSHFLT:MOV (R4)+,-(R5) ; PUSHINT:MOV (R4)+,-(R5) RETURN ; ; CPUSH: JSR PC,GETCOL ; PUSH: MOV @(R4)+,-(R5) RETURN ; POP: MOV (R5)+,@(R4)+ RETURN ; CADD: MOV (R5)+,R0 MOV (R5),R1 MOV ROWS,R3 CADD1: ADD (R0)+,(R1)+ SOB R3,CADD1 RETURN ; CSUB: MOV (R5)+,R0 MOV (R5),R1 MOV ROWS,R3 CSUB1: SUB (R0)+,(R1)+ SOB R3,CSUB1 RETURN ; CMOV: MOV (R5)+,R0 MOV (R5),R1 MOV ROWS,R3 CMOV1: MOV (R0)+,(R1)+ SOB R3,CMOV1 RETURN ; CMUL: MOV R4,-(SP) ;SAVE POLISH POINTER MOV (R5)+,R0 MOV (R5),R1 MOV ROWS,R3 CMUL1: MOV (R1),R4 MUL (R0)+,R4 MOV R4,(R1)+ SOB R3,CMUL1 MOV (SP)+,R4 ;RESTORE POLISH POINTER RETURN ; CDIV: MOV R4,-(SP) ;SAVE POLISH POINTER MOV (R5)+,R0 MOV (R5),R1 MOV ROWS,R4 CDIV1: MOV (R1),R3 CLR R2 DIV (R0)+,R2 MOV R2,(R1)+ SOB R4,CDIV1 MOV (SP)+,R4 ;RESTORE POLISH POINTER RETURN ; CDOWN: RETURN ; ADDFL: FADD R5 RETURN ; SUBFL: FSUB R5 RETURN ; MULFL: FMUL R5 RETURN ; DIVFL: FDIV R5 RETURN ; ADDI: ADD (R5)+,(R5) RETURN ; SUBI: SUB (R5)+,(R5) RETURN ; MULI: MOV (R5)+,R1 ;GET MULTIPLICAND MUL (R5),R1 ;MULTIPLY IT BY STACK VALUE MOV R1,(R5) ;STORE RESULT ON STACK RETURN ; DIVI: MOV (R5)+,R1 ;GET DIVISOR MOV (SP),R3 ;GET DIVIDEND CLR R2 DIV R2,R1 ;DIVIDE IT MOV R2,(R5) ;GET QUOTIENT RETURN ; FLT: MOV (R4)+,R2 MOV (R4)+,(R2)+ MOV (R4)+,(R2) RETURN ; MOVE: MOV @(R4)+,@(R4)+ RETURN ; PUT: MOV @(R4)+,R0 MOV @(R4)+,R1 DEC R1 ASL R1 ADD R1,R0 MOV @(R4)+,(R0) RETURN ; GET: MOV @(R4)+,R0 MOV @(R4)+,R1 DEC R1 ASL R1 ADD R1,R0 MOV (R0),@(R4)+ RETURN ; INTEGER:JSR PC,$IR RETURN ; FLOAT: JSR PC,$RI RETURN ; RELCOLS:MOV BEGCOL,R0 CMP R0,ENDMEM BEQ RELC3 RELC1: MOV 2(R0),R1 BEQ RELC2 CLR (R1) CLR 2(R0) RELC2: MOV (R0),R0 TST (R0) BNE RELC1 RELC3: RTS PC ; DECLARE:CMP (R4),#MAIN1 ;DEFAULT END OF LIST? BEQ 1$ ;YES TST (R4)+ BNE DECLARE 1$: RETURN ; FDECLARE:MOV (R4)+,R2 ;R2 -> DESCRIPTOR VALUE MOV #FLTTYPE,-2(R2) ;TYPE FIELD = 3 ADD #2,-10.(R2) ;CHANGE LINK ADDRESS CLR 4(R2) ;SET NEXT LINK TO NULL RETURN ; CDECLARE:JSR PC,GETCOL ;GET A COLUMN ALLOCATED TST (R4)+ ;IGNORE ADDRESS RETURN ; IF: MOV @(R4)+,R1 MOV @(R4)+,IF1 MOV @(R4)+,R2 MOV @(R4)+,R3 CMP R1,R2 IF1: .WORD 0 RETURN ASL R3 ADD R3,R4 RETURN ; CASE: MOV @(R4)+,R0 DEC R0 ASL R0 MOV @(R4)+,R1 ASL R1 ADD R4,R0 ADD R1,R4 JMP @(R0)+ ; PROG: MOV R4,-(SP) MOV (R4),R4 MOV #DIFF,R1 MOV #4,R0 PROG1: MOV (R1)+,(R4)+ SOB R0,PROG1 MOVB #BLUE,MSG1 ;PRINT PROMPT IN CYAN PROG2: JSR PC,GETLINE JSR PC,TRANSLATE CMP -2(R4),#END BNE PROG2 MOVB #CYAN,MSG1 ;RESET PROMPT TO BLUE CLR (R4) MOV R4,R0 MOV (SP)+,R4 MOV (R4)+,R2 MOV #CMDTYPE,-(R2) SUB #6,R2 MOV R0,-(R2) RETURN ; END: MOV (SP)+,R4 RETURN ; FREE: MOV (R4)+,R2 CLR (R2) MOV #RETURN,@-8.(R2) ;TURN OFF COL ADDRESS DEC COLS RETURN ; FPUSH: MOV (R4)+,R2 MOV (R2)+,-(R5) MOV (R2),-(R5) RETURN ; FPOP: MOV (R4)+,R2 MOV (R5)+,(R2)+ MOV (R5)+,(R2) RETURN ; SET: JSR PC,GETCOL ;CHECK FOR NEW COLUMN MOV @(R4)+,R0 MOV @(R4)+,R1 MOV ROWS,R3 SET1: MOV R1,(R0)+ SOB R3,SET1 RETURN ; ; ;-------> DUMP <-------------------------------------------- ; ; DUMP ALL MEMORY VARIABLES. ; DUMP: MOV R5,-(SP) ;SAVE MATH POINTER MOV #MEMDUMP,R5 ;R5 -> DESCRIPTOR BLK TO DMP DUMP1: MOV ITEMADD(R5),R2 ;R2 -> VARIABLE TO PRINT MOV #CLINE,R0 ;R0 -> PRINT BUFFER JSR PC,PRTITEM ;CONVERT THE VARIABLE CLRB (R0) ;MARK END OF LINE JSR PC,CPRINT ;PRINT THE VARIABLE MOV (R5),R5 ;GET ADD. OF NEXT BLOCK TST (R5) ;END OF LIST? BNE DUMP1 ;CONTINUE IF MORE MOV (SP)+,R5 ;RESTORE MATH POINTER RETURN ; ; ;-------> PRINT VAR1 VAR2 .... VARN $ <----------------------- ; ; PRINT VARIAJLES SPECIFIED IN THE GIVEN LIST. VARIABLES ; MAY BE EITHER INTEGER OR REAL. DOLLAR SIGN MUST END THE ; LIST OF VARIABLES. ; PRINT: MOV #CLINE,R0 ;R0 -> PRINT LINE PRINT1: CMP (R4),#MAIN1 ;DEFAULT END OF LIST? BEQ PRINT2 ;YES MOV (R4)+,R2 ;R2 -> VARIABLE TO PRINT BEQ PRINT2 ;EXIT IF END OF LIST JSR PC,PRTITEM ;PRINT THE VARIABLE MOVB #',,(R0)+ ;SEPARATE ITEMS BY MOVB #BLANK,(R0)+ ;A COMMA AND SPACE BR PRINT1 ;PRINT NEXT VARIABLE PRINT2: CLRB -(R0) ;CLEAR END OF LINE CLRB -(R0) JSR PC,CPRINT ;PRINT THE LINE CLR CLINE ;RESET PRINT LINE RETURN ; LIST: MOV R5,-(SP) ;SAVE MATH POINTER MOV #CLINE,R0 CLR R5 ;R5 = COLUMN COUNTER 1$: CMP (R4),#MAIN1 ;DEFAULT END OF LIST? BEQ 4$ ;YES MOV (R4)+,R2 ;R2=ADDR OF COLUMN ADDR BEQ 4$ ;END OF LIST? YES MOV (R2),R1 ;R1 -> COLUMN CMP -(R2),#COLTYPE ;TYPE = COLUMN? BNE 1$ ; NO, THEN SKIP IT MOV R1,-(SP) ;PUT COL ADDRESS ONTO STACK INC R5 ;KEEP COUNT OF COLUMNS CMP -(R2),-(R2) ;POINT R2 TO NAME FIELD MOV #4,R1 ;INSERT 4 SPACES 3$: MOVB #BLANK,(R0)+ ; INTO CLINE SOB R1,3$ MOV #4,R1 ;MOVE 4 CHAR NAME FIELD 2$: MOVB (R2)+,(R0)+ ; INTO CLINE SOB R1,2$ CLRB (R0) ;MARK END OF LINE BR 1$ ;GET NEXT COLUMN 4$: JSR PC,CPRINT ;PRINT TITLE LINE MOV R5,R1 ASL R1 ADD SP,R1 ;R1 = (COLS*2) + SP MOV R4,-(SP) ;SAVE POLISH POINTER MOV R1,-(SP) ;SAVE ADDR OF STACK LIST MOV ROWS,R4 ;R4 = ROW COUNTER 5$: MOV R5,R2 ;R2 = COL COUNTER MOV (SP),R3 ;R3 = POINTS TO ADDR OF COL ADD 6$: MOV @-(R3),R1 ;R1 = DATA VALUE TO PRINT ADD #2,(R3) ;INC COL ADDR BY ONE ROW JSR PC,ICON ;CONVERT DATA VALUE SOB R2,6$ ;DO ONE ROW AT A TIME CLRB (R0) ;MARK END OF LINE JSR PC,CPRINT ;PRINT ONE ROW SOB R4,5$ ;GET NEXT ROW TST (SP)+ ;POP R1 MOV (SP)+,R4 ;RESTORE R4 ASL R5 ADD R5,SP ;RESTORE SP MOV (SP)+,R5 ;RESTORE MATH POINTER RETURN ; ; -------> TTYOUT VAR <---------------------------------- ; TTYOUT: MOV @(R4)+,R0 $TTYOUT RETURN ; ;---------> DELAY EXECUTION <----------------------------- ; DELAY: $DELAY RETURN ; ; ;-------> SCALE VAR1 VAR2 ...... VARN $ <------------------- ; SCALE: MOV @(R4)+,R3 ;R3 = COL ADDRESS MOV (R3),R0 ;R0 = MIN VALUE MOV R0,R1 ;R1 = MAX VALUE BR 2$ 1$: CMP (R4),#MAIN1 ;DEFAULT END OF LIST? BEQ 7$ ;YES TST (R4) ;IS IT THE LIST COL? BEQ 6$ ;YES MOV @(R4)+,R3 ;R3 = COL ADLRESS 2$: MOV ROWS,R2 ;R2 = ROW COUNTER DEC R2 ;1ST ZOW IS ILREADY LONE 3$: TST (R3)+ CMP (R3),R0 ;CHECK MIN VALUE BGT 4$ MOV (R3),R0 ;GET NEW MIN VILUE 4$: CMP (R3),R1 ;CHECK MAX VALUE BLT 5$ MOV (R3),R1 ;GET NEW MAX VALUE 5$: SOB R2,3$ ;CHECK ALL VALUES IN(COL BR 1$ ;DO NEXT COL 6$: TST (R4)+ ;SKIP ZERO WORD 7$: MOV R0,MINSCALE ;SAVE MIN VALUE ; RANGESCALE = ((R1-R0)+(MAXY-1))/MAXY SUB R0,R1 ;GET THE RANGE MOV MAXY,R2 DEC R2 ADD R2,R1 MOV R1,-(R5) JSR PC,$IR ;PUSH RANGE ONTO STACK MOV MAXY,-(R5) JSR PC,$IR ;PUSH MAXY ONTO STACK FDIV R5 MOV (R5)+,RANGESCALE ;SAVE RANGE MOV (R5)+,RANGESCALE+2 RETURN ; ;-------> LINE COL <-------------------------------------- ; LINE: MOV @(R4)+,R3 ;GET COL ADDRESS MOV R4,-(SP) ;SAVE POLISH POINTER MOV FIRSTROW,R0 INC R0 ASL R0 ADD R0,R3 ;R3 = ADDRESS OF ROW MOV LASTROW,R4 SUB FIRSTROW,R4 ;R5 = NUMBER OF ROWS CMP R4,MAXX ;WILL IT FIT ON SCREEN BLE 1$ ;YES MOV MAXX,R4 ;NO, THEN REDUCE IT 1$: CLR R2 ;R2 = X PLOT VALUE $TTYOPEN ;PREPARE FOR GRAPHICS $TTYOUT #2 ;ENTER POINT PLOT MODE 2$: $TTYOUT R2 ;PLOT X VALUE MOV (R3)+,R1 ;GET DATA VALUE SUB MINSCALE,R1 ;SCALE TO MIN VALUE MOV R1,-(R5) JSR PC,$IR ;PUSH DATA VALUE ONTO STACK MOV RANGESCALE+2,-(R5) ;PUSH RANGE MOV RANGESCALE,-(R5) FDIV R5 ;COMPUTE PLOT VALUE JSR PC,$RI MOV (R5)+,R0 ;GET PLOT VALUE $TTYOUT ;PLOT Y VALUE MOV PLTWAIT,R0 SOB R0,. ;WAIT FOR COMPUCOLOR II TST R2 ;IS IT THE FIRST POINT? BNE 3$ ;YES, THEN GO ON $TTYOUT #242. ;ENTER VECTOR MODE 3$: INC R2 ;STEP TO NEXT X VALUE SOB R4,2$ $TTYOUT #255. ;EXIT PLOT MODE $TTYCLOSE ;RETURN TO RT-11 MODE MOV (SP)+,R4 ;RESTORE POLISH POINTER RETURN ; ;------------------> READ COL <-------------------------- ; ; THE READ COL COMMAND WILL READ FROM THE FLOPPY ONE ; COLUMN OF LATA FROM DISK , WHICH IS LOCATED AT "BLOCK". ; READ: JSR PC,GETCOL MOV @(R4)+,R3 ;R3 -> NEW COLUMN READ1: ;GLOBAL ENTRANCE .IFDF RT11 .READW #INAREA,#INCHN,R3,ROWS,BLOCK ;READ COL BCC 1$ ;ERROR? MOV #RDERR,R0 ;MRROR: READ ERROR JMP ERROR ;START ALL OVER .ENDC 1$: INC BLOCK ;POINT TO NEXT BLOCK RETURN ; ;******************************************************** ; ; STUBS SECTION ; ; ;******************************************************* ; ; FREE STORAGE SECTION FOR DYNAMIC ALLOCATION ; ENDPOL: .WORD 0 .END MAIN