* Prime 2.2
*
* XFER.ML1 - By John Hagen - O1 Oct 89
*
* An ML program to allow faster processing of
* files from within Xfer 6.XX.
*

GRANTLVL EQU $344 ;Access level granted by Prime
ERRCODE EQU $DE
OPENBUF EQU $4C00 ;I/O Buffer
POUT EQU $9344 ;Modem output routine
NMSTRING EQU $9880 ;User Data & Information (HBUFF)
BITLOCKS EQU NMSTRING+100 ;Start of Index Bytes
MLI EQU $BF00 ;MLI

RECRDLEN EQU 128

 ORG $6800 ;Buffer workspace

 JMP BEGIN ;To allow storage of temp data

* $6803 <26627>
FILETF DS 1 ;Total files in this Lbr

* $6804 <26628>
XFERMODE DS 1 ;Scan mode

* $6805 <26629>
RECRDNUM DS 1 ;Counter for current position

* $6806 <26630>
YYMMDD DS 3 ;Users file scan YYMMDD

* $6809 <26633>
VALIDFIL DS 1 ;Number of valid files to display

* $680A <26634>
FILENUMB DS 99 ;Flags for valid files to display

BEGIN TSX
 STX STACKSAV ;see HANDLERR
*
*  Put the File Name into the buffer
*
FILESET LDX #0 ;Clear the index
FILOOP LDA XFERFILE,X ;Get the filename character
 BEQ FILDONE ;Finished, go open the file
 STA PATHNAME+1,X ;Save the char
 INX ;Inc the char cntr
 BNE FILOOP ;Continue
FILDONE STX PATHNAME ;Save the char count

*
*  Open the file
*
FILEOPEN LDX #0 ;Clear the index
 JSR MLI ;Call the MLI
 HEX C8 ;OPEN
 DA POPEN ;OPEN Param list
 BEQ SETREFN ;MLI Call successful
 JMP HANDLERR ;MLI Error

*
*  Update all the file reference number pointers
*
SETREFN LDA OPREFNUM ;Get the ref number
 STA RDREFNUM ;For the READ command
 STA WRREFNUM ;For the WRITE command
 STA EOREFNUM ;EOF Command
 STA SOREFNUM ;SET_EOF command
 STA MKREFNUM ;READ MARK commands
 STA WMREFNUM ;WRITE MARK commands
 STA CLREFNUM ;CLOSE command

*
*  Time For The GET_EOF
*
GETEOF JSR MLI ;Call the MLI
 HEX D1 ;GET_EOF
 DA PEOF
 BEQ STARTPRG ;MLI Successful
 JMP HANDLERR ;MLI Error

*
*  Set up and initialize variables
*
STARTPRG LDA #0 ;Clear the data
 STA VALIDFIL ;Clear the valid files cntr
 STA WMARKPOS+2
 STA MARKPOS+2
 LDA XFERMODE ;Ck what mode we're in
 CMP #6 ;Are we in Mode 6?
 BEQ PRINTBUF ;Yes, bypass preset of RECRDNUM
 CMP #7 ;Are we in mode 7?
 BEQ PRINTBUF ;Yes, bypass preset of RECRDNUM
 LDA #1 ;Preset to avoid record 0
 STA RECRDNUM ; and the record counter

*
*  Work with the buffer contents
*
PRINTBUF JSR PRESETR ;Preset the markers
 JSR SETMARK ;Move the mark
 CLC
 LDA MARKPOS
 ADC #RECRDLEN
 STA MARKPOS
 LDA MARKPOS+1
 ADC #/RECRDLEN
 STA MARKPOS+1
 LDA #/RECRDLEN
 LDY #RECRDLEN
 STA RDCOUNT+1
 STY RDCOUNT
 JSR READFIL ;Read the next record

*
*  File Info in the buffer
*
 JSR ACCESS ;Set & ck access required
 JSR MODECK ;Ck status of this file
 LDA XFERMODE ;Get the mode
 CMP #7 ;Mode 7?
 BEQ PRINTBU1 ;Yes, back to BASIC
 JSR POSITION ;Update the actual position
 INC RECRDNUM ;Increment the file counter
 BCC PRINTBUF ;go back for more
PRINTBU1 RTS ;Back to BASIC

*
*  Check Mode for various bypasses
*
MODECK LDA XFERMODE ;What mode are we running?

*  0=Scan Files
MODECK0 CMP #0 ;Is it "S"can files?
 BNE MODECK1 ;Nope, keep looking
 JSR ACCESSCK ;See if it's a valid file
 JSR FILENOT ;See if it's a not displayed
 JSR FILETYPE ;See if correct filetype
 JMP FILEOK ;Set as valid file

*  1=Get Description
MODECK1 CMP #1 ;Is it "G"et Descriptions
 BNE MODECK2 ;Nope, keep looking
 JSR ACCESSCK ;See if it's a valid file
 JSR FILENOT ;See if it's a not displayed
 JSR FILETYPE ;See if correct filetype
 JMP FILEOK ;Set as valid file

*  2=File Info
MODECK2 CMP #2 ;Is it "F"ile Info?
 BNE MODECK3 ;Nope, keep checking
 JSR ACCESSCK ;See if it's a valid file
 JSR FILENOT ;See if it's a not displayed
 JSR FILETYPE ;See if correct filetype
 JMP FILEOK ;Set as valid file

*  3=List Files
MODECK3 CMP #3 ;Is it "L"ist Files?
 BNE MODECK4 ;Nope, keep checking
 JSR ACCESSCK ;See if it's a valid file
 JSR FILENOT ;See if it's a not displayed
 JSR FILETYPE ;See if correct filetype
 JMP FILEOK ;Set as valid file

*  4=New file scan
MODECK4 CMP #4 ;Is it the "N"ew files?
 BNE MODECK5 ;Nope, keep going
 JSR FILENEW ;Go see if it's a new file
 JSR ACCESSCK ;See if it's a valid file
 JSR FILETYPE ;See if correct filetype
 JMP FILEOK ;Set as valid file

*  5=Recent Upload
MODECK5 CMP #5 ;Is it the "R"ecent Uploads?
 BNE MODECK6 ;Nope, keep going
 JSR YEARS ;Go setup the date of the file
 JSR DATECK ;See if the date is okay
 JSR ACCESSCK ;See if it's a valid file
 JSR FILENOT ;See if it's a not displayed
 JSR FILETYPE ;See if correct filetype
 JMP FILEOK ;Set as valid file

*  6=Delete A Record
MODECK6 CMP #6 ;"D"elete & "R"emove Record?
 BNE MODECK7 ;Nope, keep going
MODECK6A CLC ;Clear the carry
 LDA FILETF ;How many files in this Lbr?
 CMP RECRDNUM ;Are they the same?
 BEQ MODECK6C ;Yes, just reset the EOF
 INC RECRDNUM
 JSR PRESETR ;Let's calculate the READ mark
 JSR PRESETW ;calc WRITE mark from READ mark
 DEC RECRDNUM
MODECK6B JSR SETMARK ;Mark READ start point
 INC MARKPOS+1 ;Inc the pointer
 INC MARKPOS+1 ; and once more
 LDA #/512
 LDY #512
 STA RDCOUNT+1
 STY RDCOUNT
 JSR READFIL ;Read the next set
 JSR WSETMARK ;Mark WRITE start point
 INC WMARKPOS+1 ;Inc the pointer
 INC WMARKPOS+1 ; and once more
 JSR WRITEFIL ;Write it back out
 CLC
 LDA RECRDNUM ;Load the file counter
 ADC #4 ;Add four records
 STA RECRDNUM ; and save it
 JSR POSITION ;See if we're finished
 BCC MODECK6B ;Nope, continue working
*
*  Now SET_EOF
*
MODECK6C
 LDA FILETF ;Load the new total files
 STA RECRDNUM ;New amount
 JSR PRESETR ;Preset the read marker
 LDA MARKPOS ;Load the LSByte
 STA SEOFVAL ;Store as LSByte
 LDA MARKPOS+1 ;Load the Middle Byte
 STA SEOFVAL+1 ;Save as the Middle Byte
 LDA MARKPOS+2 ;Load the MSByte
 STA SEOFVAL+2 ;Save as the MSByte
 JSR SETEOF ;Now SET_EOF
 RTS

*
* 7=Get One description
*
MODECK7 CMP #7 ;Is it to G>et One Description?
 BNE MODECK8 ;Nope, keep looking
 JSR ACCESSCK ;See if it's a valid file
 JSR FILENOT ;See if it's a Not displayed
 JSR FILETYPE ;See if computer type matches
 JMP FILEOK ;Set as valid file

*
* 8=Return for now
*
MODECK8 RTS  ;Back to basic

*
*  Set up the Bit Lock needed for access
*
ACCESS LDA #0 ;Clear the A
 STA ACCESLVL ; to clear the access lvl
 LDX #20 ;First Byte in Index Bits
 JSR READIT ;Go get the desired byte
 SEC
 SBC #'0' ;To get back to 0-9
 STA MTPC ;Save it for use
 LDA #10 ;Set the multiplier to 10
 STA MTPR ;Save it as the multiplier
 JSR MULTIPLY ;Go set up decimal stuff
 LDX #21 ;Last byte for the lock
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 CLC ;Clear the carry just in case
 ADC RESULT ;Add it to the first part
 STA LOCK ;Save as the bit lock number
 TAY ;Put it into the Y

*
*  File needs for access (security checks)
*
ACCESS1 LDX #22 ;Byte Level Required
 LDA BITLOCKS,Y ;Get users byte for access
 CMP #'Z' ;Is it a SysOp type user?
 BNE ACCESS2 ;Nope, keep checking
 LDA #3 ;Set up to save as a SysOp
 JMP ACCESS4 ;And save it
ACCESS2 JSR READIT ;Go get the byte
 CMP BITLOCKS,Y ;Do they have access?
 BEQ ACCESS3 ;Yes, it's equal, good file
 BCS ACCESSRT ;Access too low
ACCESS3 LDA #1 ;Access is GRANTED!
ACCESS4 STA ACCESLVL ;Save for users access
ACCESSRT RTS ;Back to routines

*
*  File is okay for display
*
FILEOK LDX VALIDFIL ;Get how many there are
 INC VALIDFIL ;Increment the valid file cnt
 LDA RECRDNUM ;To set the flag
 STA FILENUMB,X ;Set the file as valid
 RTS ;Back to ck next file

*
*  File Not Okay
*
FILEOKNO PLA ;Not a valid file, pop
 PLA ; both bytes
USEREXIT RTS ;Back to ck next file


*
*  Check for past end of position
*
POSITION LDA RECRDNUM ;How many have we checked?
 CMP FILETF ;Have we done them all?
 RTS ;return SEC = done

POSITIN1 LDA #0 ;Clear the accumulator
 LDA #$8D ;Carriage return
 JSR POUT ;Send to user
 JSR POUT ;One more for measure
 LDX #0 ;Clear the index
POSEOF LDA ENDUSERS,X ;Get TXT for EOF
 CMP #0 ;Finished yet?
 BEQ POSEND1 ;Yes, finish with a press key
 JSR POUT ;Send msg to screen
 INX ;Inc the index
 BNE POSEOF ;Always
POSEND1 LDA #20 ;Press any key char
 JSR POUT ;Send to the user
 JSR CLOSEALL ; and close the file
POSRTS RTS ;Back to BASic or the prg

*
*  Error Handler
*
STACKSAV DS 1 ;Save the Stack here
*
HANDLERR STA ERRCODE ;Save MLI error code
 LDX STACKSAV ;restore stack pointer
 TXS ;to the value it had on entry
 CMP #$40 ;Invalid pathname error?
 BEQ E2 ;That's it
 CMP #$44 ;Pathname not found?
 BEQ E2 ;That's it
 CMP #$45 ;Vol/Dir not found?
 BEQ E2 ;That's it
 CMP #$46 ;File not found?
 BEQ E2 ;That's it
 CMP #$4C ;EOF Yet?
 BEQ E4 ;That's it
 CMP #$4D ;Past Marker?
 BEQ E4 ;That's it
 CMP #$56 ;Buffer address bad?
 BEQ E2 ;That's it
 LDX #TXIOERR-ZTXT
 BNE E3 ;Always
E2 LDX #TXFNF-ZTXT
E3 JSR PRINT ;Print error msg
 LDA #$8D ;Carriage Return
 JSR POUT ;Send to the user
 JSR CLOSEALL ;Close the files
 RTS ;Finished, back to BASic
E4 JMP POSITIN1

*
*  Print Message
*
PRINT LDA ZTXT,X ;Get the character
 BEQ PRINTRTS ;If 00, then exit
 JSR POUT ;Send to the user
 INX ;Increment the counter
 BNE PRINT ;Always
PRINTRTS RTS ;Back to the main routine

*
*  READ the data from the file
*
READFIL JSR MLI ;Call the MLI
 HEX CA ;READ
 DA PREAD
 BEQ READFIL1 ;MLI Successful
 JMP HANDLERR ;MLI Error
READFIL1 RTS ;Back to the program

*
*  WRITE the records out to disk
*
WRITEFIL JSR MLI ;Call the MLI
 HEX CB ;WRITE
 DA PWRITE
 BEQ WRITEFI1 ;MLI Successful
 JMP HANDLERR ;MLI Error
WRITEFI1 RTS ;Back to the program

*
*  SET_MARK for the READ command
*
SETMARK JSR MLI ;Call the MLI
 HEX CE ;SET_MARK
 DA PMARK ;Paramater pointer
 BEQ SETMARK1 ;MLI Successful
 JMP HANDLERR ;MLI Error
SETMARK1 RTS ;Back to the program

*
*  SET_MARK for the WRITE command
*
WSETMARK JSR MLI ;Call the MLI
 HEX CE ;SET_MARK
 DA WPMARK ;Paramater pointer
 BEQ WSETMAR2 ;MLI Successful
 JMP HANDLERR ;MLI Error
WSETMAR2 RTS ;Back to the program

*
*  Close all the files
*
CLOSEALL JSR MLI ;Call the MLI
 HEX CC ;CLOSE
 DA PCLOSE ;Paramater List
 RTS ;No error ck

*
*  Read desired byte with or without offsets
*  and return
*
READIT LDA READBUF,X ;Read the selected byte
 RTS

*
*  Preset the position for the 128 byte records
*  For the READ command
*
* Calculate MARKPOS (3 bytes) = RECRDNUM * 128
*
PRESETR LDA #0
 STA MARKPOS+2
 STA MARKPOS
 LDA RECRDNUM
 LSR
 STA MARKPOS+1
 ROR MARKPOS
 RTS

*
*  Preset the position for the 128 byte records
*  For the WRITE command
*
PRESETW SEC  ;Clear to see if borrow is needed
 LDA MARKPOS ;Load the READ position
 SBC #RECRDLEN ;Length of one record
 STA WMARKPOS ;Start the WRITE here
 LDA MARKPOS+1 ;Get the middle byte
 SBC #/RECRDLEN ;Decrement via the carry flag
 STA WMARKPOS+1 ; and save it too
 RTS

*
*  Ck to see if user has access
*
ACCESSCK LDA GRANTLVL ;Menu command access granted
 CMP #3 ;Is it a SysOp access request
 BEQ ACCESCK1 ;Yes, allow access now
 LDA ACCESLVL ;User granted normal access
 CMP #3 ;Is it a different SysOp?
 BEQ ACCESCK1 ;Yes, allow total access
 CMP #1 ;Is it valid to this user
 BEQ ACCESCK2 ;Yes, continue checks
 JMP FILEOKNO ;Not accessable, next file
ACCESCK1 PLA ;Pop the two bytes from
 PLA ; the stack and then
 JMP FILEOK ;Yes, allow total access
ACCESCK2 RTS ;Back for more cks

*
*  Check for "N"ot Displayed File
*
FILENOT LDX #0 ;For the file status byte
 JSR READIT ;Read the file's byte
 CMP #'N' ;Is it a "N"ot displayed file
 BNE FILENOT1 ;No, file okay to display
 JMP FILEOKNO ;Not accessable, next file
FILENOT1 RTS ;File okay to process

*
*  Check for "U"nvalid or "?"questionable file
*
FILENEW LDX #0 ;For the file status byte
 JSR READIT ;Read the file's byte
 CMP #'U' ;Is it an "U"nvalidated file?
 BEQ FILENEW1 ;Yes, continue
 CMP #'?' ;Is it a "?"questionable file?
 BEQ FILENEW1 ;Yes, continue
 JMP FILEOKNO ;Not accessable, next file
FILENEW1 RTS ;Back to the program

*
*  Check files computer type
*
FILETYPE LDX #71 ;Computer type byte
 JSR READIT ;Read the computer type
 CMP #'0' ;"0" For all computers?
 BEQ FILETYP1 ;Yes, continue
 CMP NMSTRING+63 ;Compare it to the users
 BEQ FILETYP1 ;Yes, continue
 JMP FILEOKNO ;Not accessable, next file
FILETYP1 RTS ;Back to the program

*
*  SET_EOF Routine
*
SETEOF JSR MLI ;Call the MLI
 HEX D0 ;SET_EOF
 DA PSEOF ;Set parms
 BEQ SETEOF1 ;No error
 JMP HANDLERR ;Handle the error
SETEOF1 RTS ;Back to the prg.

*
*  Set up the date of last status change
*
YEARS LDX #53 ;First byte of the Year
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 STA MTPC ;Save it for use
 LDA #10 ;Set the multiplier to 10
 STA MTPR ; and save it
 JSR MULTIPLY ;Do the conversion
 LDX #54 ;Last byte of the year
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 CLC ;Clear the carry just in case
 ADC RESULT ;Add it to the first part
 STA YEAR ;Save it as the year

MONTHS LDX #55 ;First byte of the month
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 STA MTPC ;Save it for use
 LDA #10 ;Set the multiplier to 10
 STA MTPR ; and save it
 JSR MULTIPLY ;Do the conversion
 LDX #56 ;Last byte of the month
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 CLC ;Clear the carry just in case
 ADC RESULT ;Add it to the first part
 STA MONTH ;Save it as the month

DAYS LDX #57 ;First byte of the day
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 STA MTPC ;Save it for use
 LDA #10 ;Set the multiplier to 10
 STA MTPR ; and save it
 JSR MULTIPLY ;Do the conversion
 LDX #58 ;Last byte of the month
 JSR READIT ;Now go get it
 SEC
 SBC #'0' ;To get back to 0-9
 CLC ;Clear the carry just in case
 ADC RESULT ;Add it to the first part
 STA DAY ;Save it as the day
 RTS

YEAR DS 1 ;Year in decimal
MONTH DS 1 ;Month in decimal
DAY DS 1 ;Day in decimal

*
*  Multiply routine
*
MULTIPLY LDA #0 ;Let's preclear the result
 STA RESULT ;Clear it now
 LDX #8 ;Our shift counter
LOOP LSR MTPR ;Shift the multiplier
 BCC NOADD ;Nothing in the carry
 CLC ;Clear the carry flag
 ADC MTPC ;Add it to the multiplican
NOADD LSR A ;Shift the result
 ROR RESULT ;Catch the bit into the result
 DEX ;Decrement the counter
 BNE LOOP ;Not finished, keep working
 RTS ;Back to the program for more

RESULT DS 1 ;The answer!
MTPR DS 1 ;Multiplier
MTPC DS 1 ;Multiplican

*
*  Check users YYMMDD against the files
*
DATECK LDA YEAR ;Get the files Year byte
 CMP YYMMDD ;Is it less than the users
 BEQ DATECK1 ;Equal, keep looking
 BCS DATECKRT ;Year is greater, file ok
 BCC DATECKR ;No good, press on
DATECK1 LDA MONTH ;Get the files Month byte
 CMP YYMMDD+1 ;Is it less than the users
 BEQ DATECK2 ;Month is ok, check date
 BCS DATECKRT ;Month is greater, file ok
 BCC DATECKR ;Too long ago, press on
DATECK2 LDA DAY ;Get the files day
 CMP YYMMDD+2 ;Is it less than users
 BCC DATECKR ;Too long ago, press on
DATECKRT RTS
DATECKR JMP FILEOKNO ;Not accessable, next file

*
*  Messages
*
ZTXT EQU *
TXIOERR HEX 87
 ASC "I/O Error            "00
TXFNF HEX 87
 ASC "File/Path not found"00
TXEOF HEX 87
 ASC "End of File!"00
ENDUSERS ASC "End of Xfer Files.."00

*
*  Paramater List
*
POPEN HEX 03 ;OPEN Parm list
 DA PATHNAME ;Pathename pointer
 DA OPENBUF ;I/O Buffer
OPREFNUM HEX 00 ;File ref number

PCLOSE HEX 01 ;Close Parm list
CLREFNUM HEX 00 ;CLOSE Ref number

PREAD HEX 04 ;READ Parm list
RDREFNUM HEX 00 ;READ Ref number
 DA READBUF ;Data pointer
RDCOUNT DW 512 ;Request count
RXFERCNT DW 0 ;Transfer count

PWRITE HEX 04 ;WRITE Parm list
WRREFNUM HEX 00 ;WRITE Ref number
 DA READBUF ;Data pointer
WRCOUNT DW 512 ;Request count
WXFERCNT DW 0 ;Transfer count

PMARK HEX 02 ;SET/GET_MARK Parm list
MKREFNUM HEX 00 ;Reference number
MARKPOS DS 3 ;File position

WPMARK HEX 02 ;SET/GET_MARK Parm List
WMREFNUM HEX 00 ;Reference Number
WMARKPOS DS 3 :File Position

PEOF HEX 02 ;SET/GET_EOF Parm list
EOREFNUM HEX 00 ;Reference number
EOFVAL DS 03 ;Data Storage for EOF

PSEOF HEX 02 ;SET_EOF Parm list
SOREFNUM HEX 00 ;Reference number
SEOFVAL DS 03 ;Data Storage for EOF

*
*  Miscellaneous info
*
ACCESLVL DS 1 ;Security Level granted
LOCK DS 1 ;Bit Lock for access
POSACT DS 3 ;Actual position Bytes
XFERFILE ASC "XFER.FILES",00
PATHNAME DS 65 ;Pathname storage space
READBUF DS 512 ;File buffer space

 SAVE /HARD1/PRIME/XFER/XFER.ML1
 LST OFF

