~~ I>~~~~~~~~ I>a ~~ q ; ; GENERAL SUBROUTINE UTILITY PACKAGE FOR DOS. ; .TITL GSUB .NREL .ENT SAV ;SAVE REGISTERS .ENT RTN ;RESTORE REGISTERS .ENT MVBYT ;MOVE BYTES .ENT LDCHR ;LOAD A BYTE .ENT STCHR ;STORE A BYTE .ENT XOR ;EXCLUSIVE OR .ENT OR  ;INCLUSIVE OR .ENT CLEAR ;CLEAR CORE .ENT MVWD ;MOVE WORDS .ENT CMPWD ;COMPARE WORDS .ENT DIVD,DIVI ;DIVIDE .ENT SETFL ;SET BITS ON .ENT RSTFL ;SET BITS OFF .ENT IDCB,FIDCB .ENT SDIRR ;SEARCH DIRECTORY RING .EXTN DIRR ;DIRECTORY RING POINTER ; ; SUBROUTINE LINKAGE. ; SAV: STA 3,RLOC ;SAVE RETURN IN TEMP. LOCATION LDA 3,CSP ;CURRENT STACK POINTER LDA 3,NSP,3 ;NEXT STACK POINTER MOVL# 3,3,SZC JMP STOUF STA 3,CSP ;PUSH STACK FRAME STA 0,OAC0,3 ;SAVE AC'S STA 1,OAC1,3 STA 2,OAC2,3 JMP@ RLOC ;ENTER SUBROUTINE RTN: LDA 3,CSP ;CURRENT STACK POINTER LDA 0,OAC0,3 ;LOAD AC'S LDA 1,OAC1,3 LDA 2,OAC2,3 LDA 3,OSP,3 ;POP STACK POINTER STA 3,CSP JMP@ RTLOC,3 ;RETURN TO CALLER STOUF: JSR@ .PNIC PNCSO ; ; MOVE BYTES AROUND. ; ; ; AC0: FROM BYTE POINTER ; AC1: TO BYTE POINTER ; AC2: BYTE COUNT ; JSR MVBYT ; MVBYT: STA@ 3,CSP ;SAVE RETURN SAVE  ;SAVE REGISTERS MOVR# 0,0,SZC JMP MB  ;MOVE BYTES MOVR# 1,1,SZC JMP MB MOVR# 2,2,SNC JMP MW  ;MOVE WORDS MB: STA 0,TMP,3 STA 1,TMP+1,3 MOV 0,1 NEG 2,2,SNR RTRN MVLP: JSR LDBT ;LOAD A BYTE ISZ TMP,3 ;BUMP FROM POINTER LDA 1,TMP+1,3 ;TO POINTER JSR STBT ;STORE BYTE ISZ TMP+1,3 LDA 1,TMP,3 INC 2,2,SZR ;DONE ? JMP MVLP ;LOOP BACK RTRN  ;RETURN MW: MOVZR 0,0 MOVZR 1,1 MOVZR 2,2 JMP MVWD+2 ; ; BYTE ROUTINES. ; ; AC1: BYTE POINTER ; AC0: BYTE ;(CARRY IS DESTROYED) ; LDCHR: LDBT: STA 3,RLOC ;SAVE RETURN MOVZR 1,3 ;MAKE CORE ADDRESS FROM BYTE POINTER LDA 1,C377 ;MASK LDA 0,0,3 ;BYTE WORD MOV# 0,0,SNC MOVS 0,0 ;SWAP WORD AND 1,0  ;MASK TO GET BYTE MOVL 3,1 ;RESTIRE AC0 LDA 3,CSP ;GET CSP JMP@ RLOC ;RETURN C377: 377 STCHR: STBT: STA 3,RLOC ;SAVE RETURN LDA 3,CSP STA 2,AC2,3 STA 0,AC0,3 LDA 2,C377 ;HALF WORD MASK AND 2,0  ;MASK INPUT TO HALF WORD MOVZR 1,3,SZC ;MAKE CORE ADDRESS MOVS 2,2 ;SWAP LDA 1,0,3 ;BYTE WORD AND 2,1,SNC MOVS 0,0 ADD 1,0  ;ADD IN BYTE STA 0,0,3 ;PUT BACK MOVL 3,1 ;RESTORE AC0 LDA 3,CSP LDA 2,AC2,3 ;RESTORE AC0,AC2 LDA 0,AC0,3 JMP@ RLOC  ; ; AC1 = AC0.XOR.AC1 ; XOR: STA@ 3,CSP ;SAVE REUTNR MOV 1,3  ;COPY AC1 ANDZL 0,3 ;CARRY BITS ADD 0,1  ;ADD SUB 3,1  ;SUBTRACT CARRYS LDA 3,CSP JMP@ 0,3 ; ; AC1 = AC0.OR.AC1 ; OR: STA@ 3,CSP STA 0,RLOC ;SAVE AC0 COM 0,0 AND 0,1 ADC 0,1 LDA 3,CSP LDA 0,RLOC JMP@ 0,3 ;RETURN ; ; CLEAR CORE ; ; AC0: COUNT ; AC2: ADDRESS ; JSR CLEAR ; CLEAR: STA@ 3,CSP ;SAVE RETURN SAVE  ;SAVE REGISTERS NEG 0,0,SNR RTRN  ;NONE SUB 1,1  ;CLEAR STA 1,0,2 ;STORE ZERO INC 2,2 INC 0,0,SZR JMP .-3 RTRN ; ; MOVE WORDS ; ; AC0: FROM ADDRESS ; AC1: TO ADDRESS ; AC2: COUNT ; JSR MVWD ; MVWD: STA@ 3,CSP ;SAVE RETURN SAVE  ;SAVE REGISTERS MOV 0,3  ;FROM NEG 2,0,SNR ;COUNT RTRN  ;NONE MOV 1,2  ;TO ADDRESS LDA 1,0,3 STA 1,0,2 INC 2,2 INC 3,3 INC 0,0,SZR ;DONE ? JMP .-5 RTRN ; ; COMPARE WORDS ; ; AC0: ADDRESS 1 ; AC1: ADDRESS 2 ; AC2: WORD COUNT ; JSR CMPWD ; -SUCESS RETURN ; -FAIL RETURN ; CMPWD: STA@ 3,CSP ;SAVE RETURN SAVE  ;SAVE REGISTERS MOV 0,3 NEG 2,0,SNR RTRN  ;NONE STA@ 0,CSP ;COUNT TO STACK TEMP. MOV 1,2 CMPLP: LDA 0,0,2 LDA 1,0,3 SUB# 0,1,SZR JMP NOTEQ ;NOT THE SAME INC 2,2 INC 3,3 ISZ@ CSP ;DONE JMP CMPLP RTRN NOTEQ: LDA 3,CSP ISZ ORTN,3 ;TAKE FAIL RETURN RTRN ; ; DIVIDE R0,,R1 BY R2. ; QUOTIENT IN R1 AND REMAINDER IN R0. ; SET CARRY ON OVERFLOW. ; DIVI: SUB 0,0  ;INTEGER DIVIDE ENTRY POINT DIVD: STA@ 3,CSP ;SAVE RETURN LDA 3,MC20 MOVZL 1,1 D0: MOVL 0,0 SUB# 2,0,SZC SUB 2,0 MOVL 1,1 INC 3,3,SZR JMP D0 LDA 3,CSP JMP@ 0,3 MC20: -20 ; ; SET/RESET BITS ; AC0: WORD ; AC1: MASK ; RSTFL: MOVZ 0,0,SKP SETFL: MOVO 0,0 STA@ 3,CSP COM 1,3 AND 3,0,SZC ADC 3,0 LDA 3,CSP JMP@ 0,3 ; INITIALIZE A DCB ; INPUT: AC0 - FIRST DISK ADDRESS ;  AC2 - DCB ADDRESS IDCB: STA 3,@CSP ; SAVE RETURN ADDRESS SAVE   ; AND REGISTERS STA 0,DCBNA,2 ; SET NEXT ADDRESS AND STA 0,DCBFA,2 ; FIRST ADDRESS TO START ADC 0,0 STA 0,DCBCB,2 ; CURRENT BLOCK INC 0,0 STA 0,DCBLA,2 ;CLEAR LAST ADDRESS STA 0,DCBCA,2 ;CLEAR CURRNT ADDRESS LDA 0,DCBST,2 LDA 1,MSKI AND 1,0 STA 0,DCBST,2 ;STATUS CLEARED RTRN MSKI: STINI+STCMK ; ; FULL INIT FOR DCB ; AC1: DCB ADDRESS OF SYS.DR ; FIDCB: STA@ 3,CSP SAVE MOV 1,3 LDA 1,DCBDC,3 ;DCT ADDRESS STA 1,DCBDC,2 LDA 1,DCBUN,3 ;UNIT NUMBER STA 1,DCBUN,2 LDA 1,DCBDR,3 STA 1,DCBDR,2 JMP IDCB+2 ; SEARCH THE DIRECTORY RING ; INPUT: NAME KEY - AC0 ;  UNIT NUMBER - AC1 ; CALLING SEQUENCE: ; JSR SDIRR ; ^FAIL RETURN (AC1 DESTROYED) ; ^SUCCESS RETURN - PTR. TO DIRECTORY DCB IN AC1 SDIRR: STA 3,@CSP  ; SAVE RETURN ADDRESS SAVE   ; AND ACS LDA 2,.DIRR  ; GET FIRST POINTER SDIR1: STA 2,OAC1,3 ; ASSUME THIS IS IT LDA 3,SFKEY,2 ; KEY WORD SUBZ 0,3,SZR  ; MATCH? JMP NO  ; NO LDA 3,DCBUN,2 ; YES, CARRY IS 1 MOVL# 3,3,SNC  ; 1B0 MATCHES ALL SUBO 1,3,SNR  ; NO, DOES IT MATCH? ADDR 1,1,SKP  ; YES, 1B0 REMAINS THE SAME JMP NO  ; NO STA 1,DCBUN,2 ; NEW UNIT NUMBER LDA 3,CSP ISZ ORTN,3  ; SUCCESS RETURN RTRN NO: LDA 3,CSP LDA 2,OAC1,3 ; GET CURRENT POINTER LDA 2,SFNX,2 ; POINTER TO NEXT ENTRY COM# 2,2,SNR  ; END OF CHAIN? RTRN   ; YES, FAIL JMP SDIR1  ; NO, KEEPING SEARCHING .DIRR: DIRR .END O *U*U*U*U+c