home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Archive Magazine 1996
/
ARCHIVE_96.iso
/
discs
/
mag_discs
/
volume_2
/
issue_04
/
currdirrm
/
CURRDIRTXT
< prev
Wrap
Text File
|
1995-06-22
|
4KB
|
70 lines
As a new Archimedes user, coming from the IBM PC environment I am familiar
with the idea of a modifiable prompt as described in the Users Guide to
provide an example of the use of the SETMACRO command.
"SETMACRO CLI$PROMPT <SYS$TIME>" will provide the current time as a prompt
by re-evaluating the prompt string each time it is used, and the SYS$TIME
variable is maintained by the operating system. Personally I find the most
useful information to have at the prompt is the path or current directory,
especially since I have a hard disk. It is suprising that Arthur doesn't
provide a system variable to keep track of the current directory. I decided
to find out what is involved in creating and maintaining such a variable.
The current directory is always changed, whether by a program or a command
via the OS_FSControl SWI. When a SWI is issued by a program, control is
passed via a "vector" or pointer, and this vector can be "claimed" or
redirected to your own piece of code. It is then up to you whether you pass
control on to the previous owner of the vector or "intercept" it entirely and
replace the functions being requested with your own.
The logic behind my program is as follows:
- The program is entered via the claimed FSControlV vector.
- If the function requested is not set current directory, then pass control
onto the previous owner of the vector.
- If set current directory(i.e. R0=0) is requested, then ensure that we regain
control after the directory has been changed, by providing our return
address pushed onto the stack.
- On return we use the SWI OS_GBPB to "read current directory".
- Then issue the OS_SetVarVal SWI to update the variable.
Now if I am going to start interfering with the operating system by claiming
vectors, I want to be sure that the memory into which I place my code is not
going to inadvertently be overwritten by some application or utility. Else all
functions provided by that SWI, and not just changing the current directory
will be disabled! The ideal way to see that your interfering piece of code
is well looked after, is to package it as a module.
Other benefits of writing the program as a module are the ready made commands
to install and remove it with RMLOAD and RMKILL, and predefined entry points
for initialisation, finalisation and service call handler. The first two
entry points are almost self explanatory, the initialisation code is called
when the module is loaded and also after the RMA has been tidied. The
finalisation code is entered for the OS_Module call with reason codes Tidy,
Reinit, Delete and Clear, also if a module is loaded twice, the old one is
killed.
The use of the service call handler entry point is not as immediately
obvious. Service calls are issued by OS_ServiceCall and are identified by the
service number in R1. They fall into two categories either soliciting
information or action because of an unknown - e.g. unknown file type,
command, *status or OS_Word. Or else informing modules of an event that may
be of interest to them - e.g. Error, StartUpFS, Reset, Keyboard handler, or
Pre-reset.
CurrDirRM was initially written without a service call handler, but the
claimed vector was mysteriously being returned to its previous owner, which
left the module useless and what was more annoying it was impossible to
reinitialise, kill or tidy as it got an error whenever it tried to release a
vector it no longer owned! I eventually saw the connection between, soft and
machine resets and the "reset" vector. I used the service call handler to
check for Reset and Pre-reset service calls, and set a flag to inform the
finalisation code not to worry about releasing the vector.
The module once assembled and saved to the modules directory, only occupies
&13A bytes which even on a 512K system isn't too great a sacrifice. To
install it and incorporate it into a prompt, add the following lines to your
!BOOT program:
*RMLOAD $.Modules.CurrDirRM
*SETMACRO Cli$Prompt <Curr$Dir>==>