public interface DeviceDriver
Device drivers are responsible for handling all file I/O. A device driver must, of course, have a corresponding SMSQE device driver which is correctly linked into SMSQE. The NFA driver shows how this is done.
Device drivers must implement all of the methods set out herein some of which return a boolean
value.
These methods MUST set the D0 register to signal success (or not) of the operation. In many cases (notably OPEN), the
boolean
returned by a method does NOT signal that an I/O operation succeeded (or not),
but has some other meaning : See the individual methods for more information on the returned boolean
.
ATM, device driver operations will always seem atomic to SMSQE, i.e. when the TRAP call returns, the operation in its entirety will have succeeded (or not). In other words, the timeout for the trap #3 calls is totally ignored. This has the unfortunate side effect that SMSQE will appear to be frozen whilst file i/o takes place.
In keeping with standard SMSQE practice, it is presumed throughout that each device may have 8 drives.
Each device driver must have a deviceID, which consists of one Java int
. This device ID must also be the one that
the SMSQE driver uses. The deviceID is normally a long word, containing the upper cased three letter word of the device, followed by ASCII 0.
Thus, for the NFA driver, this is 0x0x4e464130, which translates to 'NFA0'.
Modifier and Type | Method and Description |
---|---|
void |
closeAllFiles()
Closes all files opened by all drives of this device driver.
|
boolean |
closeFile(int driveNbr,
int fileID)
This closes an open file.
|
boolean |
deleteFile(int driveNumber,
byte[] filename,
java.io.File file)
Deletes a file.
|
boolean |
formatMedium(java.lang.String formatName,
inifile.IniFile inifile)
Formats a medium.
|
int |
getDeviceID()
Gets the device ID for this device, eg.
|
java.lang.String |
getName(int drive)
Gets the name of the native directory/file used for one drive of the device, or the current usage name of the device.
|
java.lang.String[] |
getNames()
Gets the names of the native directories/files used for each drive of the device.
|
int |
getUsage()
This gets the usage name of the device.
|
boolean |
openFile(int devDriverLinkageBlock,
int channelDefinitionBlock,
int openType,
int driveNumber,
byte[] filename,
byte[] uncased)
Opens a file.
|
void |
setCpu(MC68000Cpu cpu)
Sets the cpu used by the device driver.
|
void |
setFilenameChange(int change)
Sets whether a filename's case should be changed (0 = unchanged, 1=all upper case, 2=all lower case.
|
boolean |
setNames(java.lang.String[] names,
inifile.IniFile inifile,
boolean forceRemoval,
boolean suppressWrnings)
Sets the names of the native directories to be used for each drive of the device.
|
void |
setUsage(int usage)
This sets the usage name of the device, eg.
|
boolean |
trap3OK(int driveNumber,
int trapKey,
int channelDefinitionBlock,
int fileNbr)
Handles trap#3 calls (but should check first whether the trap#3 call is, indeed, for this device).
|
void |
writeBack(int driveNbr)
Writes the drive back to a native file
|
boolean openFile(int devDriverLinkageBlock, int channelDefinitionBlock, int openType, int driveNumber, byte[] filename, byte[] uncased)
If the file is opened OK, D0 in the cpu is set to 0.
If the file isn't OK, D0 is set to an error code.
The device must first of all check whether the file is for itself (i.e. for this device). If the file isn't for this device,
immediately return false
. In that case, the value of register D0 doesn't matter.
In all other cases (i.e. the file was, indeed, for this device) always return true
, but previously set D0 to signal
whether the open routine was successful or not.
If the operation succeeds, the Driver should place a word sized file ID at offset 0x1e of the channel definition block (eg.
this.cpu.writeMemoryWord(channelDefinitionBlock+0x1e, fileID)
), or use any other convenient method to make
size it can later identify the file when the file's I/O routines are called.
devDriverLinkageBlock
- pointer to the SMSQE device driver linkage block (a3).channelDefinitionBlock
- pointer to the SMSQE channel defintion block (a0).openType
- which kind of open is requested?
driveNumber
- number of drive on which to open the file.filename
- the name of the file to open.uncased
- the name of the file to open in all lower case.true
if file was opened OK, false
if not.boolean closeFile(int driveNbr, int fileID)
driveNbr
- the number of the drive (0..7).fileID
- the fileID.true
if file was for this device, else false
.
If this returns true, this method MUST have set the D0 register to signal success (or not) of the operation to SMSQE.
boolean formatMedium(java.lang.String formatName, inifile.IniFile inifile)
formatName
- the name to give to the formatted drive.inifile
- the ".ini" file object.true
if deviceID corresponded to this device, false
if not.
This method MUST set the D0 register to signal success (or not) of the operation to SMSQE.
boolean deleteFile(int driveNumber, byte[] filename, java.io.File file)
driveNumber
- number of drive on which to delete the file.filename
- the name of the file to open.file
- the file to delete.true
if the file deleted.
This method MUST set the D0 register to signal success (or not) of the operation to SMSQE.
boolean setNames(java.lang.String[] names, inifile.IniFile inifile, boolean forceRemoval, boolean suppressWrnings)
In keeping with standard SMSQE practice, it is presumed throughout that each device may have 8 drives.
names
- an 8 element String array with names for the drives.inifile
- the initialization object.forceRemoval
- true if files/drives should removed before being remounted.suppressWrnings
- if true, don't show missing drives etc warningstrue
if names were set, else false
.java.lang.String[] getNames()
In keeping with standard SMSQE practice, it is presumed throughout that each device may have 8 drives.
null
if the device ID wasn't mine.
Individual elements may be null
or empty if the corresponding drive isn't assigned.java.lang.String getName(int drive)
In keeping with standard SMSQE practice, it is presumed throughout that each device may have 8 drives.
drive
- the drive (from 1 to 8) for which the name is to be obtained, or 0 if the current usage name is to be returned.null
if the device ID wasn't mine, or "" if the device ID was mine but the drive didn't exist..boolean trap3OK(int driveNumber, int trapKey, int channelDefinitionBlock, int fileNbr)
All device drivers get called in turn for this operation, until one signals that it has handled the trap call. "Handling" the trap call does not mean that the trap call was completed successfully, it only means that the device driver signals that this trap call concerned a file for which it was,indeed, the appropriate driver.
driveNumber
- number of drive on which to open the filetrapKey
- what kind of trap #3 is it?channelDefinitionBlock
- pointer to the SMSQE channel definition block (a0)fileNbr
- the file number given by the ddd when file was opened (A0+0x1e)true
if file was for this device, else false
. This says nothing about the success of the trap #3
operation in itself, it only shows that the device driver recognized that this I/O operation was for a file on one of its drives.
This method MUST set the D0 register to signal success (or not) of the operation to SMSQE.
void setUsage(int usage)
usage
- the usage name as an intint getUsage()
int getDeviceID()
void setFilenameChange(int change)
change
- 0 = unchanged, 1=all upper case, 2=all lower case.void closeAllFiles()
void setCpu(MC68000Cpu cpu)
cpu
- the cpu to be set.void writeBack(int driveNbr)
driveNbr
- the drive number (1...8)