mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-07 11:17:06 +00:00
1758 lines
52 KiB
Plaintext
1758 lines
52 KiB
Plaintext
TITLE DSKIO - Disk I/O routines for editor AMIS -*-Macro-*-
|
||
|
||
SEARCH UUOSYM,MACTEN
|
||
|
||
t0==0
|
||
t1==1
|
||
t2==2
|
||
t3==3
|
||
t4==4
|
||
t5==5
|
||
t6==6
|
||
t7==7
|
||
t8==8
|
||
p==17
|
||
|
||
dsk==2 ;Channel for disk I/O.
|
||
|
||
dsksize==^D640 ;Size of disk block, in chars.
|
||
|
||
strsize==^D40
|
||
|
||
opdef call[ pushj p,]
|
||
|
||
define bugerr(msg),<
|
||
jrst[ movei 2,[
|
||
asciz "'msg'"]
|
||
pushj p,bug##]
|
||
>;End of bugerr macro.
|
||
|
||
define DBP(ac,%lbl),< ;Decrement Byte Pointer
|
||
caml ac,[35b5]
|
||
jrst[ sub ac,[340000,,1]
|
||
jrst %lbl]
|
||
add ac,[7b5]
|
||
%lbl:
|
||
>;End of DBP macro
|
||
|
||
TWOSEG 600000 ;make a shareable highsegment
|
||
|
||
|
||
;=============================================================================
|
||
;PROCEDURE dskinit;
|
||
;
|
||
;(* Initialises the DSKIO-module *)
|
||
|
||
dskini::SETZM ds.opn ; no files open yet
|
||
SETZM proflg ; no funny renameing done yet
|
||
SETZM notdir ; no device checks yet
|
||
SETZM tcrflg ; we haven't fiddled
|
||
SETZM tcrdev ; with TMPCORE yet
|
||
setzm prsarg ; No parameters from TMP:EDS yet.
|
||
|
||
; Make a temporary filename based on the jobnumber.
|
||
|
||
PJOB t1, ; get our job number
|
||
IDIVI t1,^D100 ; I don't really want to explain..
|
||
IDIVI t2,^D10 ; ..this code sequence...
|
||
ROT t2,-6
|
||
ROTC t1,-6
|
||
TLO t2,'000'(t3)
|
||
TRO t2,'AMI' ; ...
|
||
MOVEM t2,tmpnam ; store it
|
||
POPJ P,
|
||
|
||
|
||
|
||
;=============================================================================
|
||
;PROCEDURE blankstring (VAR txt: STRING);
|
||
;
|
||
;(* Blanks the string 'txt' *)
|
||
|
||
txt==2
|
||
|
||
blanks: push p,t1 ;Save T1.
|
||
move t1,[BYTE (7) " "," "," "," "," "]
|
||
movem t1,(txt) ;Blank first word
|
||
HRLZ t1,txt ;get pointer to string
|
||
HRRI t1,1(txt)
|
||
BLT t1,strsiz/5-1(txt) ; blank the string
|
||
POP p,t1
|
||
POPJ P,
|
||
|
||
|
||
;==============================================================================
|
||
; This routine is called upon initialization to rescan the command line.
|
||
|
||
rrspar::setzm rsccnt ;No chars rescanned yet.
|
||
rescan 1 ;Try rescan the command line.
|
||
skipa ; OK, start parsing.
|
||
popj p, ; Not OK, just return.
|
||
setz t4, ;Clear word.
|
||
move t5,[point 6,t4] ;Load byte pointer.
|
||
movei t6,6 ;Load char count.
|
||
rrs.2: pushj p,rrsgch ;Try get a character.
|
||
popj p, ; No more, give up.
|
||
caie t1," " ;Loop until some non-blank char.
|
||
cain t1,.chtab
|
||
jrst rrs.2
|
||
rrs.3: cail t1,"0" ;While char is alphanumeric, collect word.
|
||
caile t1,"9"
|
||
cail t1,"A"
|
||
caile t1,"Z"
|
||
cail t1,"a"
|
||
caile t1,"z"
|
||
jrst rrs.5
|
||
sojl t6,rrs.4
|
||
cail t1,"a"
|
||
subi t1,40
|
||
subi t1,40
|
||
idpb t1,t5
|
||
rrs.4: pushj p,rrsgch ;Get next char of word.
|
||
tdza t1,t1 ; No more, flag in T1 and skip.
|
||
jrst rrs.3
|
||
rrs.5: came t4,['A '] ;Do we know this initial command?
|
||
camn t4,['AM ']
|
||
jrst rrs.8
|
||
came t4,['AMI ']
|
||
camn t4,['AMIS ']
|
||
jrst rrs.8
|
||
jumpe t1,.popj ;No, quit if this was eol.
|
||
rrs.6: caie t1,"!" ;Not eol, scan for comment start or "-".
|
||
cain t1,";"
|
||
jrst read6c
|
||
cain t1,"-"
|
||
jrst rrs.7
|
||
pushj p,rrsgch
|
||
popj p,
|
||
jrst rrs.6
|
||
|
||
read6c: pushj p,rrsgch ;We found a command, skip to eol.
|
||
popj p,
|
||
jrst read6c
|
||
|
||
rrs.7: pushj p,rrsgch ;Found a hyphen, eat it and use rest.
|
||
popj p,
|
||
rrs.8: setom offset## ;'AMIS' started command, flag it.
|
||
jumpe t1,.popj ;Allow eol after command.
|
||
caie t1," " ;Start of arguments -- skip leading blanks.
|
||
cain t1,.chtab
|
||
jrst rrs.7
|
||
move t5,[point 7,tcrbuf+1]
|
||
rrs.9: idpb t1,t5
|
||
aos rsccnt
|
||
pushj p,rrsgch
|
||
skipa t1,[ascii "AMIS "]
|
||
jrst rrs.9
|
||
movem t1,tcrbuf+0 ;Store initial part of TMP:EDS
|
||
movei t1,^D13 ;Terminate file with CRLF.
|
||
idpb t1,t5
|
||
movei t1,^D10
|
||
idpb t1,t5
|
||
setzm offset## ;No need to read the file we just wrote...
|
||
movsi t0,'EDS' ;Load tempcore file name.
|
||
move t1,rsccnt ;Get count of bytes rescanned.
|
||
addi t1,5+4+2 ;Add one word, two chars and adjustment.
|
||
idivi t1,5 ;Compute number of words.
|
||
movn t1,t1 ;Negate.
|
||
hrl t1,t1 ;Put in left half.
|
||
hrri t1,tcrbuf-1 ;Make IOWD to buffer.
|
||
movx t2,<.tcrwf,,t0>
|
||
tmpcor t2, ;Write TMP:EDS
|
||
jfcl ; Oh well...
|
||
popj p, ;Done with all this junk.
|
||
|
||
rrsgch: inchwl t1 ;Get a character.
|
||
movei t0,1B35 ;Load a bit.
|
||
lsh t0,(t1) ;Shift according to character.
|
||
trne t0,^B10000000000001;Ignore CR and NULL.
|
||
jrst rrsgch
|
||
tdnn t0,[^B1100000101000001110010001000]
|
||
aos (p)
|
||
popj p,
|
||
|
||
;=============================================================================
|
||
;function GetParameters: boolean;
|
||
;
|
||
;(* Reads TMP:EDS and prepares for special things. *)
|
||
|
||
getpar::skipe offset## ;Check runoffset.
|
||
jrst getpa0 ; Set, look for and read TMP:EDS
|
||
hrlz t1,rsccnt ;Zero, check what we rescanned.
|
||
jumpe t1,retf ;Nothing, tell MAIN the fact.
|
||
hrri t1,tcrbuf+1 ;Something, make len,,addr.
|
||
movem t1,prsarg ;Set up for DSKOPEN
|
||
jrst rett ;Return true.
|
||
|
||
getpa0: MOVSI t3,'EDS' ; read from TMP:EDS
|
||
HRLZI t4,-50 ; negative count of words in buffer
|
||
HRRI t4,tcrbuf-1 ; addr-1 to buffer
|
||
MOVE t1,[.TCRRF,,t3]
|
||
TMPCOR t1,
|
||
jrst retf ; No tmp:eds maybe.
|
||
MOVE t3,[POINT 7,tcrbuf]
|
||
IMULI t1,5
|
||
;come here to find first blank or <TAB>
|
||
getpa1: jumple t1,retf ;Abort now if no chars left.
|
||
ILDB t4,t3
|
||
CAIE t4," "
|
||
CAIN t4,.CHTAB
|
||
SOJA t1,getpa2
|
||
soja t1,getpa1
|
||
;now scan past all blanks or <TAB>s
|
||
getpa2: jumple t1,retf
|
||
ILDB t4,t3
|
||
CAIE t4,.CHTAB
|
||
CAIN t4," "
|
||
SOJA t1,getpa2
|
||
;come here to shift the string to the left
|
||
move t5,[POINT 7,tcrbuf]
|
||
tdza t6,t6
|
||
getpa3: ildb t4,t3
|
||
caie t4,.chcnv ;^V?
|
||
cail t4," " ; No, other control char?
|
||
cail t4,177 ; or rubout?
|
||
jrst quit ; Terminator.
|
||
idpb t4,t5
|
||
addi t6,1 ;Count chars moved.
|
||
sojg t1,getpa3
|
||
|
||
quit: jumpe t6,retf ;No chars moved means no parameters.
|
||
hrli t6,tcrbuf ;set up swapped pointer.
|
||
movsm t6,prsarg ;store.
|
||
jrst rett
|
||
|
||
retf: tdza t1,t1
|
||
rett: movei t1,1
|
||
movem t1,1(p)
|
||
popj p,
|
||
|
||
|
||
;=============================================================================
|
||
;FUNCTION filprs(n: STRING; lkb:LOOKUP/ENTER/RENAME-block): INTEGER;
|
||
;
|
||
;(* Local function to parse a filespec.
|
||
; Returns the following "error" codes in ac0: *)
|
||
|
||
errnoe==101 ; no error, success
|
||
erricf==102 ; illegal character in filspec.
|
||
errtlf==103 ; too long field in filespec.
|
||
errdfn==104 ; duplicate filename
|
||
errdex==105 ; duplicate extension
|
||
errddr==106 ; double directory
|
||
errcnd==107 ; colon, but no device
|
||
errddv==110 ; duplicate device
|
||
errils==111 ; illegal separator in directory
|
||
errtms==112 ; too many sfds
|
||
errnls==113 ; null sfd
|
||
errilf==114 ; illegal format for directory
|
||
errilp==115 ; illegal protection code
|
||
errdpr==116 ; duplicate protection
|
||
errnw8==117 ; cant write 8-bit files.
|
||
|
||
;parameters
|
||
n==2
|
||
lkb==3
|
||
|
||
;locals
|
||
flags==0
|
||
pos==4
|
||
separ==5
|
||
word==6
|
||
sfdpnt==7
|
||
pth==10
|
||
err==11
|
||
|
||
X==7 ;Duplicate use of these.
|
||
NUMB==10
|
||
|
||
;filespec. flags
|
||
f.dev==1B35 ; device found
|
||
f.nam==1B34 ; file name found
|
||
f.ext==1B33 ; extension found
|
||
f.dir==1B32 ; directory found
|
||
f.pro==1B31 ; protection found
|
||
|
||
|
||
filprs: SETZ flags, ; clear flag word
|
||
PUSH p,pos ; save some accumulators
|
||
PUSH p,separ
|
||
PUSH p,word
|
||
PUSH p,sfdpnt
|
||
PUSH p,pth
|
||
PUSH p,err
|
||
SETZM cvseen ; no CTRL-V seen yet
|
||
SETZM PG.VAL ;[JE] No /Page yet.
|
||
SETZM LN.VAL ;[JE] No /Line yet.
|
||
SETZM CH.VAL ;[JE] No /Char yet.
|
||
SETZM FLAG8 ;[JE] No bytesize yet.
|
||
HLRZM n,prslen ;[JE] save string length.
|
||
HRLI n,(POINT 7,0) ; set up bytepointer to string
|
||
MOVEI pos,1 ; pos points to first char in n
|
||
filpr1: CALL nxtsix ; get next sixbit char
|
||
JRST .firet ; illegal character
|
||
JUMPL separ,.finrt ; end of string
|
||
filpr2: DBP n ; decrement byte pointer
|
||
SUBI pos,1 ; reset pos to last read char
|
||
CALL nxtwrd ; get a sixbit word
|
||
JRST .firet ; too long field
|
||
CAIN separ,':' ; is it device?
|
||
JRST fildev ; yes
|
||
JUMPE word,filpr3 ; if null, not filename
|
||
MOVEI err,errdfn ; assume double filenam error
|
||
TROE flags,f.nam ; check double filename error
|
||
JRST .firet ; yes, duplicate filename error
|
||
MOVEM word,.RBNAM(lkb) ; save filename
|
||
|
||
filpr3: CAIN separ,'.' ; is it extension?
|
||
JRST filext ; yes
|
||
CAIN separ,'<' ; protection or directory?
|
||
JRST filpro ; see if protection
|
||
CAIN separ,'[' ; directory?
|
||
JRST fildir ; yes
|
||
JUMPLE separ,.finrt ; at end of string?
|
||
MOVEI err,erricf ; no, we don't recognise it
|
||
JRST .firet
|
||
|
||
; here if "<" seen - check if it is protection
|
||
filpro: MOVEM n,save.n ; save position in
|
||
MOVEM pos,savpos ; name string
|
||
CALL nxtoct ; get prortection code
|
||
JRST .firet ; error
|
||
CAIE separ,'>' ; was it protection?
|
||
JRST[ MOVE n,save.n ; no, try directory instead
|
||
MOVE pos,savpos
|
||
JRST fildir]
|
||
MOVEI err,errdpr ; assume duplicate protection
|
||
TROE flags,f.pro ; duplicate?
|
||
JRST .firet ; yep
|
||
MOVEI err,errilp
|
||
CAILE word,777 ; check if legal
|
||
JRST .firet ; illegal
|
||
DPB word,[POINT ^D9,dslkbk+.RBPRV,^D8] ; store protection code
|
||
JRST filpr1 ; back for next field
|
||
|
||
|
||
; here if colon seen - we should have a device
|
||
fildev: MOVEI err,errilf ; assume illegal format
|
||
TRNE flags,f.nam+f.ext+f.dir ; device must be first in spec.!!
|
||
JRST .firet
|
||
JUMPE word,[
|
||
MOVEI err,errcnd ; no device before colon, error
|
||
JRST .firet]
|
||
MOVEI err,errddv ; assume double device error
|
||
TROE flags,f.dev
|
||
JRST .firet ; yes, duplicate device
|
||
MOVEM word,dsopbk+.OPDEV ; save device
|
||
DEVCHR word, ; what kind of device?
|
||
TXNE word,DV.DIR ; directory device?
|
||
JRST filpr1 ; yes, go back for more
|
||
SETOM notdir ; it was not a directory device
|
||
JUMPN word,filpr1 ; but it was a device
|
||
MOVE word,dsopbk+.OPDEV ; see if it was TMP:
|
||
CAXN word,SIXBIT /TMP/ ; tmpcore?
|
||
SETOM tcrdev ; yes, remember it
|
||
JRST filpr1
|
||
|
||
; here if period seen - next word should be extension
|
||
filext: MOVEI err,errdex ; assume duplicate extension
|
||
TROE flags,f.ext ; check for double extension
|
||
JRST .firet ; yes, double extension
|
||
CALL nxtwrd ; get next sixbit word
|
||
JRST .firet ; too long field
|
||
HLLM word,.RBEXT(lkb) ; save extension
|
||
JUMPG separ,filpr2 ; go back for more, if there is any
|
||
JRST .finrt ; ok, we're finished
|
||
|
||
; here if left bracket seen - directory should come next
|
||
fildir: SKIPE notdir ; directory device?
|
||
JRST fild.1 ; no, don't check default path
|
||
MOVE pth,.RBPPN(lkb) ; get pointer to PATH.-block
|
||
MOVE separ,dsopbk+1 ; get device
|
||
MOVEM separ,.PTFCN(pth) ; put device in PATH.-block
|
||
HRLI pth,.PTMAX
|
||
MOVEI err,ERDNA% ; assume device not available
|
||
PATH. pth, ; find out default path for this device
|
||
JRST .firet ; yep, it wasn't there
|
||
GETPPN word, ; get job's PPN (*JMR*)
|
||
JFCL ; (*JMR*)
|
||
MOVEM word,.PTPPN(pth) ; save PPN
|
||
fild.1: MOVEI err,errddr ; assume duplicate directory
|
||
TROE flags,f.dir ; check duplicate directory error
|
||
JRST .firet ; yes, duplicate directory
|
||
CALL nxtoct ; read an octal number (project)
|
||
JRST .firet ; error, too long field
|
||
CAIE separ,'-' ; default directory?
|
||
JRST fildr1 ; no, proceed
|
||
CALL nxtsix ; get next char
|
||
JRST .firet ; error, illegal char
|
||
JRST fildr3 ; finish directory parsing
|
||
|
||
|
||
fildr1: SKIPE word ; null project?
|
||
HRLM word,.PTPPN(pth) ; no, save project
|
||
MOVEI err,errils ; assume illegal separator in directory
|
||
CAIE separ,',' ; check it
|
||
JRST .firet ; yes, illegal separator
|
||
CALL nxtoct ; read an octal number (programmer)
|
||
JRST .firet ; error, too long field
|
||
SKIPE word ; null programmer?
|
||
HRRM word,.PTPPN(pth) ; no, save programmer
|
||
MOVEI sfdpnt,.PTSFD(pth) ; set pointer to first sfd
|
||
fildr2: CAIE separ,',' ; sfd next?
|
||
JRST fildr3 ; no, finish directory parsing
|
||
MOVEI err,errtms ; assume too many sfds
|
||
CAIL sfdpnt,.PTMAX(pth) ; how many sfds now?
|
||
JRST .firet ; too many
|
||
CALL nxtwrd ; get next sixbit word
|
||
JRST .firet ; too long field
|
||
MOVEM word,(sfdpnt) ; save the sfd
|
||
ADDI sfdpnt,1 ; increment sfd-pointer
|
||
JUMPN word,fildr2 ; if not null sfd, get next
|
||
MOVEI err,errnls ; null sfd, illegal
|
||
JRST .firet
|
||
|
||
fildr3: SETZM (sfdpnt) ; null word must be last in path
|
||
MOVEI err,errilf ; assume illegal format for directory
|
||
JUMPLE separ,filpr1 ; hack to allow missing right bracket
|
||
CAIE separ,']' ; must be at end of directory
|
||
CAIN separ,'>' ; check end of 2741 directory too
|
||
JRST filpr1 ; back for next field
|
||
JRST .firet ; yep, it was error all right
|
||
|
||
.finrt: MOVEI err,errnoe ; return success
|
||
SKIPE notdir ; is it a directory device?
|
||
JRST .firet ; no
|
||
TRNN flags,f.dir ; directory found?
|
||
SETZM .RBPPN(lkb) ; directory wasn't seen, use default
|
||
TRNE flags,f.pro ; protection found?
|
||
JRST .firet ; yep
|
||
MOVX t1,<-1,,.GTDFL>
|
||
GETTAB t1, ; find out default protection
|
||
SETZ t1, ; that should give us default later
|
||
TXNN t1,JD.SDP ; did user set default prot?
|
||
JRST[ MOVX t1,%LDSTP ; no, get system default
|
||
GETTAB t1,
|
||
MOVX t1,057B8 ; well...
|
||
JRST .+1]
|
||
LDB t1,[POINT ^D9,t1,^D8] ; extract prot.
|
||
DPB t1,[POINT ^D9,dslkbk+.RBPRV,^D8] ; store it
|
||
.firet: MOVE t0,err ; return error code
|
||
POP p,err ; restore some accumulators
|
||
POP p,pth
|
||
POP p,sfdpnt
|
||
POP p,word
|
||
POP p,separ
|
||
POP p,pos
|
||
POPJ P,
|
||
|
||
;get next sixbit char
|
||
|
||
;skip return if succesful, with char in ac 'separ',
|
||
; negative "char" if end of string.
|
||
;nonskip return if failure, with error code in 'err'
|
||
|
||
nxtsix: CAMLE pos,prslen ; past last char?
|
||
JRST[ SETO separ, ; yes, return negative "char"
|
||
JRST .nsret]
|
||
ILDB separ,n ; get next ascii char
|
||
CAIL separ,"a"
|
||
CAILE separ,"z"
|
||
SKIPA
|
||
SUBI separ," " ; convert to capitals
|
||
CAIL separ," " ; is char in sixbit range?
|
||
CAILE separ,"_"
|
||
JRST[ MOVEI err,erricf ; assume it's illegal
|
||
CAIE separ,"V"-"@" ; is it CTRL-V?
|
||
POPJ P, ; no it isn't, sorry
|
||
SKIPE cvseen ; CTRL-V already typed?
|
||
JRST[ SETZM cvseen ; yes, sorry
|
||
POPJ P,]
|
||
SETOM cvseen ; set the CTRL-V flag
|
||
ADDI pos,1 ; we have read on more char
|
||
JRST nxtsix ; ignore this char and get next
|
||
]
|
||
SUBI separ," " ; convert to sixbit
|
||
ADDI pos,1 ; increment pos
|
||
CAIE separ,'/' ;[JE] Attempt to read switches.
|
||
JRST .nsret ;[JE] Normal char, return.
|
||
PUSHJ P,SWTCHK ;[JE] Check for switches.
|
||
SETO separ, ;[JE] Call this end of string.
|
||
.nsret: AOS (p) ; bump return address
|
||
POPJ P,
|
||
|
||
; Here to check for switches. Don't look too close...
|
||
|
||
swtchk: push p,word ;Save current word.
|
||
push p,t7 ;Save this one too.
|
||
swtlup: pushj p,atom ;Read an atom.
|
||
camn word,['8 '] ;Want eight bit bytes?
|
||
jrst sw.8bt ; Yes, go handle.
|
||
camn word,['I '] ;Want I*M eight bits?
|
||
jrst sw.ibm ; Yes, go handle.
|
||
caie separ,':' ;Terminated by colon?
|
||
jrst swtret ; No, then we don't know about it.
|
||
came word,['P '] ;/P?
|
||
camn word,['PA '] ; /Pa?
|
||
jrst sw.page ; Yes, go handle.
|
||
came word,['PAG '] ;/Pag?
|
||
camn word,['PAGE '] ; /Page?
|
||
jrst sw.page ; Yes, go handle.
|
||
came word,['L '] ;/L?
|
||
camn word,['LI '] ; /Li?
|
||
jrst sw.line ; Yes, go handle.
|
||
came word,['LIN '] ;/Lin?
|
||
camn word,['LINE '] ; /Line?
|
||
jrst sw.line ; Yes, go handle.
|
||
came word,['C '] ;/C?
|
||
camn word,['CH '] ; /Ch?
|
||
jrst sw.char ; Yes, go handle.
|
||
came word,['CHA '] ;/Cha?
|
||
camn word,['CHAR '] ; /Char?
|
||
jrst sw.char ; Yes, go handle.
|
||
came word,['R '] ;/R?
|
||
camn word,['RU '] ; /Ru?
|
||
jrst sw.run ; Yes, go handle.
|
||
camn word,['RUN '] ;/Run?
|
||
jrst sw.run ; Yes, go handle.
|
||
|
||
swtret: pop p,t7
|
||
pop p,word
|
||
popj p,
|
||
|
||
; Here to handle /8 and /I
|
||
|
||
sw.ibm: skipa numb,["I"]
|
||
sw.8bt: movei numb,"8"
|
||
movem numb,flag8
|
||
jrst swtlup
|
||
|
||
; Here to decode /Page
|
||
|
||
sw.pag: pushj p,decnum ;Get decimal argument.
|
||
movem numb,pg.val ;Store argument.
|
||
jrst swtlup ;Loop for more.
|
||
|
||
; Here to decode /Line
|
||
|
||
sw.lin: pushj p,decnum ;Get decimal argument.
|
||
movem numb,ln.val ;Store argument.
|
||
jrst swtlup ;Loop for more.
|
||
|
||
; Here to decode /Char.
|
||
|
||
sw.cha: pushj p,decnum ;Get decimal argument.
|
||
movem numb,ch.val ;Store argument.
|
||
jrst swtlup ;Loop for more.
|
||
|
||
; Here to decode /Run.
|
||
|
||
sw.run: MOVEI X,6 ;Load a loop counter.
|
||
SETZM RUNBLK-1(X) ;Clear a word.
|
||
SOJG X,.-1 ;Loop over them all.
|
||
RUNLUP: PUSHJ P,ATOM ;The rest should be obvious.
|
||
CAIN SEPAR,':'
|
||
MOVEI X,4
|
||
XCT STATE(X)
|
||
TDZA X,X
|
||
MOVEM WORD,RUNFIL
|
||
JUMPLE SEPAR,swtret ;Restore and return after all is done.
|
||
CAIN SEPAR,'.'
|
||
AOJA X,RUNLUP
|
||
CAIE SEPAR,'<';'>'
|
||
CAIN SEPAR,'[';']'
|
||
MOVEI X,2
|
||
CAIN SEPAR,','
|
||
MOVEI X,3
|
||
JRST RUNLUP
|
||
|
||
STATE: SKIPE RUNFIL
|
||
HLLZM WORD,RUNEXT
|
||
HRLM NUMB,RUNPPN
|
||
HRRM NUMB,RUNPPN
|
||
MOVEM WORD,RUNDEV
|
||
|
||
ATOM: SETZB NUMB,WORD
|
||
PUSH P,[POINT 6,WORD]
|
||
ATOM.2: PUSHJ P,GETCHR
|
||
CAIG SEPAR,'Z'
|
||
CAIGE SEPAR,'A'
|
||
CAIG SEPAR,'9'
|
||
CAIGE SEPAR,'0'
|
||
JRST ATOM.4
|
||
LSH NUMB,3
|
||
TRO NUMB,-'0'(SEPAR)
|
||
TRNN WORD,77
|
||
IDPB SEPAR,(P)
|
||
JRST ATOM.2
|
||
|
||
ATOM.4: POP P,(P)
|
||
.POPJ: POPJ P,
|
||
|
||
decnum: movei numb,0 ;Start with zero.
|
||
decn.2: pushj p,getchr ;Get next char.
|
||
cail separ,'0' ;In range?
|
||
caile separ,'9'
|
||
popj p, ; No, return now.
|
||
imuli numb,^D10 ;Shift...
|
||
addi numb,-'0'(separ);Add...
|
||
jrst decn.2 ;Loop...
|
||
|
||
GETCHR: CAMLE POS,PRSLEN ;More to take?
|
||
JRST[ SETO SEPAR, ; No, return -1.
|
||
POPJ P,]
|
||
ILDB SEPAR,N ;Yes, get next char.
|
||
ADDI POS,1
|
||
CAIL SEPAR,141
|
||
SUBI SEPAR,40
|
||
SUBI SEPAR,40
|
||
POPJ P,
|
||
|
||
;get next sixbit word
|
||
|
||
;skip return if succesful,
|
||
; with sixbit value in ac 'word' and break char in ac 'separ'
|
||
;nonskip return if failure, with error code in 'err'
|
||
|
||
nxtwrd: PUSH p,t7 ; save an ac
|
||
SETZ word, ; clear result
|
||
MOVEI t7,6 ; max 6 chars in a sixbit word
|
||
nxtwr1: CALL nxtsix ; get next char
|
||
JRST[ POP p,t7 ; unsave an ac
|
||
POPJ P,] ; error, illegal char
|
||
JUMPL separ,.nwret ; end of string
|
||
SKIPN separ ; null char?
|
||
JRST nwillc ; yes, just return
|
||
CAIGE separ,'0' ; legal char?
|
||
JRST nwillc ; no
|
||
CAIG separ,'9' ; try again
|
||
JRST nxtwr2 ; yes, definitely legal
|
||
CAIL separ,'A' ; last chance
|
||
CAILE separ,'Z'
|
||
nwillc: JRST[ SKIPN cvseen ; have we seen a CTRL-V?
|
||
JRST .nwret ; sorry, illegal char
|
||
SETZM cvseen ; yes, clear the CTRL-V flag
|
||
JRST nxtwr2 ; and pretend it's a legal char
|
||
]
|
||
nxtwr2: JUMPE t7,nxtwr1 ; t7 = 0 means word is full -- don't store...
|
||
LSH word,6 ; shift left SIX BITs
|
||
IOR word,separ ; append next char
|
||
SOJA t7,nxtwr1 ; get next char, if room for more
|
||
.nwret: IMULI t7,6
|
||
LSH word,(t7) ; left justify
|
||
POP p,t7 ; restore an ac
|
||
AOS (p) ; bump return pc
|
||
POPJ P,
|
||
|
||
|
||
;read an octal number
|
||
|
||
;skip return if succesful,
|
||
; with octal value in ac 'word' and break char in ac 'separ'
|
||
;nonskip return if failure, with error code in 'err'
|
||
|
||
nxtoct: PUSH p,t7 ; save an ac
|
||
SETZ word, ; clear result
|
||
MOVEI t7,6 ; max six digits in an octal halfword
|
||
nxtoc1: CALL nxtsix ; get next char
|
||
JRST[ POP p,t7 ; error, illegal char (error code -2)
|
||
POPJ P,]
|
||
SKIPN separ ; null char?
|
||
JRST .noret ; yes, just return
|
||
CAIL separ,'0' ; legal digit?
|
||
CAILE separ,'7'
|
||
JRST .noret ; no
|
||
JUMPE t7,[ ; yes, but halfword is full
|
||
MOVEI err,errtlf
|
||
POP p,t7
|
||
POPJ P,]
|
||
LSH word,3 ; shift left one octal digit
|
||
SUBI separ,'0' ; convert to octal
|
||
IOR word,separ ; append next digit
|
||
SOJA t7,nxtoc1
|
||
.noret: POP p,t7 ; restore an ac
|
||
AOS (p) ; bump return pc
|
||
POPJ P,
|
||
|
||
;------------------------------------------------------------------------------
|
||
; Routines to handle "List Files". Currently just dummies.
|
||
;
|
||
; function LsFOpen(s: string; l: integer): boolean;
|
||
; function LsFMore: boolean;
|
||
; function LsFChar: char;
|
||
; function LsFClose: boolean;
|
||
|
||
LSFOPE::movei 1,[[ASCIZ "LSF? List Files not yet implemented"]]
|
||
movem 1,errtab
|
||
setzm lsterr
|
||
movni 1,2
|
||
movem 1,1(p)
|
||
popj p,
|
||
|
||
LSFMORE::
|
||
LSFCHAR::
|
||
LSFCLOSE::
|
||
movei 2,[ASCIZ "DSKIO: LSFxxx routine called."]
|
||
pushj p,bug##
|
||
|
||
;=============================================================================
|
||
;FUNCTION dskopen(n: STRING; a: CHAR): INTEGER;
|
||
;
|
||
;(* Opens the file "n" in access "a". Returns 0 if success,
|
||
; otherwise -1 if file wasn't found, and -2 on all other errors *)
|
||
|
||
;parameters
|
||
n==2
|
||
a==3
|
||
|
||
dskope::HRLI n,strsize ;Load default string length.
|
||
skipe prsarg ;Special case?
|
||
move n,prsarg ; Yes, use another argument.
|
||
setzm prsarg ;... but only once.
|
||
SKIPE ds.opn ; check if we already have an open file
|
||
bugerr <DSKOPEN: File is already open>
|
||
cain a,"R" ;Map new access codes to old.
|
||
movei a,1
|
||
cain a,"W"
|
||
movei a,2
|
||
cail a,1 ;Range check the new access code.
|
||
caile a,2
|
||
bugerr <DSKOPEN: Illegal access code>
|
||
DMOVE t0,[
|
||
EXP .IOASC ; use ascii mode
|
||
SIXBIT 'DSK'] ; default device
|
||
DMOVEM t0,dsopbk+.OPMOD
|
||
MOVEI t1,dslkln ; length of LOOKUP-block
|
||
MOVEM t1,dslkbk+.RBCNT ; it might be clobberd
|
||
MOVEI t0,dslkpt ;Pointer to path.
|
||
SETZ t1, ;Empty file name.
|
||
DMOVEM t0,dslkbk+.RBPPN
|
||
MOVE t1,[
|
||
dslkbk+.RBEXT,,dslkbk+.RBPRV]; set up to clear lookup block
|
||
SETZM dslkbk+.RBEXT ; clear first word
|
||
BLT t1,dslkbk+.RBDEV ; clear the block
|
||
PUSH p,3 ; save ac3
|
||
MOVEI 3,dslkbk ; prepare to parse for lookup-block
|
||
CALL filprs ; parse the filename
|
||
POP p,3 ; unsave ac3
|
||
CAIE t0,errnoe ; check if no error
|
||
JRST fatal
|
||
SKIPE tcrdev ; tmpcore?
|
||
JRST @[
|
||
tcropn ; yes, go read in from TMP:
|
||
opnret ; yes, but nothing special when writing
|
||
]-1(A)
|
||
MOVEI t0,ERDNA% ; assume device not available
|
||
OPEN dsk,dsopbk ; open device
|
||
JRST fatal
|
||
MOVE t1,dsopbk+.OPDEV
|
||
DEVTYP t1, ; ask monitor what kind of device
|
||
bugerr <DSKOPEN: DEVTYP failed>
|
||
JRST @[
|
||
opread ; open for read
|
||
opwrit ; open for write
|
||
]-1(a)
|
||
|
||
tcropn: HLLZ t4,dslkbk+.RBNAM ; no, read from TMP:
|
||
MOVE t5,[IOWD dsksiz/5,dsbuf1+3]
|
||
MOVE t3,[.TCRRF,,t4]
|
||
TMPCOR t3,
|
||
JRST[ MOVEI t0,ERFNF% ; wasn't there
|
||
JRST warn]
|
||
MOVEM t3,tcrsiz ; save number of read words
|
||
JRST opnret
|
||
|
||
|
||
; come here if open for read
|
||
opread:
|
||
TXNN t1,DV.IN ; can device can do input?
|
||
JRST fatal
|
||
MOVX t0,.INFIN ; infinitely large
|
||
MOVEM t0,blknum ; file assumed
|
||
SKIPE notdir ; is it a directory device?
|
||
JRST opre10 ; no, don't do LOOKUP
|
||
LOOKUP dsk,dslkbk
|
||
JRST[ HRRZ t0,dslkbk+.RBEXT; failed, return with error code
|
||
SKIPE t0 ; fatal error?
|
||
JRST fatal ; yes
|
||
JRST warn] ; no, just warning
|
||
MOVE t0,dslkbk+.RBSIZ ; get size in words
|
||
IDIVI t0,dsksiz/5 ; how many blocks?
|
||
SKIPE t1 ; exact?
|
||
ADDI t0,1 ; no, but we still want the last block
|
||
MOVEM t0,blknum ; save it
|
||
MOVEI t1,dsk ; disk channel
|
||
MOVEM t1,dslkpt+.PTFCN ; to path-block
|
||
MOVE t1,[.PTMAX,,dslkpt]
|
||
PATH. t1, ; get real path to the file
|
||
bugerr <Can't get real path to file> ; should never happen
|
||
PUSHJ P,FFIXUP ;[JE]
|
||
opre10: MOVEI t1,dsbfih ; use buffers for input
|
||
CALL bufbld ; build buffers
|
||
JRST opnret
|
||
|
||
; Routine to get file name and extension from Tops-10. (7.02)
|
||
|
||
FFIXUP: MOVE T1,[
|
||
XWD 2,[
|
||
XWD DSK,.FOFIL
|
||
XWD ^D11,EXPFIL]]
|
||
FILOP. T1, ;Try get Name and Ext. from Topsy.
|
||
POPJ P, ; Nope, just ignore this.
|
||
MOVE T1,EXPFIL+.FOFFN;Get file name, and store in LOOKUP block.
|
||
MOVEM T1,DSLKBK+.RBNAM
|
||
MOVE T1,EXPFIL+.FOFEX;Get extension, and store in LOOKUP block.
|
||
HLLM T1,DSLKBK+.RBEXT
|
||
POPJ P, ;Return, with LOOKUP/ENTER block updated.
|
||
|
||
|
||
; come here if open for write
|
||
opwrit:
|
||
TXNN t1,DV.OUT ; can device do output?
|
||
JRST fatal
|
||
movei t0,errnw8 ;Assume /8 set.
|
||
skipe flag8 ;Is it?
|
||
jrst fatal ; Yes, then we cannot write.
|
||
MOVEI t1,<.PTSLJ>B29+<.PTSCN>B35
|
||
MOVEM t1,dslkpt+.PTSWT ; don't use fishy switches
|
||
LDB t1,[POINT ^D9,dslkbk+.RBPRV,^D8] ; save original prot.
|
||
MOVEM t1,orgpro
|
||
SKIPN notdir ; is it a directory device?
|
||
LOOKUP dsk,dslkbk ; see if it is an existing file
|
||
JRST nfound ; no open a new one
|
||
MOVEI t1,dslkpt
|
||
MOVEM t1,dslkbk+.RBPPN ; set pointer to path block
|
||
MOVEI t1,dsk
|
||
MOVEM t1,dslkpt+.PTFCN ; channel
|
||
MOVE t1,[11,,dslkpt] ; length,,arg
|
||
PATH. t1, ; find out path to this file
|
||
bugerr <Can't get path to file>
|
||
PUSHJ P,FFIXUP ;[JE]
|
||
SETOM xxbak ; yes, indicate that we're using backup
|
||
SKIPE orgpro ; do we have an original prot already?
|
||
JRST opwr05 ; yes
|
||
LDB t1,[POINT ^D9,dslkbk+.RBPRV,^D8] ; save original prot.
|
||
MOVEM t1,orgpro
|
||
opwr05: HLLZ t1,dslkbk+.RBEXT ; save original extension
|
||
MOVEM t1,orgext
|
||
MOVE t1,dslkbk+.RBNAM ; save original filename
|
||
MOVEM t1,orgnam
|
||
MOVE t1,tmppro ; use temporary protection
|
||
DPB t1,[POINT ^D9,dslkbk+.RBPRV,^D8]
|
||
MOVE t1,tmpnam ; use the temporary name
|
||
MOVEM t1,dslkbk+.RBNAM
|
||
MOVE t1,tmpext ; use temporary fileextension
|
||
HLLM t1,dslkbk+.RBEXT
|
||
MOVEI t0,ERDNA% ; assume device not available
|
||
OPEN dsk,dsopbk ; open device again
|
||
JRST fatal
|
||
nfound: HLLZS dslkbk+.RBEXT ; clear creation-date (high order bits)
|
||
SETZ t1,
|
||
DPB t1,[POINT ^D23,dslkbk+.RBPRV,^D35] ; and low bits
|
||
MOVE t1,[dslkbk+.RBSIZ,,dslkbk+.RBVER]
|
||
push p,dslkbk+.rbspl ;*****
|
||
push p,dslkbk+.rbver ;***
|
||
SETZM dslkbk+.RBSIZ
|
||
BLT t1,dslkbk+.RBDEV ; clear rest of LOOKUP block
|
||
pop p,dslkbk+.rbver ;***
|
||
pop p,dslkbk+.rbspl ;*****
|
||
ENTER dsk,dslkbk ; create a file
|
||
JRST[ HRRZ t0,dslkbk+.RBEXT ; error
|
||
JRST fatal]
|
||
SKIPE notdir ; is it a directory device?
|
||
JRST opwr10 ; no, don't try to get path
|
||
MOVEI t1,dsk ; disk channel
|
||
MOVEM t1,dslkpt+.PTFCN ; to path-block
|
||
MOVE t1,[.PTMAX,,dslkpt]
|
||
PATH. t1, ; get real path to the file
|
||
bugerr <Can't get real path to the file>
|
||
PUSHJ P,FFIXUP ;[JE]
|
||
opwr10: MOVEI t1,dsbfoh ; use buffers for output
|
||
CALL bufbld ; build buffers
|
||
OUT dsk, ; try a dummy OUT
|
||
SKIPA
|
||
bugerr <DSKOPEN: Dummy OUT failed>
|
||
opnret: MOVE t1,a
|
||
MOVEM t1,ds.opn ; the file is now open
|
||
SETZM 1(P)
|
||
POPJ P, ; all's well, return with 0
|
||
|
||
|
||
;build buffers, arg is pointer to buffer header control block in t1
|
||
bufbld:
|
||
PUSH p,t0
|
||
MOVX t0,<BF.VBR+dsbuf1+.BFHDR>; pointer to current buffer
|
||
MOVEM t0,.BFADR(t1) ; put it in buffer-header
|
||
MOVE t0,[POINT 7,0,35]
|
||
MOVEM t0,.BFPTR(t1) ; set up byte-pointer
|
||
SETZM .BFCTR(t1) ; clear byte-counter
|
||
HRLZI t0,dsksiz/5+1 ; buffer size + 1
|
||
HRRI t0,dsbuf2+.BFHDR
|
||
MOVEM t0,dsbuf1+.BFHDR ; set up first buffer
|
||
HRRI t0,dsbuf3+.BFHDR
|
||
MOVEM t0,dsbuf2+.BFHDR ; set up second buffer
|
||
HRRI t0,dsbuf4+.BFHDR
|
||
MOVEM t0,dsbuf3+.BFHDR ; set up third buffer
|
||
HRRI t0,dsbuf5+.BFHDR
|
||
MOVEM t0,dsbuf4+.BFHDR ; set up fourth buffer
|
||
HRRI t0,dsbuf6+.BFHDR
|
||
MOVEM t0,dsbuf5+.BFHDR ; set up fifth buffer
|
||
HRRI t0,dsbuf1+.BFHDR
|
||
MOVEM t0,dsbuf6+.BFHDR ; set up sixth buffer
|
||
POP p,t0
|
||
POPJ P,
|
||
|
||
|
||
;=============================================================================
|
||
;PROCEDURE truename (VAR namstr: string; fields: char);
|
||
;
|
||
;(* Gives the name of the opened file. *)
|
||
|
||
;parameters
|
||
namstr==2
|
||
fields==3
|
||
|
||
;locals
|
||
sixwrd==6
|
||
number==5
|
||
char==5
|
||
|
||
x1==7
|
||
x2==10
|
||
|
||
;flags to decide what fields to return
|
||
devp==1B35 ; 1
|
||
namep==1B34 ; 2
|
||
typep==1B33 ; 4
|
||
dirp==1B32 ; 8
|
||
attrp==1B31 ; 16
|
||
nodep==1B30 ; 32
|
||
|
||
truena::cain fields,"B" ;Map from new calling standard...
|
||
movei fields,<namep>
|
||
cain fields,"D"
|
||
movei fields,<nodep+devp+namep+typep+dirp>
|
||
cain fields,"F"
|
||
movei fields,<devp+namep+typep+dirp+attrp>
|
||
push p,namstr ;Save argument, for retry.
|
||
pushj p,.truen ;First try...
|
||
jumpge t1,tnret ;All OK, return.
|
||
trz fields,<nodep+attrp>
|
||
move namstr,(p)
|
||
pushj p,.truen ;second try...
|
||
jumpge t1,tnret ;Did it without protection, good.
|
||
trz fields,dirp
|
||
move namstr,(p)
|
||
pushj p,.truen ;Last try...
|
||
tnret: pop p,(p) ;restore stack.
|
||
popj p, ;return.
|
||
|
||
.truen: CALL blanks ; blank the string
|
||
HRLI namstr,(POINT 7,0) ; make a bytepointer
|
||
MOVEI t1,strsiz ; length of string
|
||
txnn fields,nodep ;Node name wanted?
|
||
jrst no.nod ; Nope, skip a bit.
|
||
movei x1,2 ;Set up argument list length.
|
||
movei x2,.gtloc
|
||
gettab x2, ;Get number of local node.
|
||
jrst no.nod ; Oops...
|
||
movx sixwrd,<.ndrnn,,x1>
|
||
node. sixwrd, ;Convert to node name.
|
||
jrst no.nod ; Oops...
|
||
call trusix ;Store in string.
|
||
movei char,":" ;Store double colon.
|
||
call putnam
|
||
call putnam
|
||
no.nod: SKIPN sixwrd,dslkbk+.RBDEV ; if nothing there
|
||
SKIPA sixwrd,dsopbk+1 ; then try here
|
||
TRZ sixwrd,007777 ; only first 4 chars, thank you
|
||
MOVEM sixwrd,dsopbk+1 ; save device name
|
||
TXNN fields,devp
|
||
JRST no.dev
|
||
CALL trusix ; output to the namestring
|
||
MOVEI char,":" ; colon finishes
|
||
CALL putnam
|
||
no.dev: MOVE t7,dsopbk+1 ; get device name again
|
||
HLRZ t6,t7 ; we need it once more
|
||
DEVTYP t7, ; get charcteristics
|
||
bugerr <TRUNAME: DEVTYP failed>
|
||
TXNE t7,TY.MAN+TY.SPL ; directory device or spooled device?
|
||
JRST trufil ; yes, print at least filename
|
||
CAIE t6,'TMP' ; no, is it TMP: ?
|
||
POPJ P, ; no, don't do anything more
|
||
SETO t7, ; make sure we don't go past filename
|
||
trufil: TXNN fields,namep
|
||
JRST no.nam
|
||
MOVE sixwrd,dslkbk+.RBNAM ; filename
|
||
CALL trusix
|
||
no.nam: TXNE t7,TY.SPL ; spooled device?
|
||
POPJ P, ; yes, don't print any more junk
|
||
TXNN fields,typep
|
||
JRST no.typ
|
||
MOVEI char,"." ; separates from extension
|
||
CALL putnam
|
||
HLLZ sixwrd,dslkbk+.RBEXT ; get extension
|
||
CALL trusix ; print the extension
|
||
no.typ: TXNN fields,dirp
|
||
JRST no.dir
|
||
trudir: MOVEI char,"[" ; here comes directory
|
||
CALL putnam
|
||
SKIPE dslkbk+.RBPPN ; null pointer
|
||
JRST trudi1 ; no, proceed
|
||
MOVE t8,dsopbk+1
|
||
MOVEM t8,dslkpt+.PTFCN ; device
|
||
MOVE t7,[.PTMAX,,dslkpt]
|
||
PATH. t7, ; get default path
|
||
bugerr <TRUENAME: Can't get path of device>
|
||
trudi1: HLRZ number,dslkpt+.PTPPN ; get project
|
||
CALL truoct
|
||
MOVEI char,"," ; separate with comma
|
||
CALL putnam
|
||
HRRZ number,dslkpt+.PTPPN ; get programmer
|
||
CALL truoct
|
||
|
||
MOVEI t7,dslkpt+.PTSFD ; get first sfd
|
||
trudi2: SKIPN (t7) ; null sfd?
|
||
JRST trudi3 ; yes, end of directory
|
||
MOVEI char,"," ; separator
|
||
CALL putnam
|
||
MOVE sixwrd,(t7) ; get sfd-name
|
||
CALL trusix
|
||
AOJA t7,trudi2 ; get next sfd
|
||
trudi3: MOVEI char,"]" ; finishes the directory
|
||
CALL putnam
|
||
no.dir: TXNN fields,attrp
|
||
JRST no.att
|
||
trupro: MOVEI char,"<" ; start of protection field
|
||
CALL putnam
|
||
MOVEI t8,3 ; three digits in protection code
|
||
MOVE t7,[POINT 3,dslkbk+.RBPRV] ; pointer to protection code
|
||
trupr1: ILDB char,t7 ; get a digit
|
||
ADDI char,"0" ; convert to ascii
|
||
CALL putnam ; put it in string
|
||
SOJG t8,trupr1 ; get next digit
|
||
MOVEI char,">" ; end of protection field
|
||
CALL putnam
|
||
skipn flag8 ;[JE] Eight bit?
|
||
jrst no.att ;[JE] Nope, skip this.
|
||
movei char,"/" ;[JE] Yes, add "/" to string.
|
||
pushj p,putnam
|
||
move char,flag8 ;[JE] Add kind of eight-bit.
|
||
pushj p,putnam
|
||
no.att: popj p,
|
||
|
||
|
||
; put a sixbit word in the string.
|
||
; sixbit word in ac 'sixwrd'.
|
||
|
||
trusix: JUMPE sixwrd,[POPJ P,] ; null word
|
||
trusi1: SETZ char,
|
||
LSHC char,6 ; get a sixbit byte
|
||
ADDI char," " ; convert to ascii
|
||
CAIGE char,"0" ; legal char?
|
||
JRST trusi2 ; no
|
||
CAIG char,"9" ; try again
|
||
JRST trusi3 ; yes, definitely legal
|
||
CAIL char,"A" ; last chance
|
||
CAILE char,"Z"
|
||
trusi2: JRST[ HRLZ char,char ; save char in left half of ac
|
||
HRRI char,.CHCNV ; CTRL-V
|
||
CALL putnam ; put the ^V
|
||
HLRZ char,char ; get back the char
|
||
JRST trusi3] ; go put the char too
|
||
trusi3: CALL putnam ; put it in namestring
|
||
JUMPN sixwrd,trusi1 ; get next byte
|
||
POPJ P,
|
||
|
||
; put an octal number in the string.
|
||
; number in ac 'number'. number+1 is destroyed.
|
||
|
||
truoct: IDIVI number,^D8 ; get quotient and remainder
|
||
PUSH p,number+1 ; push remainder
|
||
SKIPE number ; IF quotient /= 0 THEN
|
||
CALL truoct ; trueoct (quotient)
|
||
POP p,char ; ELSE fall thru to put-routine
|
||
ADDI char,"0" ; but first convert to ascii
|
||
|
||
; put a character in the string..
|
||
; character in ac 'char'.
|
||
|
||
putnam: SUBI t1,1 ;[JE]Decrement char counter
|
||
SKIPL t1 ;[JE]Room left in string?
|
||
IDPB char,namstr ;[JE] No, deposit the byte
|
||
POPJ P,
|
||
|
||
;=============================================================================
|
||
;FUNCTION TrueMode: majors;
|
||
;(* Return our opinion of what major mode this buffer shall have, *)
|
||
;(* based on what extension we have. *)
|
||
|
||
TRUEMO::HLRZ T1,DSLKBK+.RBEXT ;Get extension from lookup/enter block
|
||
MOVEI T2,MODLEN ;Get length of mode table
|
||
TMOD.2: HRRZ T3,MODTAB(T2) ;Get next extension from table
|
||
CAIN T3,(T1) ;Is this it?
|
||
JRST TMOD.4 ; Yes, go return corresponding mode
|
||
SOJGE T2,TMOD.2 ;No, decrement counter, and maybe loop back
|
||
MOVEI T1,MD%FUN ;No table left, assume fundamental mode
|
||
MOVEM T1,1(P) ;Return value for pascal
|
||
POPJ P,
|
||
|
||
TMOD.4: HLRZ T1,MODTAB(T2) ;We found a match, get the mode from table
|
||
MOVEM T1,1(P) ;Return it for pascal
|
||
POPJ P, ;All done!
|
||
|
||
;*** NOTE *** These must agree with the type 'majors' in MAIN.PAS
|
||
|
||
MD%FUN==1
|
||
MD%TXT==2
|
||
MD%ALG==3
|
||
MD%MAC==4
|
||
MD%PAS==5
|
||
MD%LSP==6
|
||
MD%C== 7
|
||
MD%TEX==10
|
||
MD%ADA==11
|
||
MD%MOD==12
|
||
MD%PL1==13
|
||
MD%BLI==14
|
||
|
||
MODTAB: XWD MD%TXT,'DOC' ;Documentation files
|
||
XWD MD%TXT,'HLP' ;Help files
|
||
XWD MD%TXT,'MAN' ;Manuals
|
||
XWD MD%TXT,'MEM' ;Memos
|
||
XWD MD%TXT,'MSS' ;Scribe something
|
||
XWD MD%TXT,'PL ' ;Prolog (NIL says text mode is best...)
|
||
XWD MD%TXT,'RFC' ;Request For Comments...
|
||
XWD MD%TXT,'TXT' ;General text files
|
||
XWD MD%ALG,'ALG' ;Algol-60
|
||
XWD MD%ALG,'SAI' ;Sail
|
||
XWD MD%ALG,'SIM' ;Simula
|
||
XWD MD%MAC,'MAC' ;Macro-10
|
||
XWD MD%MAC,'MID' ;Midas
|
||
XWD MD%MAC,'P11' ;Macro-11
|
||
XWD MD%PAS,'PAS' ;Pascal
|
||
XWD MD%LSP,'LSP' ;Lisp
|
||
XWD MD%C, 'C ' ;C
|
||
XWD MD%C, 'H ' ;C 'include' files
|
||
XWD MD%TEX,'TEX' ;TeX sources
|
||
XWD MD%ADA,'ADA' ;Frog code.
|
||
XWD MD%BLI,'BLI' ;Bliss (yeach) code.
|
||
XWD MD%BLI,'B36' ; -""-
|
||
XWD MD%BLI,'R36' ; -""-
|
||
XWD MD%BLI,'REQ' ; -""-
|
||
MODLEN==.-MODTAB
|
||
|
||
;=============================================================================
|
||
;PROCEDURE TruePos(var pagenumber, linenumber, charnumber: bufpos);
|
||
;(* Give back information about where in the file to start. *)
|
||
|
||
TRUEPO::move 1,pg.val
|
||
movem 1,(2) ;Give page #.
|
||
move 1,ln.val
|
||
movem 1,(3) ;Give line #.
|
||
move 1,ch.val
|
||
movem 1,(4) ;Give char #.
|
||
popj p, ;Return.
|
||
|
||
;=============================================================================
|
||
;FUNCTION dskcd(d: string): integer;
|
||
;(* This implements the function "Connect to Directory". *)
|
||
|
||
dskcd:: SETZM dslkpt ;Clear first word of PATH. block.
|
||
MOVE 1,[dslkpt,,dslkpt+1]
|
||
BLT 1,dslkpt+.PTMAX ;Clear rest of block.
|
||
HRLI 2,strsize ;Load string size.
|
||
MOVEI 3,dslkbk ;Load stupid argument pointer.
|
||
CALL filprs ;Call parser to fill in data.
|
||
CAIE t0,errnoe ;Any error?
|
||
JRST fatal ; Yes, conplain.
|
||
HRROI 1,.PTFSD
|
||
MOVEM 1,dslkpt+.PTFCN ;Set up function code.
|
||
MOVE 1,[.PTMAX,,dslkpt]
|
||
MOVEI t0,errccd ;Assume error.
|
||
PATH. 1, ;Try change default path.
|
||
JRST fatal ; Bad, propagate error.
|
||
SETZM 1,1(p) ;Give good return.
|
||
POPJ p,
|
||
|
||
;=============================================================================
|
||
;FUNCTION dskrecognition(VAR f: string; VAR len: integer; ch: char): boolean;
|
||
;(* This is the file name recognition routine. It just returns FALSE *)
|
||
;(* in this implementation. *)
|
||
|
||
DSKREC::SETZM 1(P) ;Clear return value. (Means FALSE)
|
||
POPJ P, ;Return and show that this did not work.
|
||
|
||
;=============================================================================
|
||
;FUNCTION dskread(VAR x: ^DSKBLOCK): INTEGER;
|
||
;
|
||
;(* Reads data from the file into x.
|
||
; Returns number of read characters if success, -1 if EOF and
|
||
; -2 if other error. *)
|
||
|
||
;parameters
|
||
x==2
|
||
|
||
dskrea::SKIPN ds.opn ; check if file is open
|
||
bugerr <DSKREAD: File is not open>
|
||
SKIPE tcrdev ; tmpcore?
|
||
JRST tcrrea ; yes
|
||
IN dsk,
|
||
JRST dskr10
|
||
STATZ dsk,IO.EOF ; check for end-of-file
|
||
JRST[ SETOM 1(P) ; return -1 in case of EOF
|
||
POPJ P,]
|
||
STATZ dsk,IO.ERR ; hard error?
|
||
bugerr <DSKREAD: Hard error. Please reboot>
|
||
bugerr <DSKREAD: Strange error>
|
||
POPJ P,
|
||
|
||
dskr10: HRRZ t1,dsbfih+.BFADR ; address to current buffer
|
||
ADDI t1,2 ; get pointer to start of buffer
|
||
SETAM t1,(x) ; to where it should end up
|
||
MOVE t3,dsbfih+.BFCTR ; get number of read bytes
|
||
skipe flag8 ;[JE] Eight-bit bytes?
|
||
jrst dskr.8 ;[JE] Yes, have to convert block.
|
||
SOSLE blknum ; last block?
|
||
JRST .inret ; no, just return count
|
||
pushj p,getlwd ;[JE] Get last word in buffer.
|
||
TXNN t5,000000000377 ; [BD] Ends with <NUL> ?
|
||
SUBI t3,1 ; [BD] yes, decrement count
|
||
TXNN t5,000000077777 ; [BD] Ends with <NUL> <NUL> ?
|
||
SUBI t3,1 ; [BD] yes, decrement count
|
||
TXNN t5,000017777777 ; [BD] Ends with <NUL> <NUL> <NUL> ?
|
||
SUBI t3,1 ; [BD] yes, decrement count
|
||
TXNN t5,003777777777 ; [BD] Ends <NUL> <NUL> <NUL> <NUL> ?
|
||
SUBI t3,1 ; [BD] yes, decrement count
|
||
.inret: MOVEM t3,1(p) ; return count
|
||
POPJ P,
|
||
|
||
; Get last data word in buffer.
|
||
|
||
getlwd: move t2,dsbfih+.bfptr;Get byte pointer.
|
||
movei t4,-1(t3) ;Get number of 7-bit bytes, minus one.
|
||
idivi t4,5 ;Get number of words minus one.
|
||
add t2,t4 ;Increment byte pointer.
|
||
ibp t2 ;... to last word somewhere.
|
||
move t5,(t2) ;Fetch last word.
|
||
popj p, ;return.
|
||
|
||
dskr.8: move t1,t3 ;Get number of bytes.
|
||
imuli t1,4 ;Convert to 8-bit bytes.
|
||
idivi t1,5
|
||
sosle blknum ;Last block?
|
||
jrst dskr8b ; Nope, just convert buffer.
|
||
pushj p,getlwd ;Get last word in buffer.
|
||
txnn t5,000000007777 ;Check for one null.
|
||
subi t1,1
|
||
txnn t5,000003777777 ;Check for two nulls.
|
||
subi t1,1
|
||
txnn t5,001777777777 ;Check for three nulls.
|
||
subi t1,1
|
||
dskr8b: movem t1,1(p) ;Set return value.
|
||
jumple t1,.popj ;Save some work for empty buffers.
|
||
movei t6,[jrst (t3)] ;Default to no conversion.
|
||
move t2,flag8 ;What kind of eight-bit?
|
||
cain t2,"I" ;I*M specials?
|
||
movei t6,cvtibm ; Yes, load conversion routine.
|
||
cain t2,"A" ;ANSI eight bit?
|
||
movei t6,cvtansi ; Yes, load conversion routine.
|
||
move t7,dsbfih+.bfptr;Get seven-bit byte pointer.
|
||
move t8,t7 ;Copy it.
|
||
tlc t8,001700 ;Convert to eight-bit pointer.
|
||
dskr8c: ildb t2,t8 ;Get eight-bit byte.
|
||
jsp t3,(t6) ;Possibly convert it.
|
||
idpb t2,t7 ;Store seven-bit byte.
|
||
sojg t1,dskr8c ;Decrement and loop.
|
||
popj p,
|
||
|
||
; Routine to convert eight-bit char in T2 to suitable seven-bit character.
|
||
|
||
define convert(c8,c7),<
|
||
cain t2,100+c8
|
||
movei t2,c7
|
||
>;convert macro
|
||
|
||
cvtibm: caig t2,200 ;High bit set?
|
||
jrst (t3) ; No, save compares.
|
||
convert "A","~"
|
||
convert "B","`"
|
||
convert "D","{"
|
||
convert "F","}"
|
||
convert "N","["
|
||
convert "O","]"
|
||
convert "P","@"
|
||
convert "T","|"
|
||
convert "Y","\"
|
||
convert "Z","^"
|
||
jrst (t3) ;Return from JSP call.
|
||
|
||
cvtansi:jrst (t3) ;Just return for now.
|
||
|
||
|
||
tcrrea: skipe tcrflg ; have we read a block already?
|
||
jrst[ setom 1(p) ; yes, return EOF
|
||
popj p,]
|
||
move t3,tcrsiz ; get number of words read
|
||
subi t3,1 ; minus one
|
||
move t4,t3 ; compute number..
|
||
imuli t3,5 ; ..of bytes
|
||
movei t0,dsbuf1+3 ; get pointer to buffer
|
||
movem t0,(x) ; give to caller
|
||
hrli t0,(POINT 7,0) ; make a bytepointer to the buffer
|
||
add t4,t0 ; adjust to last word - 1
|
||
tcrr10: ildb t5,t4 ; get that byte
|
||
skipe t5 ; <NUL>?
|
||
aoja t3,tcrr10 ; no, get next
|
||
movem t3,1(p) ; give number of read bytes to caller
|
||
setom tcrflg ; indicate we've read from TMP:
|
||
popj p,
|
||
|
||
|
||
;=============================================================================
|
||
;FUNCTION dsknext: ^DSKBLOCK;
|
||
;
|
||
;(* Returns the address of the next available diskbuffer. *)
|
||
|
||
dsknex::HRRZ t1,dsbfoh+.BFADR ; address of buffer header
|
||
SKIPE tcrdev ; tmpcore?
|
||
MOVEI t1,dsbuf1+.BFHDR ; yes, use predefined buffer
|
||
ADDI t1,2 ; offset to get beginning of text
|
||
MOVEM t1,1(p)
|
||
POPJ p,
|
||
|
||
|
||
;=============================================================================
|
||
;FUNCTION dskwrite(count: INTEGER) INTEGER;
|
||
;
|
||
;(* Writes count bytes of data on the file from x.
|
||
; Returns 0 if success, -2 otherwise. *)
|
||
|
||
;parameters
|
||
count==2
|
||
|
||
dskwri::SKIPN ds.opn ; check if file is open
|
||
bugerr <DSKWRITE: File is not open>
|
||
CAILE count,dsksiz
|
||
bugerr <DSKWRITE: Too large diskblock>
|
||
MOVE t3,count ; get number of bytes to write
|
||
IDIVI t3,5
|
||
;[je] n'th try to get the correct byte pointer...
|
||
movei t5,dsbuf1+3
|
||
hrli t5,(point 7)
|
||
skipn tcrdev
|
||
move t5,dsbfoh+.bfptr
|
||
add t3,t5
|
||
|
||
dskw10: JUMPE t4,dskw20
|
||
IBP t3
|
||
SOJA t4,dskw10
|
||
|
||
dskw20: SETAM t3,dsbfoh+.BFPTR
|
||
CAIE count,dsksize ; check if disk block full (*JMR*)
|
||
CALL filnul
|
||
MOVNI t3,9(count) ; calculate number of full words(*JMR*)
|
||
IDIVI t3,5 ; in the buffer (*JMR*)
|
||
HRLZ t3,t3 ; make an AOBJN pointer out of (*JMR*)
|
||
HRR t3,dsbfoh+.BFADR ; it (*JMR*)
|
||
ADDI t3,1 ; (*JMR*)
|
||
MOVEI t4,1 ; bit to clear (*JMR*)
|
||
dskw30: AOBJP t3,dskw40 ; more words to clear bit in? (*JMR*)
|
||
ANDCAM t4,(t3) ; yes, clear least significant (*JMR*)
|
||
JRST dskw30 ; bit and loop (*JMR*)
|
||
|
||
dskw40: SKIPE tcrdev ; tmpcore?
|
||
JRST tcrwri ; yes
|
||
OUT dsk,
|
||
JRST[ SETZM 1(p) ; all's well
|
||
POPJ p,]
|
||
STATZ dsk,IO.ERR ; hard error?
|
||
bugerr <DSKWRITE: Hard error.Error code later>
|
||
bugerr <DSKWRITE: Strange error>
|
||
|
||
tcrwri: HLLZ t4,dslkbk+.RBNAM ; get filename
|
||
MOVN t5,count ; negative number of bytes to write
|
||
IDIVI t5,5 ; convert
|
||
JUMPE t6,tcrw10 ; into
|
||
SUBI t5,1 ; words
|
||
tcrw10: HRLZ t5,t5 ; make an
|
||
HRRI t5,dsbuf1+2 ; IOWD
|
||
MOVE t3,[.TCRWF,,t4]
|
||
TMPCOR t3, ; write the TMP: file
|
||
JRST[ MOVEI t0,ERNRM% ; too large possibly
|
||
JRST fatal]
|
||
SETZM 1(p) ; all's well
|
||
POPJ p,
|
||
|
||
filnul: SETZ t0, ; if not, nullpad last word (*JMR*)
|
||
TLNN t3,37B22 ; check if thru last word (*JMR*)
|
||
POPJ p, ; done, exit from small loop (*JMR*)
|
||
IDPB t0,t3 ; store a null in buffer ring (*JMR*)
|
||
JRST filnul ; and loop back for next byte (*JMR*)
|
||
|
||
|
||
;=============================================================================
|
||
;FUNCTION dskclose: INTEGER;
|
||
;
|
||
;(* Closes the open file. Returns 0 if succesful,
|
||
; -1 if file not found, -2 otherwise. *)
|
||
|
||
dskclo::SKIPN ds.opn ; check if file is open
|
||
bugerr <DSKCLOSE: File is not open>
|
||
SKIPE tcrdev ; tmpcore?
|
||
JRST dskcl1 ; yes
|
||
RELEAS dsk, ; release the channel
|
||
SKIPN xxbak ; do we have backup?
|
||
JRST dskcl1 ; no we're finished
|
||
MOVE t1,orgnam ; get original name
|
||
SETAM t1,dslkbk+.RBNAM
|
||
MOVE t1,bakext ; get backupextension
|
||
HLLM t1,dslkbk+.RBEXT
|
||
MOVEI t0,ERDNA% ; assume device not available
|
||
OPEN dsk,dsopbk ; open the device
|
||
JRST fatal ; sorry...
|
||
LOOKUP dsk,dslkbk ; do we have an old backup file?
|
||
JRST newbak ; no
|
||
SETZ t0, ; yes
|
||
RENAME dsk,t0 ; delete old backup file
|
||
JRST[ MOVEI t0,errbkd ; can't delete old backup
|
||
JRST fatal]
|
||
newbak: MOVE t1,orgnam ; get original name back
|
||
SETAM t1,dslkbk+.RBNAM
|
||
MOVE t1,orgext ; get original extension back
|
||
HLLM t1,dslkbk+.RBEXT
|
||
MOVEI t0,ERDNA% ; assume device not available
|
||
OPEN dsk,dsopbk ; try open a device
|
||
JRST fatal
|
||
LOOKUP dsk,dslkbk ; lookup the original file
|
||
JRST rentmp ; never mind, perhaps we don't have one
|
||
|
||
SETOM proflg
|
||
HRRZ t2,dslkbk+.RBEXT ; get creation date
|
||
HLL t2,bakext ; get backup extension
|
||
tobakr: MOVEM t2,dslkbk+.RBEXT
|
||
RENAME dsk,dslkbk ; rename original file
|
||
JRST[ MOVEI t0,errbkr
|
||
SKIPN proflg ; have we tried before?
|
||
JRST fatal ; yes, tell'm we're sorry
|
||
LDB t1,[POINT 3,dslkbk+.RBPRV,2]
|
||
MOVEI t0,errbkr
|
||
CAIE t1,2 ; is it protection code 2 ?
|
||
JRST fatal ; no we can't rename
|
||
MOVE t1,orgext
|
||
HLLM t1,dslkbk+.RBEXT
|
||
MOVEI t1,1
|
||
DPB t1,[POINT 3,dslkbk+.RBPRV,2]
|
||
MOVEI t0,errbkr
|
||
RENAME dsk,dslkbk ; try to change the protection
|
||
JRST fatal ; can't lower prot, sorry
|
||
MOVEI t1,2
|
||
MOVE t1,orgpro
|
||
ANDI t1,477 ; safety measure in case of FILE DAEMON
|
||
DPB t1,[POINT ^D9,dslkbk+.RBPRV,^D8]
|
||
SETZM proflg ; don't try this again
|
||
JRST tobakr ; go try rename to backup name again
|
||
]
|
||
|
||
rentmp: MOVE t1,tmpnam ; get name of tmp-file
|
||
SETAM t1,dslkbk+.RBNAM
|
||
MOVE t1,tmpext ; get extension of tmp-file
|
||
HLLM t1,dslkbk+.RBEXT
|
||
MOVEI t0,ERDNA% ; assume device not available
|
||
OPEN dsk,dsopbk ; try open a device
|
||
JRST fatal
|
||
LOOKUP dsk,dslkbk ; lookup the tmp-file
|
||
JRST[ HRRZ t0,dslkbk+.RBEXT ; error
|
||
SKIPN t0
|
||
JRST warn
|
||
JRST fatal]
|
||
MOVE t1,orgnam ; get name of original file
|
||
SETAM t1,dslkbk+.RBNAM
|
||
MOVE t1,orgext ; get extension of original file
|
||
HLLM t1,dslkbk+.RBEXT
|
||
MOVE t1,orgpro ; get original protection
|
||
DPB t1,[POINT ^D9,dslkbk+.RBPRV,^D8]
|
||
RENAME dsk,dslkbk ; rename tmp-file to original file
|
||
JRST[ HRRZ t0,dslkbk+.RBEXT; failed, return with error code
|
||
SKIPN t0
|
||
JRST warn
|
||
JRST fatal]
|
||
RELEAS dsk, ; don't need device any more
|
||
SETZM xxbak ; reset backup flag
|
||
dskcl1: SETZM ds.opn ; file isn't open any more
|
||
SETZM tcrflg
|
||
SETZM tcrdev
|
||
SETZM notdir
|
||
setzm 1(p)
|
||
popj p,
|
||
|
||
|
||
|
||
;=============================================================================
|
||
;PROCEDURE dskmessage (VAR errstr: STRING);
|
||
;
|
||
;(* Returns latest disk-error. *)
|
||
|
||
;parameters
|
||
errstr==2
|
||
|
||
dskmes::CALL blanks ; blank the string
|
||
MOVE t1,errtab ; get what table
|
||
ADD t1,lsterr ; add offset into table
|
||
MOVE t1,(t1) ; get address of errorstring
|
||
HRLI t1,(POINT 7,0) ; make a bytepointer
|
||
MOVEI t4,strsiz ; max length of a string
|
||
MOVE t6,[POINT 7,(errstr)] ; make byte pointer to dest.
|
||
dskme1: ILDB t5,t1 ; get next char
|
||
JUMPE t5,dskme2 ; break on <NUL>
|
||
IDPB t5,t6 ; put byte in dest.
|
||
SOJG t4,dskme1 ; get next char, if room for more
|
||
dskme2: MOVEI t1,otherr
|
||
CAME t1,errtab ; misc. error?
|
||
popj p, ; no, just return
|
||
MOVEI t1,errbkr-errmis
|
||
CAME t1,lsterr ; errbkr error-code?
|
||
popj p, ; no, return
|
||
MOVE t6,[POINT 7,jobpos/5(errstr),<jobpos-jobpos/5*5>*7-1]
|
||
MOVE t1,[pOiNT 6,tmpnam] ; pointer to jobnumber in SIXBIT
|
||
MOVEI t4,3 ; mAx 3 digits in jobnumber
|
||
dskm10: ILDB t5,t1 ; get next digit
|
||
ADDI t5," " ; convert to ascii
|
||
IDPB t5,t6 ; store it
|
||
SOJG t4,dskm10 ; get next digit
|
||
popj p,
|
||
|
||
|
||
; routine to set latest error, argument in ac0, which is preserved on exit
|
||
seterr:
|
||
PUSH p,t0
|
||
PUSH p,t1
|
||
PUSH p,t2
|
||
CAILE t0,1000 ; misc. error?
|
||
JRST[ SUBI t0,errmis ; subtract to get offset
|
||
MOVEI t1,otherr ; use misc. error table
|
||
MOVEI t2,othmax ; check
|
||
JRST setchk ; boundaries
|
||
]
|
||
CAILE t0,100 ; parsing error codes are > 100
|
||
JRST[ SUBI t0,errnoe ; subtract first error to get offset
|
||
MOVEI t1,prserr ; use parsing error table
|
||
MOVEI t2,prsmax ; check
|
||
JRST setchk ; boundaries
|
||
]
|
||
MOVEI t1,monerr ; use monitor error table
|
||
MOVEI t2,monmax
|
||
setchk: JUMPL t0,setch1 ; IF offset < 0 OR
|
||
CAMG t0,t2 ; offset > max allowed
|
||
JRST seter1 ; THEN
|
||
setch1: MOVEI t1,errset ; use special error-error
|
||
SETZ t0, ; FI
|
||
seter1: SETAM t1,errtab ; set what table to use
|
||
SETAM t0,lsterr ; set latest error
|
||
CLOSE dsk, ; close the file
|
||
SETZM tcrflg
|
||
SETZM tcrdev
|
||
SETZM notdir
|
||
SETZM ds.opn ; and remember it
|
||
SETZM xxbak ; clear backup-flag too
|
||
POP p,t2
|
||
POP p,t1
|
||
POP p,t0
|
||
popj p,
|
||
|
||
|
||
fatal: CALL seterr ; set latest error
|
||
movx t1,-2
|
||
movem t1,1(p)
|
||
popj p,
|
||
|
||
warn: CALL seterr ; set latest error
|
||
setom 1(p)
|
||
popj p,
|
||
|
||
|
||
;=============================================================================
|
||
;High segment data and literals
|
||
|
||
tmppro: EXP 100 ; temporary protection
|
||
tmpext: SIXBIT 'TMP' ; temporary extension
|
||
bakext: SIXBIT 'BAK' ; backup extension
|
||
|
||
;special error-error
|
||
errset: [ASCIZ "UNK? Unknown error in DSKIO"]
|
||
|
||
;error table, misc. errors
|
||
otherr:
|
||
errmis==1001
|
||
[ASCIZ "IOF? This is no error"]
|
||
errbkd==1002
|
||
[ASCIZ "IOF? Can't delete old backup file"]
|
||
errbkr==1003
|
||
[ASCIZ "IOF? Backup failed, saving as nnnAMI.TMP"]
|
||
; 123456789012345678901234567890^
|
||
jobpos==^D31-1
|
||
errccd==1004
|
||
[ASCIZ "CCD? Can't change directory"]
|
||
othmax==.-otherr-1
|
||
|
||
;error table, parsing errors.
|
||
prserr:
|
||
;40 chars: " "
|
||
[ASCIZ "FSE? No error, success"] ;errnoe==101
|
||
[ASCIZ "FSE? Illegal character in filespec."] ;erricf==102
|
||
[ASCIZ "FSE? Too long field in filespecification"] ;errtlf==103
|
||
[ASCIZ "FSE? Duplicate filespec"] ;errdfn==104
|
||
[ASCIZ "FSE? Duplicate extension"] ;errdex==105
|
||
[ASCIZ "FSE? Double directory"] ;errddr==106
|
||
[ASCIZ "FSE? Colon, but no device"] ;errcnd==107
|
||
[ASCIZ "FSE? Duplicate device"] ;errddv==110
|
||
[ASCIZ "FSE? Illegal separator in directory"] ;errils==111
|
||
[ASCIZ "FSE? Too many sfds"] ;errtms==112
|
||
[ASCIZ "FSE? Null sfd"] ;errnls==113
|
||
[ASCIZ "FSE? Illegal format for directory"] ;errilf==114
|
||
[ASCIZ "FSE? Illegal protection code"] ;errilp==115
|
||
[ASCIZ "FSE? Duplicate protection"] ;errdpr==116
|
||
[ASCIZ "FOO? Cannot write 8-bit files"] ;errnw8==117
|
||
prsmax==.-prserr-1
|
||
|
||
|
||
;LOOKUP/ENTER/RENAME/GETSEG/RUN ERROR CODES "
|
||
monerr:
|
||
[ASCIZ "IOE? File not found"] ;ERFNF%==0
|
||
[ASCIZ "IOE? Incorrect ppn"] ;ERIPP%==1
|
||
[ASCIZ "IOE? Protection failure"] ;ERPRT%==2
|
||
[ASCIZ "IOE? File being modified"] ;ERFBM%==3
|
||
[ASCIZ "IOE? Already existing file name"] ;ERAEF%==4
|
||
[ASCIZ "IOE? Illegal sequence of uuos"] ;ERISU%==5
|
||
[ASCIZ "IOE? Transmission error"] ;ERTRN%==6
|
||
[ASCIZ "IOE? Not a save file"] ;ERNSF%==7
|
||
[ASCIZ "IOE? Not enough core"] ;ERNEC%==10
|
||
[ASCIZ "IOE? Device not available"] ;ERDNA%==11
|
||
[ASCIZ "IOE? No such device"] ;ERNSD%==12
|
||
[ASCIZ "IOE? Ill. mon. call for getseg and filop"] ;ERILU%==13
|
||
[ASCIZ "IOE? No room"] ;ERNRM%==14
|
||
[ASCIZ "IOE? Write-locked"] ;ERWLK%==15
|
||
[ASCIZ "IOE? Not enough table space"] ;ERNET%==16
|
||
[ASCIZ "IOE? Partial allocation"] ;ERPOA%==17
|
||
[ASCIZ "IOE? Block not free"] ;ERBNF%==20
|
||
[ASCIZ "IOE? Can't supersede a directory"] ;ERCSD%==21
|
||
[ASCIZ "IOE? Can't delete non-empty directory"] ;ERDNE%==22
|
||
[ASCIZ "IOE? Sfd not found"] ;ERSNF%==23
|
||
[ASCIZ "IOE? Search list empty"] ;ERSLE%==24
|
||
[ASCIZ "IOE? Sfd nest level too deep"] ;ERLVL%==25
|
||
[ASCIZ "IOE? No-create for all s/l"] ;ERNCE%==26
|
||
[ASCIZ "IOE? Segment not on swap space"] ;ERSNS%==27
|
||
[ASCIZ "IOE? Can't update file"] ;ERFCU%==30
|
||
[ASCIZ "IOE? Low seg overlaps hi seg (getseg)"] ;ERLOH%==31
|
||
[ASCIZ "IOE? Not logged in (run)"] ;ERNLI%==32
|
||
[ASCIZ "IOE? File has outstanding locks set"] ;ERENQ%==33
|
||
[ASCIZ "IOE? Bad .EXE file directory (getseg,run"] ;ERBED%==34
|
||
[ASCIZ "IOE? Bad ext. for .EXE file(getseg,run)"] ;ERBEE%==35
|
||
[ASCIZ "IOE? .EXE directory too big(getseg,run)"] ;ERDTB%==36
|
||
[ASCIZ "IOE? TSK - exceeded network capacity"] ;ERENC%==37
|
||
[ASCIZ "IOE? TSK - task not available"] ;ERTNA%==40
|
||
[ASCIZ "IOE? TSK - undefined network node"] ;ERUNN%==41
|
||
[ASCIZ "IOE? Rename - sfd is in use"] ;ERSIU%==42
|
||
[ASCIZ "IOE? Delete - file has an ndr lock"] ;ERNDR%==43
|
||
[ASCIZ "IOE? Job count high (A.T. read cnt ovrfl"] ;ERJCH%==44
|
||
[ASCIZ "IOE? Cannot rename sfd to a lower level"] ;ERSSL%==45
|
||
monmax==.-monerr-1
|
||
|
||
|
||
LIT
|
||
|
||
|
||
|
||
;=============================================================================
|
||
;Lowsegment storage
|
||
|
||
RELOC
|
||
|
||
; OPEN block
|
||
dsopbk: EXP 0 ; I/O status and flags
|
||
EXP 0 ; Sixbit device name or UDX
|
||
dsbfoh,,dsbfih ; Buffer ring header pointers
|
||
dsopln==.-dsopbk
|
||
|
||
; LOOKUP/ENTER block
|
||
dslkbk: EXP dslkln ; .RBCNT, Number of args following
|
||
XWD 0,dslkpt ; .RBPPN, Pointer to path
|
||
BLOCK .RBDEV+1-.RBNAM
|
||
dslkln==.-dslkbk-1
|
||
|
||
; Job's PPN (*JMR*)
|
||
jobppn: BLOCK 1 ; Logged in PPN (*JMR*)
|
||
|
||
; PATH.-block
|
||
dslkpt: BLOCK .PTMAX+1
|
||
|
||
prslen: BLOCK 1 ;String length when parsing file names.
|
||
prsarg: block 1 ;Special input pointer for parser.
|
||
|
||
tcrsiz: BLOCK 1 ; place to save number of read words
|
||
|
||
tcrdev: BLOCK 1 ; flag for TMP:
|
||
tcrflg: BLOCK 1 ; flag for reading TMP:
|
||
notdir: BLOCK 1 ; flag for non-directory devices
|
||
ds.opn: EXP 0 ; file-is-open flag
|
||
|
||
; buffer ring headers
|
||
dsbfoh: BLOCK 3 ; output header
|
||
dsbfih: BLOCK 3 ; input header
|
||
|
||
|
||
; buffers
|
||
dsbuf1: BLOCK 3 ; first buffer
|
||
BLOCK dsksiz/5
|
||
dsbuf2: BLOCK 3 ; second buffer
|
||
BLOCK dsksiz/5
|
||
dsbuf3: BLOCK 3 ; third buffer
|
||
BLOCK dsksiz/5
|
||
dsbuf4: BLOCK 3 ; fourth buffer
|
||
BLOCK dsksiz/5
|
||
dsbuf5: BLOCK 3 ; fifth buffer
|
||
BLOCK dsksiz/5
|
||
dsbuf6: BLOCK 3 ; sixth buffer
|
||
BLOCK dsksiz/5
|
||
|
||
; data for backup
|
||
tmpnam: BLOCK 1 ; temporary filename
|
||
orgpro: BLOCK 1 ; original protection
|
||
orgnam: BLOCK 1 ; original file name
|
||
orgext: BLOCK 1 ; original extension
|
||
xxbak: BLOCK 1 ; backup flag
|
||
|
||
; storage for the error-handler
|
||
errtab: BLOCK 1 ; pointer to last error tabel
|
||
lsterr: BLOCK 1 ; offset into last error table
|
||
|
||
proflg: BLOCK 1 ; protection-code flag
|
||
|
||
cvseen: EXP 0 ; CTRL-V flag
|
||
|
||
save.n: BLOCK 1 ; place to save pointer to filename
|
||
savpos: BLOCk 1 ; place to save position in filename
|
||
|
||
blknum: BLOCK 1 ; number of blocks in file
|
||
|
||
TCRBUF: BLOCK 50 ;Buffer for TMP:EDS reading/writing.
|
||
RSCCNT: block 1 ;Count of argument chars rescanned.
|
||
|
||
RUNBLK:: ;[JE] Argument for /RUN:file
|
||
RUNDEV::!EXP 0 ;Device.
|
||
RUNFIL::!EXP 0 ;File name.
|
||
RUNEXT::!EXP 0 ;Extension.
|
||
EXP 0 ;Some zero word.
|
||
RUNPPN::!EXP 0 ;PPN.
|
||
EXP 0 ;Another zero word.
|
||
|
||
EXPFIL: BLOCK ^D11 ;Expand file name here.
|
||
|
||
PG.VAL: BLOCK 1 ;Value of /Page:nn
|
||
LN.VAL: BLOCK 1 ;Value of /Line:nn
|
||
CH.VAL: BLOCK 1 ;Value of /Char:nn
|
||
|
||
FLAG8: BLOCK 1 ;Byte size of input file.
|
||
|
||
END
|