'=========================================================================== ' Subject: FILE ROUTINES USING INTERRUPTS Date: 10-29-97 (01:20) ' Author: Petter Holmberg Code: QB, PDS ' Origin: petter.holmberg@usa.net Packet: INTERRPT.ABC '=========================================================================== ' -------------------------------------------------------------------------- ' ' QuickBASIC file routines, ver. 0.9beta ' ' By Petter Holmberg, 1997 (petter.holmberg@usa.net) ' ' ' ' This program demonstrates file I/O using interrupts. With these routines ' ' you can instantly access up to 65536 bytes from anywhere in files up to 2 ' ' gigabytes long, or directly write up to 65536 bytes to such a file with ' ' the speed of BLOAD/BSAVE. These routines will be included in a disk I/O ' ' library that I'll hopefully release for January 1, 1998. ' ' ' ' These routines are just a preview of what they will look in the upcoming ' ' disk library. The routines in this program don't check if the drive of ' ' the file to be read from or written to is ready, they don't feature any ' ' checking to see if the file pointer exceeds the file length, they don't ' ' tell you if you have read past the end of the file, and in that case how ' ' much data you recieved and they don't tell you if you have written past ' ' the amount of free disk space aviable. ' ' These are just a few of the things not supported yet. However, ' ' these routines are very useful for QuickBASIC programmers since the BLOAD ' ' and BSAVE routines have a 64k file size limit and the file GET and PUT ' ' keywords are based on the length of the variable used. ' ' ' ' If you want to experiment with these routines I strongly advise you to do ' ' so on a floppy disk, since I can't guarantee the results of using these ' ' routines in uncommon ways. Please note that I don't take any ' ' responsibility for any damage whatsoever due to the use of this code. ' ' These routines are just beta versions and they haven't been tested for ' ' bugs and errors, the whole code was written in just one evening. ' ' ' ' Any comments and suggestions can be sent to: petter.holmberg@usa.net ' ' If you use this code in your programs, all I ask for is some credits. ' ' Petter Holmberg ' ' ' ' -------------------------------------------------------------------------- ' TYPE RegTypeX ax AS INTEGER bx AS INTEGER cx AS INTEGER dx AS INTEGER bp AS INTEGER si AS INTEGER di AS INTEGER flags AS INTEGER ds AS INTEGER es AS INTEGER END TYPE DIM SHARED inregs AS RegTypeX, outregs AS RegTypeX DECLARE SUB InterruptX (intnum%, inregs AS RegTypeX, outregs AS RegTypeX) DECLARE SUB ReadFile (filename$, filepos&, destseg%, destofs%, readlen%, fileerror%) DECLARE SUB WriteFile (filename$, filepos&, sourceseg%, sourceofs%, writelen%, fileerror%) ' --- Demonstration code: CLS INPUT "Input a file name (Make sure it's not already used!!!): ", filename$ ' Create and reset file: OPEN filename$ FOR OUTPUT AS #1: CLOSE #1 teststr$ = "This is a test" PRINT "Test string: "; teststr$ PRINT "Writing text to file..."; WriteFile filename$, -1, VARSEG(teststr$), SADD(teststr$), LEN(teststr$), fileerror% IF fileerror% > 0 THEN PRINT "Error!" PRINT "Error code:"; fileerror% END ELSE PRINT "Done!" END IF PRINT "Reading from file..."; ' Blank out the string: teststr$ = SPACE$(LEN(teststr$)) ReadFile filename$, 0, VARSEG(teststr$), SADD(teststr$), LEN(teststr$), fileerror% IF fileerror% > 0 THEN PRINT "Error!" PRINT "Error code:"; fileerror% END ELSE PRINT "Done!" END IF PRINT "Text returned: "; teststr$ SUB ReadFile (filename$, filepos&, destseg%, destofs%, readlen%, fileerror%) ' This SUB reads a certain amount of data from a file into system memory. ' - filename$ is the name of the file to be read from. ' - filepos& is the starting position in the file for the reading. Due to ' overflow errors, you can only define a number up to a little more than 1 ' megabyte. This will hopefully be fixed in the finished version. ' - destseg% is the destination segment in system memory for the data to be ' transferred. ' - destofs% is the destination offset in system memory for the data to be ' transferred. ' - readlen% is the number of bytes to be read from the file. If you want ' to read more than 35536 bytes, write the number in hexadecimal. ' - fileerror% is a variable containing possible errors. The error codes are ' listed below: ' 0: Call successful, no error ' 1: File not found ' 2: Path not found ' 3: Too many open files ' 4: Access denied ' 5: Access code invalid filename$ = filename$ + CHR$(0) fileerror% = 0 ' Open the file for reading: inregs.ax = &H3D00 inregs.ds = VARSEG(filename$) inregs.dx = SADD(filename$) InterruptX &H21, inregs, outregs IF outregs.flags AND 1 THEN SELECT CASE outregs.ax CASE 2: fileerror% = 1 CASE 3: fileerror% = 2 CASE 4: fileerror% = 3 CASE 5: fileerror% = 4 CASE 12: fileerror% = 5 END SELECT EXIT SUB ELSE filehandle% = outregs.ax END IF ' Set the file pointer: inregs.ax = &H4200 inregs.bx = filehandle% inregs.cx = (filepos& AND &HFFFF0000) \ &H10000 AND &HFFFF& inregs.dx = filepos& AND &HFFFF InterruptX &H21, inregs, outregs ' Read the data: inregs.ax = &H3F00 inregs.bx = filehandle% inregs.cx = readlen% inregs.ds = destseg% inregs.dx = destofs% InterruptX &H21, inregs, outregs ' Close the file: inregs.ax = &H3E00 inregs.bx = filehandle% InterruptX &H21, inregs, outregs END SUB SUB WriteFile (filename$, filepos&, sourceseg%, sourceofs%, writelen%, fileerror%) ' This SUB writes a certain amount of data from system memory into a file. ' - filename$ is the name of the file to be written to. Note that the file ' specified must already exist. ' - filepos& is the starting position in the file for the writing. Due to ' overflow errors, you can only define a number up to a little more than 1 ' megabyte. This will hopefully be fixed in the finished version. ' If you set this varable to -1, the data will be written to the end of ' the file. ' - sourceseg% is the destination segment in system memory for the data to be ' - transferred. ' - sourceofs% is the destination offset in system memory for the data to be ' transferred. ' - writelen% is the number of bytes to be written to the file. If you want ' to write more than 35536 bytes, write the number in hexadecimal. ' - fileerror% is a variable containing possible errors. The error codes are ' listed below: ' 0: Call successful, no error ' 1: File not found ' 2: Path not found ' 3: Too many open files ' 4: Access denied ' 5: Access code invalid filename$ = filename$ + CHR$(0) fileerror% = 0 ' Open the file for writing: inregs.ax = &H3D01 inregs.ds = VARSEG(filename$) inregs.dx = SADD(filename$) InterruptX &H21, inregs, outregs IF outregs.flags AND 1 THEN SELECT CASE outregs.ax CASE 2: fileerror% = 1 CASE 3: fileerror% = 2 CASE 4: fileerror% = 3 CASE 5: fileerror% = 4 CASE 12: fileerror% = 5 END SELECT EXIT SUB ELSE filehandle% = outregs.ax END IF ' Set the file pointer: IF filepos& = -1 THEN inregs.ax = &H4202 inregs.bx = filehandle% inregs.cx = 0 inregs.dx = 0 InterruptX &H21, inregs, outregs ELSE inregs.ax = &H4200 inregs.bx = filehandle% inregs.cx = (filepos& AND &HFFFF0000) \ &H10000 AND &HFFFF& inregs.dx = filepos& AND &HFFFF InterruptX &H21, inregs, outregs END IF ' Write the data: inregs.ax = &H4000 inregs.bx = filehandle% inregs.cx = writelen% inregs.ds = sourceseg% inregs.dx = sourceofs% InterruptX &H21, inregs, outregs ' Close the file: inregs.ax = &H3E00 inregs.bx = filehandle% InterruptX &H21, inregs, outregs END SUB