Commodore‎ > ‎BASIC‎ > ‎Keywords‎ > ‎

RECORD

Keyword Abbreviation Token (hex) Version(s) Classification
RECORD RE{Shift+C} CF 4.x Command and Statement
JOY J{Shift+O} CF 3.5, 7.0 Function
RECORD R{Shift+E} FE 12 7.0 Command and Statement

  Syntax   
RECORD # fileNumber , recordNumber [ , byteNumber ]
 
Parameters Type Legal Value(s) Default Value Note(s)
fileNumber Unsigned Byte 1 ~ 255 Must be an OPEN file.
recordNumber Unisigned Integer  0* ~ 65535**    * Most devices will treat 0 as 1.
** The maximum is media and device specific.
byteNumber Unsigned Byte  1 ~ 254*  *Should be less than the recordLength.
 
 
  Purpose  
File input/output.  Set the recordNumber in a REL file for subsequent read/write operation.
 
  Remarks  
RECORD is designed for positioning a device's internal "file pointer" within a relative (REL) file.  This determines where the next read (with GET# or INPUT#) or write (with CMD or PRINT#) will take place with the given fileNumber.  The fileNumber must be preceded by an octothorpe (#).
 
The fileNumber must be an OPEN file or a FILE NOT FOUND ERROR is generated (umm, it should be "file not open").  The file should be a relative file opened on the IEEE/IEC bus (device number 4 to 30), but BASIC does not check.  If not, this statement will send the "position" command to the specified device, like OPEN with a command string.  This should not generate an error if the device is the keyboard or screen, but will generate FILE OPEN ERROR if the device is a cassette or RS-232.
 
The recordNumber is a 1-based record index into the corresponding file.  It does not directly set the byte position within the file!  You probably don't need to know this, but the actual (1-based) byte position in the file will be
   ( recordNumber - 1 ) * recordLength + byteNumber,  
where the recordLength is determined when the file is first created (see DOPEN) and the byteNumber defaults to 1 if omitted.
 
If the recordNumber specifies a position beyond the end of the file, the device should report (via DS$) "50, RECORD NOT PRESENT,00,00".  This can safely be ignored when expanding a relative file (i.e., adding new records).  This is a real error if you are preparing to read from the file!  Note you can not rely on the device to report "RECORD NOT PRESENT" when reading or writing because most devices, when adding a new record, will pad out the remainder of a "disk sector" (allocation block)  with empty records.  For example, with a recordLength of 64 bytes, writing the first record will actually write that record plus the next two (i.e., records 1 to 3 will be written) plus a partial record 4 (this all fits in the 254 file bytes of the first allocation block).  Thus even though "you" never wrote records 2 or 3, subsequent use of RECORD to select those records for reading will not generate an error (with most devices), but when you try to access record 4 the (typical) device detects that only a partial record 4 is available and will "correctly" report RECORD NOT PRESENT.
 
If you check out the CBM/CMD DOS manuals for the details of the relative file format, it should be clear the data structure allows the correct number of records to be determined (could/should correctly report RECORD NOT PRESENT).  However the DOS in 1541, 1571, and 1581 disk drives (at least) fail to "do the right thing".  I don't know if this is a bug, or a "feature" for compatibility.  But it does mean that you need to somehow record (or implicitly know) the actual number of records that have been written (assuming you care) because you can't rely on CBM DOS.
 
Most devices will not report an error if you specify recordNumber zero; they simply select recordNumber one.  You shouldn't rely on this; it is conceivable some device might select recordNumber 65536 instead, or use the zero value as a special extension.
 
The maximum recordNumber depends mainly on how much free space is available on the media (disk).  Note the 1541 and 1571 both use the same relative file format.  You can completely fill the a 1541 disk with a relative file, but depending on the recordLength you may not be able to fill a double-sided disk in a 1571.  This is because of the larger size available but still using the relative file structure of the 1541.  The 1581 has even more space, but it has an expanded relative file format, so this is not an issue.  Anyway, on the 1541 and 1571, you can have up to 6 * 120 = 720 records (assuming adequate disk capacity).  On the 1581 and CMD devices, the size is only limited by disk capacity (which means the maximum recordNumber depends on the amount of space available and the recordLength).
 
The byteNumber is a 1-based index to a byte within the selected recordNumber.  This time BASIC will check and report ILLEGAL QUANTITY ERROR if the byteNumber is zero (or greater than 254).  The byteNumber should be less than the recordLength, but BASIC does not know what the recordLength is (and there is no standard command that will tell you either).  However, if the byteNumber is more than the recordLength, the device should report "51, OVERFLOW IN RECORD,00,00".  Thus if you don't know the recordLength (and would like to find out), you could start at 1 and keep trying bigger values until you get this error.  Do not try to find out the recordLength of the file by a selecting the first record and reading bytes with GET# until "EOI" is detected (ST AND 64 is non zero) because this will only tell you what DOS thinks is the number of used bytes in the record (i.e., only the used size for that particular record, not the allocated size [recordLength]).
 
The paragraph above discussed the situation where byteNumber is less than recordLength (generally okay) and where it is greater than recordLength (always an error), but not the case when the byteNumber equals the recordLength.  In this case the device (shouldn't) report an error message, but as soon as you write a single character with PRINT# the device should report OVERFLOW IN RECORD unless you end the PRINT# with a semicolon (;).  This is because without a semicolon, PRINT# will send a carriage return after the single character, which is two characters... but you are started at the last position so only one byte remained available.  So, you can use a byteNumber equal to the recordLength, but it requires care with the next PRINT#.
 
If a required parameter is omitted, or an expression is not valid SYNTAX ERROR occurs.  If any parameter is not numeric, a TYPE MISMATCH ERROR will be generated.  Otherwise if a parameter is not a legal value (see table above), an ILLEGAL QUANTITY ERROR is generated.
 
Assuming the Syntax is correct, BASIC transmits a "position" command to the device (this updates ST).  Unless the transmission fails (for example DEVICE NOT PRESENT) there is no error from BASIC.  So be sure to check the device status with DS or DS$.
  
Unlike all other disk commands and statements, the Syntax is strict.  You may not re-order parameters.  On the other hand, you do not need parentheses to use a variable or expression.
 
Like all disk-based commands, RECORD will reset DS$ and set the secret variable "DosFA".  Unlike other disk-based commands, the "DosFA" is set to the device number which corresponds with fileNumber.
 
Examples (on unit 8, drive 0):
SCRATCH "TEST"          : REM be sure file does not exist
ARE YOU SURE? Y
01, FILES SCRATCHED,00,00

READY.
DOPEN #7, "TEST", L64   : REM open REL file with recordLength 64

READY.
PRINT DS$
00, OK,00,00

READY.
RECORD #7, 1            : REM go to first record

READY.
PRINT #7, "RECORD ONE"  : REM wrote first record

READY.
PRINT DS$
00, OK,00,00

READY.
RECORD #7, 2 :PRINT DS$ :REM goto second record
00, OK,00,00                      where did this come from ??

READY.
RECORD #7, 3 :PRINT DS$ :REM goto third record
00, OK,00,00                      where did this come from ??

READY.
RECORD #7, 4 :PRINT DS$ :REM goto fourth record
50, RECORD NOT PRESENT,00,00      ahh, that's better!

READY.
RECORD #7, 1, 10        :REM goto tenth byte of first record

READY.
PRINT DS$
00, OK,00,00

READY.
RECORD #7, 1, 65        :REM go past last byte of first record

READY.
PRINT DS$
51,OVERFLOW IN RECORD,00,00

READY.
DCLOSE #7               :REM close the file to flush buffers

READY.
PRINT DS$
00, OK,00,00

READY
 
 
  Compare With  
 
  Contrast With  
  See Also  
DOPENDS, DS$, GET#, INPUT#OPEN, PRINT#ST
© H2Obsession, 2014
Comments