;;The official source for this file is MIDAS;MACSYM > ;;Midas versions of some MACSYM.MAC macros, by GZ@MC. ;;(Also some useful macros/symbols no supported by MACSYM.MAC) ;Stuff supported (will add more stuff as need arises): ; PGVER. VMAJ,VMIN,VEDIT,VWHO and related masks(VI%MAJ,VI%MIN,VI%EDN,VI%WHO) ; Random symbols (.INFIN,.MINFI,.LHALF,.RHALF,.FWORD, .CHxxx, ; ASCPTR, USRLH, PSLH, .PRxxx) ; FLD(VAL,MSK) & BIT(n) & POINT SIZE,ADDR,OFFSET & ERNOP & ERSKP ; MOVX AC,MASK & TXxx AC,MASK & JXx AC,MASK,ADDR & LOAD/STOR AC,MASK,ADDR ; DO./ENDDO. macros (and related stuff) ; IFxxx/ANxxx macros ; TMSG /text/, FMSG /text/, EMSG /text/ ; SAVEACS [A,B,C,D] & SAVE. [LOC,LOC,LOC] ; FLDDB.(FUNC,FLAGS,DATA,"Help","Default",NEXT) ; FLDBK.(FUNC,FLAGS,DATA,"Help","Default",BRKMASK,NEXT) ; BRMSK.(INI0,INI1,INI2,INI3,[ALLOW],[DISALLOW]) IFNDEF $$JSER,$$JSER==0 ; Conditional on $$JSER: ; PERSTR /optional msg/ ; ERMSG /text/ ; JSERR/EJSERR/JSHLT/EJSHLT ; and support code for above. IFNDEF $$STK,$$STK==0 ; Conditional on $$STK: ; CALL/RET/RETSKP/CALLRET ; STKVAR [AA,[QQ,5],ZZ]/ENDSV. ; labels RSKP and R ; and support code for above. .KILL ..XX,..TXZ,..TXO,..TXC,..X0,..X1,..X2,..X3,TOP. .XCREF ..XX,..TXZ,..TXO,..TXC,..X0,..X1,..X2,..X3 .XCREF ..DX,..IX,..EX,.SAVX1,.SAVX2,..BRK IF2,IFE $$STK\$$JSER,.INEOF ;Don't bother if no code ;.NSTGW ;No storage words in this part DEFINE PGVER. (VMAJ,VMIN,VEDIT,VWHO) ..XX==. LOC 137 .JBVER: .BYTE 3.,9.,6.,18. VWHO VMAJ VMIN VEDIT .BYTE LOC ..XX TERMIN ;MASKS FOR THE ABOVE VI%WHO==:700000,,000000 ;Customer edit code VI%MAJ==:077700,,000000 ;Major version number VI%MIN==:000077,,000000 ;Minor version/update VI%EDN==:000000,,777777 ;Edit number ;MISC CONSTANTS .INFIN==:377777,,777777 ;PLUS INFINITY .MINFI==:400000,,000000 ;MINUS INFINITY .LHALF==:-1,,0 ;LEFT HALF .RHALF==:0,,-1 ;RIGHT HALF .FWORD==:-1 ;FULL WORD ASCPTR==:440700,,0 USERLH==:500000 PSLH==:540000 ;MIT EXEC PRARG command codes .PRCCL==0 ;redo last CCL command .PRKEP==1 ;keep fork, and halt it .PRKIL==2 ;kill fork .PRBKG==3 ;continue fork in background ;SYMBOLS FOR THE CONTROL CHARACTERS .CHNUL==:000 ;NULL .CHCNA==:001 .CHCNB==:002 .CHCNC==:003 .CHCND==:004 .CHCNE==:005 .CHCNF==:006 .CHBEL==:007 ;BELL .CHBSP==:010 ;BACKSPACE .CHTAB==:011 ;TAB .CHLFD==:012 ;LINE-FEED .CHVTB==:013 ;VERTICAL TAB .CHFFD==:014 ;FORM FEED .CHCRT==:015 ;CARRIAGE RETURN .CHCNN==:016 .CHCNO==:017 .CHCNP==:020 .CHCNQ==:021 .CHCNR==:022 .CHCNS==:023 .CHCNT==:024 .CHCNU==:025 .CHCNV==:026 .CHCNW==:027 .CHCNX==:030 .CHCNY==:031 .CHCNZ==:032 .CHESC==:033 ;ESCAPE .CHCBS==:034 ;CONTROL BACK SLASH .CHCRB==:035 ;CONTROL RIGHT BRACKET .CHCCF==:036 ;CONTROL CIRCUMFLEX .CHCUN==:037 ;CONTROL UNDERLINE .CHSPC==:040 ;SPACE .CHALT==:175 ;OLD ALTMODE .CHAL2==:176 ;ALTERNATE OLD ALTMODE .CHDEL==:177 ;DELETE ;PC FLAGS PC%OVF==:400000,,0 ;OVERFLOW PC%CY0==:200000,,0 ;CARRY 0 PC%CY1==:100000,,0 ;CARRY 1 PC%FOV==:040000,,0 ;FLOATING OVERFLOW PC%BIS==:020000,,0 ;BYTE INCREMENT SUPPRESSION PC%USR==:010000,,0 ;USER MODE PC%UIO==:004000,,0 ;USER IOT MODE PC%LIP==:002000,,0 ;LAST INSTRUCTION PUBLIC PC%AFI==:001000,,0 ;ADDRESS FAILURE INHIBIT PC%ATN==:000600,,0 ;APR TRAP NUMBER PC%FUF==:000100,,0 ;FLOATING UNDERFLOW PC%NDV==:000040,,0 ;NO DIVIDE DEFINE FLD (VAL,MASK) <.DPB ,<.BP ,>,0>TERMIN DEFINE BIT (N) <1_<35.->>TERMIN DEFINE POINT SIZE=7,ADDR=0,COUNT=0 RADIX 8+2 ..X1==SIZE ..X2==COUNT RADIX 8 ..XX==<..X2-1>/<36./..X1> ..X2==..X2-..XX*<36./..X1> <<<36.-<..X1*..X2>>_30.>+<..X1_24.>++..X1> TERMIN DEFINE ERNOP ERJMP .+1 TERMIN DEFINE ERSKP ERJMP .+2 TERMIN ABSKP==:TRNA ;MOVX - LOAD AC WITH CONSTANT DEFINE MOVX AC,#MSK IFE <-1,,0>&MSK,[MOVEI AC,MSK] .ELSE [IFE <0,,-1>&MSK,[MOVSI AC,(MSK)] .ELSE [IFE <<-1,,0>&MSK>-<-1,,0>,[HRROI AC,MSK] .ELSE [IFE <<0,,-1>&MSK>-<0,,-1>,[HRLOI AC,(MSK&.LHALF)] .ELSE [MOVE AC,[MSK]]]]] TERMIN ;TX - TEST MASK IRP OP,,[N,NA,OE,ON,OA,ZE,ZN,ZA,CE,CN,CA] DEFINE TX!OP AC,#MSK IFE <-1,,0>&MSK,[TR!OP AC,MSK] .ELSE [IFE <0,,-1>&MSK,[TL!OP AC,(MSK)] .ELSE [TD!OP AC,[MSK]]] TERMIN TERMIN IRP OP,,[N,E] DEFINE TXN!OP AC,#MSK IFE <-1,,0>&MSK,[TRN!OP AC,MSK] .ELSE [IFE <0,,-1>&MSK,[TLN!OP AC,(MSK)] .ELSE [IFE MSK+1,[CAI!OP AC,0] .ELSE [TDN!OP AC,[MSK]]]] TERMIN TERMIN ..TXZ==ANDI ..TXO==ORCMI ..TXC==EQVI IRP OP,,[Z,O,C] DEFINE TX!OP AC,#MSK IFE <-1,,0>&MSK,[TR!OP AC,MSK] .ELSE [IFE <0,,-1>&MSK,[TL!OP AC,(MSK)] .ELSE [IFE <<-1,,0>&MSK>-<-1,,0>,[..TX!OP AC,-1#MSK] .ELSE [TD!OP AC,[MSK]]]] TERMIN TERMIN EQUALS IORX,TXO EQUALS XORX,TXC DEFINE ANDX AC,#MSK TXZ AC,-1#MSK TERMIN SUBTTL JX -- JUMP ON MASK ;JXE -- JUMP IF MASKED BITS ARE EQUAL TO 0 ;JXN -- JUMP IF MASKED BITS ARE NOT EQUAL TO 0 ;JXO -- JUMP IF MASKED BITS ARE ALL ONES ;JXF -- JUMP IF MASKED BITS ARE NOT ALL ONES (FALSE) DEFINE JXE AC,#MSK,?ADR IFE MSK-.MINFI,[JUMPGE AC,ADR] .ELSE [IFE MSK+1,[JUMPE AC,ADR] .ELSE [TXNN AC,MSK JRST ADR]] TERMIN DEFINE JXN AC,#MSK,?ADR IFE MSK-.MINFI,[JUMPL AC,ADR] .ELSE [IFE MSK+1,[JUMPN AC,ADR] .ELSE [TXNE AC,MSK JRST ADR]] TERMIN DEFINE JXO AC,#MSK,?ADR IFE <.LZ MSK,>+<.TZ MSK,>-35.,[JXN AC,MSK,ADR] .ELSE [TXC AC,MSK TXCN AC,MSK JRST ADR] TERMIN DEFINE JXF AC,#MSK,?ADR IFE <.LZ MSK,>+<.TZ MSK,>-35.,[JXE AC,MSK,ADR] .ELSE [TXC AC,MSK TXCE AC,MSK JRST ADR] TERMIN ;LOAD, STOR DEFINE LOAD AC,#MSK,?LOCN IFE MSK+1,[MOVE AC,LOCN] .ELSE [IFE MSK-777777,[HRRZ AC,LOCN] .ELSE [IFE MSK-<-1,,0>,[HLRZ AC,LOCN] .ELSE [LDB AC,[.BP MSK,LOCN]]]] TERMIN DEFINE STOR AC,#MSK,?LOCN IFE MSK+1,[MOVEM AC,LOCN] .ELSE [IFE MSK-777777,[HRRM AC,LOCN] .ELSE [IFE MSK-<-1,,0>,[HRLM AC,LOCN] .ELSE [DPB AC,[.BP MSK,LOCN]]]] TERMIN SUBTTL BLOCK MACROS ;MACROS TO PROVIDE SOME BLOCK HANDLING OF CODE ;DO. - LOOP STRUCTURE, DECLARES TOP OF LOOP ; LOOP. - JUMPS TO TOP OF LOOP ; EXIT. - EXITS LOOP ; TOP. - TAG AT TOP OF LOOP FOR JUMPS, E.G. SOJG T4,TOP. ; ENDLP. - TAG AT END OF LOOP FOR JUMPS, E.G. SOJL T4,ENDLP. DEFINE DO. ..DX TERMIN DEFINE ..DX \%TGE,%SV1,%SV2,%SV3 EQUALS %SV1,TOP. ? EQUALS %SV2,ENDDO. ? EQUALS %SV3,ENDLP. .KILL %SV1 TOP.==. DEFINE ENDDO. %TGE::EQUALS TOP.,%SV1 ? EQUALS ENDDO.,%SV2 ? EQUALS ENDLP.,%SV3 .KILL %TGE TERMIN DEFINE ENDLP. %TGE!!TERMIN TERMIN DEFINE ENDDO. .ERR ENDDO. outside loop TERMIN DEFINE ENDLP. .ERR ENDLP. outside loop TERMIN TOP.==-1 DEFINE OD. ENDDO.!TERMIN DEFINE LOOP. JRST TOP.!TERMIN DEFINE EXIT. JRST ENDLP.!TERMIN ;Conditionals DEFINE IFSKP. ..IX [JRST ] TERMIN DEFINE IFNSK. ABSKP ..IX [JRST ] TERMIN DEFINE IFXN. AC,#MASK IFE 1_35.-MASK,..IX [JUMPGE AC,] .ELSE [IFE MASK+1,..IX [JUMPE AC,] .ELSE [TXNN AC,MASK ..IX [JRST ] ]] TERMIN DEFINE IFXE. AC,#MASK IFE 1_35.-MASK,..IX [JUMPL AC,] .ELSE [IFE MASK+1,..IX [JUMPN AC,] .ELSE [TXNE AC,MASK ..IX [JRST ] ]] TERMIN DEFINE IFJER. ERJMP .+2 ..IX [JRST ] TERMIN DEFINE IFNES. PRINTX /% IFNES. should be changed to IFJER. / IFJER. TERMIN DEFINE IFNJE. ..IX [ERJMP ] TERMIN DEFINE IFESK. PRINTX /% IFESK. should be changed to IFNJE. / IFNJE. TERMIN DEFINE IFE. AC ..IX [JUMPN AC,] TERMIN DEFINE IFN. AC ..IX [JUMPE AC,] TERMIN DEFINE IFG. AC ..IX [JUMPLE AC,] TERMIN DEFINE IFGE. AC ..IX [JUMPL AC,] TERMIN DEFINE IFLE. AC ..IX [JUMPG AC,] TERMIN DEFINE IFL. AC ..IX [JUMPGE AC,] TERMIN DEFINE ..IX OP,\%TAG,%SV1,%SV2 OP!%TAG EQUALS %SV1,..TG ? EQUALS %SV2,ENDIF. DEFINE ..TG LBL %TAG!!LBL!TERMIN DEFINE ENDIF. ..TG [::] .KILL ..TG EQUALS ..TG,%SV1 ? EQUALS ENDIF.,%SV2 TERMIN TERMIN DEFINE ELSE. ..EX TERMIN DEFINE ..EX \%TAG JRST %TAG ..TG [::] DEFINE ..TG LBL %TAG!!LBL!TERMIN TERMIN DEFINE ..TG LBL .ERR Conditional construct outside a conditional TERMIN DEFINE ENDIF. .ERR ENDIF. outside a conditional TERMIN ;GENERAL CASES WITHIN CONDITIONALS DEFINE ANSKP. JRST ..TG TERMIN DEFINE ANNSK. ABSKP JRST ..TG TERMIN DEFINE ANJER. ERJMP .+2 JRST ..TG TERMIN DEFINE ANNJE. ERJMP ..TG TERMIN DEFINE ANDXN. AC,#MASK IFE 1_35.-MASK,JUMPGE AC,..TG .ELSE [IFE MASK+1,JUMPE AC,..TG .ELSE [TXNN AC,MASK JRST ..TG ]] TERMIN DEFINE ANDXE. AC,#MASK IFE 1_35.-MASK,JUMPL AC,..TG .ELSE [IFE MASK+1,JUMPN AC,..TG .ELSE [TXNE AC,MASK JRST ..TG ]] TERMIN DEFINE ANDE. AC JUMPN AC,..TG TERMIN DEFINE ANDN. AC JUMPE AC,..TG TERMIN DEFINE ANDG. AC JUMPLE AC,..TG TERMIN DEFINE ANDGE. AC JUMPL AC,..TG TERMIN DEFINE ANDLE. AC JUMPG AC,..TG TERMIN DEFINE ANDL. AC JUMPGE AC,..TG TERMIN ;MACRO TO PRINT MESSAGE ON TERMINAL DEFINE TMSG &MSG HRROI 1,[ASCIZ MSG] PSOUT TERMIN ;MACRO TO OUTPUT MESSAGE TO FILE ; ASSUMES JFN ALREADY IN .AC1 DEFINE FMSG &MSG HRROI 2,[ASCIZ MSG] MOVEI 3,0 SOUT TERMIN DEFINE EMSG &MSG HRROI 1,[ASCIZ MSG] ESOUT TERMIN ; SAVEAC [A,B,C] ; Supports +1/+2 returns. ; Unlike macro version, supports arbitrary locations (not just AC's) ; and doesn't clobber AC16. DEFINE SAVEAC ACS IRP AC,,[ACS] PUSH P,AC ..XX==.IRPCNT TERMIN .SAVX1 ..XX+1,[ACS] TERMIN EQUALS SAVE.,SAVEAC ;Not in MACRO version... DEFINE .SAVX1 #N#,ACS PUSH P,[[ABSKP AOS -N(P) .SAVX2 [ACS] POPJ P, ]] TERMIN DEFINE .SAVX2 ACS IRP AC,REST,[ACS] .SAVX2 [REST] POP P,AC .ISTOP TERMIN TERMIN DEFINE BRMSK. INI0=0,INI1=0,INI2=0,INI3=0,ALLOW,DISALW ..X0==INI0 ..X1==INI1 ..X2==INI2 ..X3==INI3 IRPC CH,,[ALLOW] ..BRK 0,<.ASCVL /CH>/32.,35.-<.ASCVL /CH>&31. TERMIN IRPC CH,,[DISALW] ..BRK 1,<.ASCVL /CH>/32.,35.-<.ASCVL /CH>&31. TERMIN ..X0 ? ..X1 ? ..X2 ? ..X3 TERMIN DEFINE ..BRK VAL,#WD,BT ..X!WD==.DPB VAL,BT!0100,..X!WD TERMIN DEFINE FLDDB. ?FNC,FLAGS=0,DATA=0,&HLPM,DEFM,?NXT=0 FLDBK.(FNC,FLAGS,DATA,HLPM,DEFM,,NXT)TERMIN DEFINE FLDBK. ?FNC,FLAGS=0,DATA=0,&HLPM,DEFM,?BRK,NXT=0 ..XX==0 IFSN [HLPM][] ..XX==..XX\CM%HPP IFSN [DEFM][] ..XX==..XX\CM%DPP IFSN [BRK][] ..XX==..XX\CM%BRK <_27.>\\..XX\<0,,NXT> DATA IFSN [HLPM][][440700,,[ASCIZ HLPM]] .ELSE [IFSN [DEFM!BRK][][0]] IFSN [DEFM][][440700,,[ASCIZ DEFM]] .ELSE [IFSN [BRK][][0]] IFSN [BRK][][BRK] TERMIN ;.YSTGW ;Allow storage words again IFN $$JSER,[ ;Optional Jsys error support IFNDEF P,P==:17 ;MACRO TO PRINT MESSAGE FOR LAST ERROR, RETURNS +1 DEFINE PERSTR &MSG IFSN [MSG][]TMSG MSG PUSHJ P,JSMSG0 TERMIN ;PRINT ERROR MESSAGE IF JSYS FAILS DEFINE ERMSG *TEXT ERJMP [TMSG ż!TEXTŠ JSHLT] TERMIN ;JSYS ERROR HANDLER ; CALL JSERR0 ; RETURNS +1: ALWAYS, CAN BE USED IN +1 RETURN OF JSYS'S JSERR0: MOVEI 1,.PRIIN CFIBF ;CLEAR TYPAHEAD MOVEI 1,.PRIOU DOBE ;WAIT FOR PREVIOUS OUTPUT TO FINISH TMSG " ?JSYS error: " JSMSG0: MOVEI 1,.PRIOU HRLOI 2,.FHSLF ;SAY THIS FORK ,, LAST ERROR SETZ 3, ERSTR NOP NOP TMSG " " POPJ P, JSERR=: ;Prints last jsys error, returns +1 EJSERR=: ;FATAL JSYS ERROR - PRINT MESSAGE AND HALT ; CALL JSHLT0 ; RETURNS: NEVER JSHLT0: JSERR ;PRINT THE MSG JSHLT1: HALTF TMSG "?Program cannot continue " JRST JSHLT1 ;HALT AGAIN IF CONTINUED .KILL JSHLT1 JSHLT=: ;Prints last jsys error, halts EJSHLT=: ];$$JSER IFN $$STK,[ ;Optional stack related support SUBTTL STKVAR - STACK VARIABLE FACILITY IFNDEF P,P==:17 CALL=: RET=: CALLRET==: ;; STKVAR [AA,BB,[QQ,5],ZZ] ;; ENDSV. (end of scope, flush names) ;; Supports return and skip return. ;; Unlike the macro version, AC16 is NOT clobbered. ;; Unlike the macro version, variables defined in left-to-right order ;; (so above, DMOVEM 1,AA will put 1 in AA and 2 in BB) DEFINE STKVAR ARGS ..STKN==1+IRP VAR,,[ARGS] <.STKV1(VAR)>+TERMIN ..STKQ==..STKN IRP VAR,,[ARGS] .STKV2 ..STKQ,VAR TERMIN DEFINE ENDSV. IRP ARG,,[ARGS] .ENSV1(ARG) TERMIN .KILL ..STKN,..STKQ TERMIN ADJSP P,..STKN PUSHJ P,.STKST TERMIN DEFINE .STKV1 ?VAR,SIZE=1 SIZE!TERMIN DEFINE .STKV2 #LOC#,VAR,SIZE=1 DEFINE VAR -LOC(P)TERMIN ..STKQ==LOC-SIZE TERMIN DEFINE .ENSV1 (VAR) EXPUNGE VAR TERMIN .STKST: EXCH 16,(P) ;Get return address, save AC16 MOVEM 16,-1(P) ;Save ret address MOVN 16,-2(16) ;Fetch the word with ..stkn in it, negated MOVEI 16,(16) ;Clear lhs to allow indirecting in .STKRT EXCH 16,-1(P) ;Save it, get return address PUSH P,16 ;Set up for popj HRRI 16,.STKRT ;Fake return address for caller EXCH 16,-1(P) ;set it up, restoring AC16 POPJ P, .STKRT: JRST STKRT0 ;Normal return ADJSP P,@(P) ;Skip return RSKP: AOS (P) R: POPJ P, STKRT0: ADJSP P,@(P) POPJ P, .KILL STKRT0 RETSKP=: ];$$STK