Trailing-Edge
-
PDP-10 Archives
-
tops20tools_v6_9-jan-86_dumper
-
tools/sed-for-vms/sed1jo.mar
There are 5 other files named sed1jo.mar in the archive. Click here to see a list.
.TITLE SED1JO - SED Journaling Routines
.LIBRARY /SEDITB.MLB/
.ENABLE DEBUG
.DISABLE GLOBAL
.PSECT CODE,NOWRT,EXE,LONG
PRMDEF ;Define the SED parameters
FLGDEF ; and the flag bits
SEQDEF ; and the command codes
;Subroutines to manipulate the journal file
;(Controlled by the /JOURN and /RECOV switches)
;Subroutine to start up the journal file (SEDJRN.TMP)
;R1 R2 preserved; frags R3
JRNSTT::BSBW JRNCLS ;Close and delete previous file
MOVL R5,JRNPTR ;Save type-out pointer
MOVAB JOURNL,R5 ;Point to JRN buffer
MOVAB FILSPC,R1 ;Get current file specs
MOVL DISPTR,R4 ;and display pointer
JSB EXIFIL ;Output the status of the active file
DECL R5 ;Back up over the null
TSTB JRNCRE ;Is this file being created?
BEQL 5$ ;No
MOVAB JCRMSG,R1 ;Yes - output /CREATE
JSB PUTSTG
5$: MOVW #^X0A0D,(R5)+ ;End the line with CRLF
TSTB OLDSPC ;Is there an alternate file?
BNEQ 10$ ;Yes
BRW JRNST0 ;No - don't output its status
10$: MOVAB OLDSPC,R1 ;Get alternate file specs
MOVL SL,R4 ;and slide value
MOVL SAVESL,SL
MOVL R4,SAVESL
MOVL SAVEDP,R4 ;and display pointer
MOVQ R7,SAVEAC+8
MOVQ SAVERW,R7
JSB EXIFIL ;Output the status of the alternate file
DECL R5 ;Back up over the null at the end
MOVW #^X0A0D,(R5)+ ;End the line with CRLF
MOVQ SAVEAC+8,R7
MOVL SL,R1
MOVL SAVESL,SL
MOVL R1,SAVESL
JRNST1: MOVL R5,R1 ;Save journal buffer pointer, get type-out ptr
MOVL JRNPTR,R5
MOVL R1,JRNPTR
CVTBL #-1,JRNBIT ;Note that first file write has not been done
MOVAB JOURNL+JRNSIZ,JRNENP ;Save pointer to end of journal
10$: CMPL JRNPTR,JRNENP ;Already written too much?
BLSS 20$ ;No
ADDL #JRNSIZ,JRNENP ;Yes - recalculate the end pointer
BRB 10$
20$: BICL #M_JRO,F1 ;Note that journal file is closed
MOVZBL #1,JRNDSK ;Say writing disk block 1
RSB
JRNST0: MOVW #^X0A0D,(R5)+ ;No alternate file - output a CRLF
BRB JRNST1 ;and finish off
JCRMSG: .ASCIZ "/CREATE"
;Subroutine to save a character in the journal buffer & output it if full
;Call with character in R1; R3 is fragged
JRNSVA::MOVL R1,SAVEAC ;Preserve the character
CMPB R1,#^A"^" ;Got a real up-arrow?
BEQL JRSVA1 ;Yes
CMPB R1,#^A"$" ; or a dollar sign?
BEQL JRSVA1 ;Yes
MOVB R1,JRNTMP ;No - set up the character buffer
CLRB JRNTMP+1
BRB JRSVC0 ;Output the character and return
JRSVA1: MOVB #^A"^",JRNTMP ;Precede the character with an up-arrow
MOVB R1,JRNTMP+1 ;Save the character
CLRB JRNTMP+2
BRB JRSVC0 ;Output the character and return
;Subroutine to save a command in the journal buffer & output it if full
;Call with command index in R9; R1, R3 fragged
JRNSVC::CMPB R9,#^O56 ;Got a help command?
BNEQ 20$ ;No
10$: RSB ;Yes - don't save it
20$: CMPB R9,#$ABORT ; or an abort command?
BEQL 10$ ;Yes
MOVL CMDNAM[R9],JRNTMP ;Get the command name
CMPL JRNTMP,#^A/$ / ;Is it enter parameter?
BNEQ 25$ ;No
CLRL JRNTMP+1 ;Yes - it's only one character long
25$: CLRL JRNTMP+4
CMPL R9,#^O15 ;Got a return command?
BNEQ 30$ ;No
MOVL #^X00000A0D,JRNTMP+3 ;Yes - follow it with a real CRLF
30$: CMPB JRNTMP+3,#^A" " ;Four-character code?
BNEQ JRSVC0 ;Yes
CLRB JRNTMP+3 ;No - end with a null
JRSVC0: BITL #M_XCT!M_XBN,F1 ;Executing or restoring a journal?
BNEQ JRSVC2 ;Yes - don't do any saving
JRSVC3: TSTL JRNPTR ;Is the journal pointer set up?
BEQL JRSVC2 ;No - must not be editing a file
MOVL R2,-(SP) ;Save R2
MOVL JRNPTR,R2 ;Get ptr to journal buffer
MOVAB JRNTMP,R0 ;Point to the command mnemonic
JRSVC1: MOVB (R0)+,(R2)+ ;Save the character
CMPL R2,JRNENP ;Done all characters?
BNEQ 10$ ;No
BSBB JRNSVO ;Yes - output it
10$: TSTB (R0) ;At the end of the string?
BNEQ JRSVC1 ;No - loop through command name
MOVL R2,JRNPTR ;Yes - save journal pointer
MOVL (SP)+,R2 ; and restore R2
JRSVC2: MOVL SAVEAC,R1 ;Restore R1
RSB ;Done
;Subroutine to save an execute call in the journal buffer & output it if full
;Call with execute index in R9; R1, R3 fragged
JRNSVX::MOVW #^A"^X",JRNTMP ;Get "^X" for journal
ADDB3 #^O100,R9,JRNTMP+2 ;Store ascii version of execute index
BRB JRSVC3 ;Output the string and return
;Subroutine to write out the journal buffer
JRNSVO: MOVL R0,-(SP) ;Save R0
MOVL R1,SAVEAC+4 ;Save R1
CLRB (R2) ;End the buffer with a null
BBCS #V_JRO,F1,5$ ;Is the journal file already open?
BRW JRSVO1 ;Yes
5$: TSTL JRNBIT ;No - has the file been written to?
BEQL 10$ ;Yes
$FAB_STORE FAB=JRN_FAB,FOP=SUP ;No - prepare to open for first time
BRB 20$
10$: $FAB_STORE FAB=JRN_FAB,FOP=CIF ;Yes - prepare to continue file
20$: $FAB_STORE FAB=JRN_FAB,FAC=<BIO,PUT>,RFM=STM,-
ORG=SEQ
CLRW JRN_FAB+FAB$W_IFI
CLRL JRNBIT ;Mark journal file as open
$CREATE FAB=JRN_FAB ;Open the file
BLBS R0,30$ ;Any errors?
MOVL JRN_FAB+FAB$L_STV,R1 ;Yes - get the auxiliary error number
MOVAB JRCRER,R2 ;and point to the right error message
BRW JRNSVE ;Output the errors and return
30$: $RAB_STORE RAB=JRN_RAB,ROP=BIO
$CONNECT RAB=JRN_RAB ;Connect the record stream
BLBS R0,JRSVO1 ;Go if no error
MOVL JRN_RAB+RAB$L_STV,R1 ;Get the auxiliary error number
MOVAB JRCRER,R2 ;and the right error message address
BRW JRNSVE ;Output the errors and return
JRSVO1: $RAB_STORE RAB=JRN_RAB,BKT=JRNDSK,RBF=JOURNL,RSZ=#512,-
UBF=#0,USZ=#0 ;Point to the disk block and buffer
$WRITE RAB=JRN_RAB ;Output the block
BLBS R0,10$ ;If errors,
MOVL JRN_RAB+RAB$L_STV,R1 ;Get the auxiliary error number
MOVAB JRWRER,R2 ;Point to the right error message
BRW JRNSVE ;Output the error messages and return
10$: CMPL JRNENP,#JOURNL+JRNSIZ ;First write to this block?
BNEQ JRSVO2 ;No
$DISCONNECT RAB=JRN_RAB ;Yes - checkpoint the file
$CLOSE FAB=JRN_FAB
BICL #M_JRO,F1 ;Mark file as closed
JRSVO2: CMPL JRNENP,#JOURNL+512 ;At end of the buffer?
BLSS 10$ ;No
INCL JRNDSK ;Yes - bump disk block number
PUSHR #^M<R1,R2,R3,R4,R5> ;Clean out the journal buffer
MOVC5 #0,JOURNL,#0,#512-JRNSIZ,JOURNL+JRNSIZ
POPR #^M<R1,R2,R3,R4,R5>
MOVAB JOURNL,R2 ;Restart at beginning of buffer
MOVAB JOURNL+JRNSIZ,JRNENP ;Reset the ending pointer
BRB 20$
10$: ADDL #JRNSIZ,JRNENP ;Not at end - bump end pointer
CMPL JRNENP,#JOURNL+512 ;Beyond end now?
BLEQ 20$ ;No
MOVAB JOURNL+512,JRNENP ;Yes - point at the end
20$: MOVL SAVEAC+4,R1 ;Restore the saved R1
MOVL (SP)+,R0 ;Restore R0
RSB ;Done
;Subroutine to get rid of the journal file
JRNCLS::BBSC #V_JRO,F1,10$ ;Is the journal file open?
CLRW JRN_FAB+FAB$W_IFI ;Make sure IFI is cleared
$OPEN FAB=JRN_FAB ;Open the file so it can be deleted
BRB 20$
10$: $DISCONNECT RAB=JRN_RAB ;Yes - close and delete it
20$: $FAB_STORE FAB=JRN_FAB,FOP=DLT
$CLOSE FAB=JRN_FAB
RSB ;Done
;Routine to output error messages for writing journal
;If an error occurs, delete the journal file and stop journaling
JRNSVE: MOVL R1,-(SP) ;Save the error codes
MOVL R0,-(SP)
MOVL R2,R1 ;Point to the correct error message
BSBW ERRDSP ;Output it
MOVL (SP)+,R0 ;Get the main error code
JSB GETMSG ;Get the text of the system error message
MOVZWL ERROR_MESS_LENGTH,R1
CLRB L^ERROR_MESSAGE(R1) ;Make the system text into .ASCIZ
MOVAB ERROR_MESSAGE,R1
BSBW ERRDSP ;and output the system message
MOVL (SP)+,R0 ;Get the auxiliary message
JSB GETMSG ;Get the text
MOVZWL ERROR_MESS_LENGTH,R1
CLRB L^ERROR_MESSAGE(R1) ;Make it into .ASCIZ
MOVAB ERROR_MESSAGE,R1
BSBW ERRDSP ;and output the auxiliary message
BSBW JRNCLS ;Close and delete the journal
BICL #M_JRW,F1 ;Clear the journal save flag
MOVAB JOURNL,R2 ;Point to the journal buffer
MOVL SAVEAC+4,R1 ;Restore the saved R1
MOVL (SP)+,R0 ;Restore R0
RSB ;Finish off and return
JRCRER: .ASCIZ /Error creating journal file - journal aborted/
JRWRER: .ASCIZ /Error writing journal file - journal aborted/
;Here to read from journal - from XCTGET, when JRC (and XCT or XBN) is set
LOPJRN::BSBW LOPJRR ;Get a real character from the journal
CMPB R1,#^A"$" ;Got an escape command?
BNEQ 10$ ;No
MOVZBL #^O33,R1 ;Yes - get its index
JMP LOOP2 ;and use it
10$: CMPB R1,#^A"^" ;Got a type-in character?
BEQL 20$ ;Yes
25$: JMP ALPNUM ;No - just put it in file or buffer
20$: BSBW LOPJRR ;Yes - get first character of command
CMPB R1,#^A"$" ;Really want a real dollar sign?
BEQL 25$ ;Yes
CMPB R1,#^A"^" ; or an up-arrow?
BEQL 25$ ;Yes
MOVL #^A"^ ",JRNTMP ;Prepare to assemble command
MOVB R1,JRNTMP+1 ;Save the second character
MOVAB JRNTMP+2,R6 ;Point to the next position
BSBB LOPJRC ;Get rest of command name
CMPL JRNTMP,#^A"^RF " ;Got a roll forward?
BEQL LOPJR2 ;Yes
CMPL JRNTMP,#^A"^RB " ;or a roll backward?
BNEQ LOPJR1 ;No
LOPJR2: BSBB LOPJRC ;Get rest of command name
LOPJR1: MOVL JRNTMP,R6 ;Get the command
MOVL #CMDLEN-4,R1 ;Look for command among names
ASHL #-2,R1,R1 ;Convert to longword count
10$: CMPL R6,CMDNAM[R1] ;Is this it?
BEQL 20$ ;Yes
SOBGEQ R1,10$ ;No - keep looking
20$: TSTL R1
BLSS 30$
JMP LOOP2 ;Process command, if that's what it is
30$: CMPW JRNTMP,#^A"^X" ;First two characters an execute sequence?
BEQL 40$ ;Yes
BRW JRRERR ;No - it's an error
40$: MOVZBL JRNTMP+2,R1 ;Yes - get execute index (+ ^O100) in R1
JMP ILCER0 ;Go process the execute
LOPJRC: BSBB LOPJRR ;Get character from the journal
MOVB R1,(R6)+ ;Put it in with the rest
RSB ;Done
LOPJRR: MOVZBL @JRNPTR,R1 ;Get a character from the journal
INCL JRNPTR
CMPB R1,#^A" " ;Control character or null?
BLSS 10$ ;Yes
RSB ;No - return
10$: TSTB R1 ;Null?
BNEQ LOPJRR ;No - ignore control characters
BSBW JRNRED ;If null, read another piece of the journal
BRB LOPJRR ;Get a character from it and return
;Subroutine for recovering the journal:
;Open the journal, read the first bufferful of commands,
;and set up the file and alternate
JRNGET::CLRL JRNFLG ;Say there's more file to come
CLRB RSCANF ;Forget file given in rescan
$FAB_STORE FAB=JRN_FAB,FAC=<GET,BIO>,FOP=#0
CLRW JRN_FAB+FAB$W_IFI
$OPEN FAB=JRN_FAB
BLBS R0,10$ ;Any errors?
BRW JRNERR ;Yes
10$: $RAB_STORE RAB=JRN_RAB,RBF=#0,RSZ=#0,UBF=JOURNL,USZ=#512
$CONNECT RAB=JRN_RAB
BLBS R0,20$
BRW JRNERR
20$: MOVZBL #1,JRNDSK ;Set the first disk block number
BSBB JRNRED ;Read the first block of the journal
MOVAB JOURNL,R2
MOVAB FILSPC,R3 ;Read current filespecs
BSBB JRNCPY
SUBL3 #FILSPC,R1,FSPLEN ;Save length of the filespec
MOVAB OLDSPC,R3 ;Read old filespecs
BSBB JRNCPY
SUBL3 #OLDSPC,R1,OLDLEN ;Save length of the old filespec
MOVL R2,JRNPTR ;Save the pointer into the journal
RSB ;Done
JRNRED: TSTL JRNFLG ;Is there more file to read?
BEQL 10$ ;Yes
BRW JRNEND ;No - done
10$: MOVAB JOURNL,JRNPTR ;Yes - reset pointer into buffer
$RAB_STORE RAB=JRN_RAB,BKT=JRNDSK ;Store block to read
$READ RAB=JRN_RAB ;Read the block
BLBS R0,20$ ;Reached end of file or error?
BRB JRNDUN ;Yes - note that end of file has been reached
20$: INCL JRNDSK ;No - bump number of disk block
RSB ;Read successful - done
;Subroutine to copy filespecs from (R2) to (R3) until a carriage return
JRNCPY: CLRL R1 ;Clear pointer to start of switches
10$: CMPB (R2),#^O15 ;Is next char a CR?
BEQL 30$ ;Yes - finish off
CMPB (R2),#^A"/" ;Is it start of switches?
BNEQ 20$ ;No
TSTL R1 ;Already found start of switches?
BNEQ 20$ ;Yes
MOVL R3,R1 ;No - save starting point
20$: MOVB (R2)+,(R3)+ ;No - transfer a character
BRB 10$ ; and get more
30$: INCL R2 ;Skip over the carriage return
INCL R2 ;and the linefeed
TSTL R1 ;Any switches found?
BNEQ 40$ ;Yes
MOVL R3,R1 ;No - better save a pointer
40$: CLRB (R3) ;End filespecs with a null
RSB ;Done
;Here when recovering, when end of journal file is reached
JRNDUN: CVTBL #-1,JRNFLG ;Say end of file has been reached
CLRB JOURNL ;Make sure end of file is taken
$DISCONNECT RAB=JRN_RAB
$CLOSE FAB=JRN_FAB ;Close the file
RSB ;Done
JRNEND: MOVAB JOURNL,JRNPTR ;Initialize the journal buffer pointer
TSTL JRNBIT ;Want to keep appending to this journal?
BEQL JRNEN1 ;No - don't initialize
BISL #M_JRW,F1 ;Yes - note that journal is now being written
PUSHR #^M<R1,R2,R3,R4,R5> ;Clean out the journal buffer
MOVC5 #0,JOURNL,#0,#512-JRNSIZ,JOURNL+JRNSIZ
POPR #^M<R1,R2,R3,R4,R5>
MOVAB JOURNL+JRNSIZ,JRNENP ;Save pointer to end of journal buffer
CLRL JRNBIT
JRNEN1: MOVAB JN1MSG,R1
BRB JRNER1
JRNERR: MOVAB JREMSG,R1
JRNER1: BICL #M_XCT!M_JRC!M_JRO,F1 ;End the journal restore
BBSC #V_XBN,F1,10$ ;Need to display the file?
MOVL R1,-(SP) ;Save pointer to the message
JSB DISPLL ;Yes - go do so
MOVL (SP)+,R1 ;Restore the message pointer
10$: CLRL JRNFLG
BRW STFER1 ;Tell user that recovery is done
JRRERR: MOVAB JRRMSG,R1
BRB JRNER1
JRSERR: MOVAB JRSMSG,R1
BICL #M_JRW,F1 ;Don't do journaling
BRW STFER1 ;Tell user that recovery is done
JN1MSG: .ASCIZ /#########File recovered/
JREMSG: .ASCIZ /#####Can't find journal file/
JRRMSG: .ASCIZ /######Bad command in journal/
JRSMSG: .ASCIZ /#####Can't write journal file/
GLOB ;Define the global symbols
.END