home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
decpro300.tar.gz
/
decpro300.tar
/
prodf.mac
< prev
next >
Wrap
Text File
|
1988-08-16
|
9KB
|
326 lines
.TITLE KERDF - Default file processing routines
.SBTTL N Bush
; Version 1.0.000
.IDENT /1.0.000/
; Directives
.LIBRARY /KERMLB/ ; Pro/Kermit macro library
.LIBRARY /LB:[1,5]RMSMAC/ ; RMS-11 macro library
.SBTTL Revision History
;
; 1.0.000 By: Nick Bush On: 19-December-1983
; Create this module
;
.SBTTL .MCALLs for RSX and RMS directives
; The following are the various MCALLs that KERXK uses.
.MCALL FAB$B ; To build FAB for RMS
.MCALL RAB$B ; To build RAB for RMS
.MCALL $OPEN ; Open a file using RMS
.MCALL $CLOSE ; Close a file using RMS
.MCALL $CONNECT ; Connect RAB to FAB
.MCALL $DISCONNECT ; Disconnect RAB and FAB
.MCALL $GET ; Read a record
.MCALL $PUT ; Write a record
.MCALL $UPDATE ; Update record in place
.MCALL $REWIND ; Rewind stream
.MCALL $CREATE ; Create a file
.MCALL $STORE ; Store an RMS field
.MCALL $FETCH ; Fetch an RMS field
.MCALL $COMPARE ; Compare value with RMS field
.MCALL ORG$ ; Declare type of file access we need
ORG$ SEQ,<CRE,GET,PUT,UPD> ; Type of access we need
; The following causes the KERMIT definitions to be read and defined
.MCALL KERDEF ; Get the KERMIT definitions
KERDEF ; Define all of the KERMIT symbols
.MCALL BLOCK ; Macro to define blocks
.MCALL MSG ; Text definition macro
.SBTTL Local symbol definitions
; The following are some local symbol defintions used in the defaults file
;processing
DF.MRS= 64. ; Maximum record size is 64.
; A record in the defaults file is of the form:
;*** Insert box here
BLOCK DF ; Define DF.xxx symbols for record offsets
.X RTP ; Record type code
.XX RSZ ; Size of data portion of record
.XX OFS ; Offset to data portion of record
.X HLN,0 ; Length of header
.SBTTL Impure storage
; The following are the local impure storage locations for KERDF.
.PSECT $OWN$, D
DF.FAB: FAB$B ; Define the FAB
F$FAC FB$GET!FB$PUT!FB$UPD ; Want to be able to do a few operations
F$FNA M$DFLN ; Address of name string
F$FNS DFLN$L ; Length of name string
F$LCH DFLLUN ; Logical unit number to use
F$MRS DF.MRS ; Maximum record size
F$ORG FB$SEQ ; Sequential file
F$RFM FB$FIX ; Fixed record length
FAB$E ; End of FAB
DF.RAB: RAB$B ; Define the RAB
R$FAB DF.FAB ; Address of FAB
R$RAC RB$SEQ ; Sequential access
R$RBF DF.BUF ; Record buffer address
R$RSZ DF.MRS ; Recurd buffer size
R$UBF DF.BUF ; User buffer address
R$USZ DF.MRS ; Buffer size
RAB$E ; End of RAB
DF.BUF: .BLKB DF.MRS ; Record buffer
DFLOPN: .BLKB 1 ; Flag whether file is open
DFLRCR: .BLKB 1 ; Flag whether record is current
.EVEN ; Back to word boundary
; Pure data
.PSECT $PLIT$,RO,D ; Put in correct place
MSG DFLN,<LB:[ZZKERMIT]ZZKERMIT.DAT> ; File name
.SBTTL DF.INI - Initialize the default file handling
;++
; This routine will initialize the default file processing. It will
;determine if the default file exists, and if not, it will create it
;as an empty file. The file will be left in a state such that we can
;read and write to it.
;
; Usage:
;
; Macro:
; JSR PC,DF.INI
; (Return here always)
;
;--
.PSECT $CODE$, RO
DF.INI::CLRB DFLRCR ; No current record at all
; First try to open the file
MOV #DF.FAB,R0 ; Point at the FAB
$OPEN R0 ; Open the file
$COMPARE #SU$SUC,STS,R0 ; Did we successfully open the file?
BEQ 10$ ; Yes, set up RAB
; Here if we could not open the file for some reason. Try to create a new
;one
$CREATE R0 ; Attempt to create the file
$COMPARE #SU$SUC,STS,R0 ; Could we?
BNE 15$ ; No, give up
; Here after file has either been OPENed or CREATEd. Connect up the RAB
10$: MOV #DF.RAB,R0 ; Point at the RAB
$CONNECT R0 ; Connect it up
$COMPARE #SU$SUC,STS,R0 ; Did it work?
BEQ 20$ ; Yes, remember that
MOV #DF.FAB,R0 ; No, point back at FAB
$CLOSE R0 ; Close the file
15$: CLRB DFLOPN ; And remember file is not open
RTS PC ; Give up
; Here when file is open and RAB connected. Remember the file is ok and return
20$: MOVB #1,DFLOPN ; Flag file is open
RTS PC ; And return
.SBTTL DF.FIN - Finish out default file processing
;++
; This routine will terminate the default file processing. It will
;close the defaults file.
;
; Usage:
;
; Macro:
; JSR PC,DF.FIN
; (return here always)
;
;--
DF.FIN::TSTB DFLOPN ; File open?
BEQ 99$ ; No, nothing to close
MOV #DF.RAB,R0 ; Point at RAB
$DISCONNECT R0 ; Disconnect it
MOV #DF.FAB,R0 ; Point at FAB
$CLOSE R0 ; Close the file
99$: RTS PC ; And return
.SBTTL DF.RD - Read a record from the default file
;++
; This routine will read a record from the default file. The record
;is identified by a 16-bit value which is expected to be in the first
;two bytes of the record. If the record is found, we will return a
;pointer to the first byte and the length in bytes.
;
; Usage:
;
; Macro:
;
; MOV #record.indicator,R0
; JSR PC,DF.RD
; (Return)
;
; On return:
; If record found:
;
; R0/ Address of first byte of record (after our header info)
; R1/ Length of record (minus header) in bytes
;
; If record not found:
;
; R0/ 0
; R1/ -1
;
;--
.PSECT $CODE$, RO
DF.RD:: TSTB DFLOPN ; File open?
BEQ 80$ ; No, just say we couldn't find the record
MOV #DF.RAB,R1 ; Point at RAB
$REWIND R1 ; Back up to beginning of file
$COMPARE #SU$SUC,STS,R1 ; Did it work?
BNE 80$ ; No, punt
; Now read through the file until we find the record we want
20$: $GET R1 ; Read a record
$COMPARE #SU$SUC,STS,R1 ; Get it?
BNE 80$ ; No, must have hit eof
CMP R0,DF.BUF ; Is this the record we want?
BNE 20$ ; If not the right record, try the next
; Here when we have found the correct record. Set up the pointers to the
;users data
MOVB DF.BUF+.DFOFS,R0 ; Get offset to first byte of user data
ADD #DF.BUF,R0 ; Point to it
MOVB DF.BUF+.DFRSZ,R1 ; And get the size of the data
MOVB #1,DFLRCR ; Flag current record is real
RTS PC ; And return
; Here if we could not find the record for some reason. Return the error
;indication to our caller, and remember that we have no current record.
80$: CLRB DFLRCR ; No current record
CLR R0 ; No data to return
MOV #-1,R1 ; . . .
RTS PC ; Let caller worry about it
.SBTTL DF.WT - Write a record to the default file
;++
; This routine will write a record to the default file. The record
;is identified by a 16-bit value which will be written as the first
;two bytes of the record.
;
; Usage:
;
; Macro:
;
; MOV #record.indicator,R0
; MOV #Record.address,R1
; MOV #record.size,R2
; JSR PC,DF.WT
; (Return)
;
;--
.PSECT $CODE$, RO
DF.WT:: TSTB DFLOPN ; File open?
BEQ 99$ ; No, just return
JSR R1,$SAVE2 ; Save R1/R2
TSTB DFLRCR ; Check if current record data ok
BEQ 30$ ; No, we must first find this record
CMP R0,DF.BUF+.DFRTP ; Correct record?
BNE 30$ ; No, attempt to read it first
; Here if last record read is the one we wish to replace. First we must
;copy the users data into our buffer, then we will just update the current
;record in the file
10$: MOV R2,DF.BUF+.DFRSZ ; Store new record size
MOVB #.DFHLN,DF.BUF+.DFOFS ; Store offset to record data
MOV #DF.BUF+.DFHLN,R0 ; Point at data storage
20$: MOVB (R1)+,(R0)+ ; Copy the data
SOB R2,20$ ; All of it
MOV #DF.RAB,R0 ; Point at the RAB
$STORE #DF.MRS,RSZ,R0 ; Store the record size
$UPDATE R0 ; Update the record
RTS PC ; And return
; Here if the last record was not valid or was not the same as the
;record being written. First attempt to find the correct record. If
;we can find it, we will just update it in place, otherwise, we will
;write the new record at the end of the file.
30$: MOV R0,-(SP) ; Save the record index
MOV R1,-(SP) ; And the address
JSR PC,DF.RD ; Attempt to find the record
TST R1 ; See if we found it
BMI 40$ ; If negative, no luck
MOV (SP)+,R1 ; Get back the address
MOV (SP)+,R0 ; and the type
BR 10$ ; And re-write the record
; Here if the record did not previously exist in the file. Write
;it out at the end of the file. The next-record context should be EOF, since
;DF.RD will have read to the end of the file.
40$: MOV (SP)+,R1 ; Restore the registers
MOV (SP)+,R0 ; . . .
MOV R0,DF.BUF+.DFRTP ; Store the record type
MOVB R2,DF.BUF+.DFRSZ ; And size
MOVB #.DFHLN,DF.BUF+.DFOFS ; And offset to data portion
MOV #DF.BUF+.DFHLN,R0 ; Point at first data byte
50$: MOVB (R1)+,(R0)+ ; Copy the byte
SOB R2,50$ ; All of them
MOV #DF.RAB,R0 ; Point at RAB
$STORE #DF.MRS,RSZ,R0 ; Store the record size
$PUT R0 ; Write the record
99$: RTS PC ; And return
.SBTTL End of KERDF
.END