; autoexecute~o*hnea ;~x!ins MP/prm="ti:+FILE/nl/ni" ;+ ; File i/o macros - does csi parsing and block i/o. ; The general usage: ; CSI ;data space ; fdblabel: ; FDB lun B/R [block] ;data space ; ;block=block io buf ; ; FILE string-address string-len ;instruction space ; OPEN #fdblabel wrt/rd/upd/mod ;instruction space ; bcc ok ; note: use oldfile.mac for production version - this one's for speed ;- $MACRO CSI .MCALL CSI$ CSI$ .EVEN CSIBLK:: .BLKB C.SIZE $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO FILE ADDR-OF-STRING LEN-STR ;I%DOUT <;FILE addr-of-string len-str> ?? 4 ; .MCALL CSI$1,CSI$2 ; I%DOUT <;CSI$1 #CSIBLK,#@1,#@2> MOV #CSIBLK,R0 MOV #@1,C.CMLD+2(R0) MOV #@2,C.CMLD(R0) JSR PC,.CSI1 BCS #@4 ; I%DOUT <;CSI$2 ,OUTPUT> MOVB #CS.OUT,(R0) JSR PC,.CSI2 #@4=. $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO FDB lun,B/R,[block] ;I%DOUT <;FDB lun B/R,[block]> .mcall fdbdf$,cbyte$,cword$,fdoff$ fdoff$ DEF$L fdbdf$ ; I%DOUT <;fdop$a #@1,csiblk+c.dsds> CBYTE$ <#@1>,F.LUN CWORD$ ,F.DSPT I%IDN <#@2> < fdat$a r.fix,,512.> I%IDN <#@2> < CBYTE$ ,F.RACC> I%IDN <#@2> < fdat$a r.var,fd.cr> I%NB <#@3> <** <> < .mcall fdbk$a> < fdbk$a #@3,512.>> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO fdat$a just a subset of this, only what we need ; .MACRO FDAT$A RTYP,RATT,RSIZ,CNTG,ALOC I%NB <#@1> < CBYTE$ <#@1>,F.RTYP> I%NB <#@2> < CBYTE$ <#@2>,F.RATT> I%NB <#@3> < CWORD$ <#@3>,F.RSIZ> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Original, the above is much faster thru macro-11 ;$MACRO FDB lun,B/R,[block] ;I%DOUT <;FDB lun B/R,[block]> ; .mcall fdop$a,fdat$a,fdbdf$,fdrc$a,fdbk$a ; fdbdf$ ; fdop$a #@1,csiblk+c.dsds ;I%IDN <#@2> < fdat$a r.fix,,512.> ;I%IDN <#@2> < fdrc$a fd.rwm> ;I%IDN <#@2> < fdat$a r.var,fd.cr> ;I%NB <#@3> < fdbk$a #@3,512.> ;$ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO OPEN fdb RD/WRT/UPD/MOD ;I%DOUT <;OPEN fdb rd/wrt/upd/mod> ; .mcall open$ ; I%DOUT <;open$ #@1,#fo.#@2> MOV #@1,R0 MOVB #fo.#@2,F.FACC(R0) JSR PC,.OPEN $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; simple block i/o always waits, uses ef 20. $MACRO READ-BLOCK fdb block# input-buffer ; .mcall read$,wait$ ;READ$ #@1,#@3,#512.,#@2,#20. ;WAIT$ ; I%DOUT <;READ$ #@1,#@3,#512.,#@2,#20.> MOV #@1,R0 MOV #@3,F.BKDS+2(R0) MOV #512.,F.BKDS(R0) MOV #@2,-(SP) MOV @(SP),F.BKVB(R0) ADD #2,(SP) MOV @(SP)+,F.BKVB+2(R0) MOVB #20.,F.BKEF(R0) JSR PC,.READ IF CC ; I%DOUT <;WAIT$> JSR PC,.WAIT FI $ENDM ;+ ; These macros are used when writing privel'd tasks (or ones which ; simply must be small - can't afford the overhead of the C library). ; ; prints buf-addr p1 p2 .. ;like sprintf in c ; type buf-addr [car-control] ;qiow to lun5 buffer ; len buf-addr ;sets r0=len of str ; tty ;just dump it on ti: ; ; All assume that r0 and r1 are available to be ; destroyed without saving. (all c callable stuff is like this) ; car-control defaults to #40 ;- ; $MACRO LEN string ?? 2 mov #@1,r0 #@2=. tstb (r0)+ bne #@2 sub #@1,r0 dec r0 $ENDM ; $MACRO TYPE string-addr types asciz string LEN #@1 I%IN <#@2> <> <> ?+ 2,,28 ;qiow$s #io.wvb,#5,#5,,,,<#BUF,r0,#40> THIS IS TOO DAMN SLOW CLR -(SP) CLR -(SP) CLR -(SP) MOV #@2,-(SP) MOV r0,-(SP) MOV #@1,-(SP) CLR -(SP) CLR -(SP) CLR -(SP) MOVB #5,(SP) MOV #5,-(SP) MOV #io.wvb,-(SP) MOV (PC)+,-(SP) .BYTE 3,12. EMT ^O<377> $ENDM $MACRO TTY string-literal [control] ?? 5,4 br #@4 #@5=. .asciz _#@1_ .even #@4=. TYPE ##@5 #@2 $ENDM ; $MACRO MOVEB from to num I%DF <#@1> mov #@2,r1 mov #@3,r2 ?? 5 #@5=. movb (r0)+,(r1)+ sob r2,#@5 $ENDM / s%sw 32 ;old style program .title Cd .psect Cd .ident /18sep/ PROGRAM Cd ;Change directory (with password) .mcall fsrsz$,qiow$,dir$ temp: .blkb 100. account:.word passwd: .word uic1: .word grp: .byte 0,0,0,0 usr: .byte 0,0,0,0 pass: .byte 40,40,40,40,40,40,0 passc: .byte 40,40,40,40,40,40,0 nme: .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 acc: .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .even getpas: qiow$ io.rne,5,20.,,ios,, ios: .word 0,0 CSI ;init acnt: FDB 3 B ;lun 3 reads the acnt file block: .word 0,1 ;virt block # buf: .blkb 512. name: .ascii /[0,0]rsx11.sys/ namel= .-name .even AUTO group user FUNCTION main[argc,argv] clr account clr passwd IF argc(r5) LE #1 TTY RET #4 FI add #2,argv(r5) mov @argv(r5),account IF argc(r5) GT #2 add #2,argv(r5) mov @argv(r5),passwd let r0 = sPRINTf[#passc,"%-6s",passwd ] ELSE TTY #'$ dir$ #getpas mov #passc,r1 LOOP for r0 = #1 TO ios+2 IFB (r1) HIS #'a AND (r1) LOS #'z bicb #40,(r1) FI inc r1 NEXT r0 FI let r0 = sPRINTf[#acc, "%-14s",account] ; PRINTF #buf #acc #passc argc(r5) FILE #name #namel ;parse name OPEN #acnt rd ;open it for read block i/o IF CS PRINTF "Can't open acount file %o" acnt+f.err RET #4 FI DO FOREVER READ-BLOCK #acnt #block #buf IF CS jmp done FI inc block+2 ; PRINTF #temp acnt+f.err #buf block+2 LOOP for r3 = #buf THRU #buf+1000-1 STEP #200 MOVEB R3,#grp,#3 MOVEB R0,#usr,#3 MOVEB R0,#pass,#6 MOVEB R0,#nme,#14. IFB grp LO #'0 OR grp HI #'9 jmp done FI LET r2 = cmpstr[#nme,#acc] IF r2 NE #0 ; PRINTF #buf <[%s,%s] password=%s name=%s r3=%d> #grp #usr #pass #nme r2 jmp found FI NEXT r3 OD done: PRINTF "_<15>_Unknown account %s" account RET #1 found: LET r3 = cmpstr[#passc,#pass] IF r3 = #0 TTY <_<15>_Invalid password> RET #4 FI LET R0 = btoi[#grp,#3,&group,#8.] LET R0 = btoi[#usr,#3,&user ,#8.] IF argc(r5) LE #3 PRINTF "_<15>_-_<76>_ [%o,%o]" group(r5) user(r5) FI movb group(r5),uic1+1 movb user(r5),uic1 call change RET #1 change: ; emt 376 ;switch to system state ; .word 10$ ;return here mov $tktcb,r0 ;get tcb address mov t.ucb(r0),r0 ;get ti ucb 5$: cmp r0,u.red(r0) ;follow redirect chain beq 7$ ;if it is redirected mov u.red(r0),r0 br 5$ 7$: mov uic1,u.luic(r0) ;make it what we found mov uic1,u.uic(r0) ;make this too rts pc ;10$: rts pc ;return fsrsz$ 1 .end