home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
utility
/
disk
/
pdos_112
/
powerdos.txt
< prev
Wrap
Text File
|
1993-08-02
|
90KB
|
2,316 lines
PowerDOS Programmer's Manual (well, sort of)
Revision 1.0 - 08/02/93
(C) 1993 ViewTouch Corp.
344 NE Terry Lane
Grants Pass, OR 97526
(503)479-4278
Who's primarily at fault - Chris Latham
Lots of chiding and snide remarks - Daniel Hollis
Welcome to the first incarnation of the wonderful, furry,
spicy (low cholesterol) PowerDOS programmer's Manual (TM)!!
Included are all the documents needed to push PowerDOS to
(no, make that OVER) its limits. We assume no responsibility
for system crashes, loss of data, destruction of hardware
(willful or otherwise), loss of limbs, divorces, shattered
lives, insanity, paralysis, deaths, or global thermonuclear war
resulting from the use, misuse, unuse, abuse or refuse of this
program.
Do not insert document into ear canal. Keep out of reach
of children. May cause dizziness, convulsions, or vomiting.
Keep away from open flame. Wear safety gloves when handling.
With all that legal mumbo jumbo out of the way, fasten your
seat belts and off we go!!
Enter at own risk!
+----------------------------------------------------------------------+
First, let's discuss what multitasking is...
Well, multitasking is...wait, let me digress for a moment.
What is a computer....wait, let me digress...
Where is the on/off switch?
It's in the back.
Now that you fully understand multitasking, we'll launch right
into the functions that PowerDOS provides.
+----------------------------------------------------------------------+
4B: Program execution
PowerDOS supports four new execution modes, as described below:
long errcode = Pexec(0x10,prgfile,cmdline,envptr)
This mode is just like mode 0, except that the parent continues to
operate concurrently with the newly created child task. The error
codes only reflect errors that may occurr while trying to create
the task, such as file not found or out of memory. The only way for
the parent to receive the deathcode from the child task, is if it
executes a Wait() before the child terminates. If no error occurrs,
(d0.l is not negative), then d0.w will be the process ID of the new
task.
Also like mode 0, the newly created task gets the largest block of
ram for its basepage+text+bss+heap. Since other, concurrently running
processes in the system may try to do Mallocs before the new task
has shrunk its memory usage, it is advisable that the parent process
issues controls as to the amount of memory that the new task will
receive for both its TPA and Malloc(-1) calls that it may issue as it
executes.
Function 0xa3 (Pmaxmem) may be used to set the parents maximum
Malloc(-1) return. This max value will be inherited by the child
process as its maximum Malloc(-1) value. Also, function 0x9f may be
used to set the maximum size of the TPA given to a newly created
process. These two variables taken together will give a large
amount of control as to how the memory in the system is used.
long errcode = Pexec(0x16,0L,_psp basepage,0L)
This is just like mode 6, except that the parent again continues
to execute concurrently, whith the same problem of receiving the
child's deathcode upon its termination.
The next two Pexec modes are for support of multiple threads of
execution within a single program:
long errcode = Pexec(0x17,char *proc_name,char *cmdline,char *envptr,
void *code_ptr,long bss_size,long data_size)
This mode allows you to execute a code fragment that is within the text
segment of the calling process. It creates a basepage, followed by a
data segment of the given size (and copies the data from the parents
data segment, for the data size given), followed by a BSS of the
given size. The user stack pointer is placed at the top of the BSS, so
this must be included in the BSS size. At sp+4 will be a pointer to the
basepage, the same as Pexec mode 0. Also register a5 will point to the
start of the data segment, and register a4 will point to the start of
the BSS. proc_name is the name the process will be known by, and must
be a null terminated string of no more than 13 characters. The code
fragment may directly access or modify variables in its parents
data or BSS segments, using pc relative or absolute addresses. Access
to the thread's private data and BSS segments, however, may only be
accomplished using relative offsets from an address register.
long errcode = Pexec(0x18,char *proc_name,char *cmdline,char *envptr,
void *code_ptr,long bss_size,long data_size,
int var_ints,int *vars[])
This is the same as mode 0x17, except that it allows a number of ints
to be placed on the stack of the new task (thus the basepage pointer
will not be at sp+4). var_ints is the number of ints to copy onto the
stack, and vars is a pointer to the ints to copy.
+--------------------------------------------------------------------------+
7.1 5C: Lock/unlock File Access
long Flock(handle, mode, start, length)
word handle;
word mode;
long start;
long length;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x5c | Word block addr)
+-------------------------------------+
| File Handle | Word 1
+-------------------------------------+
| Mode | Word 2
+-------------------------------------+
| |
+ Start of Lock + Long 1
| |
+-------------------------------------+
| |
+ Length of Lock + Long 2
| |
+-------------------------------------+ High memory
This is not a function call unique to PowerDOS, since it is defined by
Atari as the record locking standard to be used by all networking or
multitasking operating systems. However, since this call is not part of
regular GemDOS, documentation for it is not readily available. It is
documented here for the convienience of PowerDOS developers or just the
curious.
Word 1 contains the file handle.
Word 2 contains a code indicating lock/unlock:
0 = Create a lock of (length) bytes, beginning at (start).
1 = Remove lock that was previously set. Parameters
Length and Start MUST match a previous lock call.
Long 1 is offset from start of file where the lock will begin.
Long 2 is the length of the locked area. Once a lock is set, only
the handle that owns the lock may read or write that area of the
file. When a handle is closed, any locks left on the file by the
handle will automatically be removed. Any handle may have any
number of non-overlapping locks on a file. PowerDOS can handle
up to 65535 total locks on all open files.
Return Parameter:
Register D0.L : Contains 0 if the operation was successful (the
lock was created or removed, depending on mode),
non-zero if an error occurs.
New error codes are defined to handle possible error conditions:
-58 : Record is locked. This error is returned if the area of the
file where a new lock is to be created already has a lock on
it, or overlapping it. This error will also be returned during
f_read or f_write calls to areas of the file containing locks
from other handles.
-59 : Matching lock not found for unlock operation. This error
will be returned during a lock removal operation if a lock
with the proper start/length belonging to the handle was
not found as part of the files previously set locks.
In assembly language:
move.l length,-(sp)
move.l start,-(sp)
move.w mode,-(sp)
move.w handle,-(sp)
move.w #$5c,-(sp)
trap #1
lea 14(sp),sp
+--------------------------------------------------------------------------+
7.2 80: Get or set Group.User ID of a process
long Puserid(process_id,flag,new_group_user)
word process_id;
word flag;
long new_group_user;
}
{
+-------------------------------------+ Low memory (parameter
| Function Code 0x80 | Word block addr)
+-------------------------------------+
| Process ID | Word 1
+-------------------------------------+
| Get/set flag | Word 2
+-------------------------------------+
| New group.user ID if |
+ + Long
| flag is <>0 (set) |
+-------------------------------------+ High memory
Note: Only a super user (group.user ID *.0-31) may set a processes
group.user ID. All others may only read group.user ID's.
Word 1 is ID of process from which to set/get the group.user ID. Zero
represents the calling process.
Word 2 Get/set flag. Zero means get, else is a set.
Long New group.user ID if flag <> 0. Upper word of long is group ID
lower word is user ID.
Return Parameter:
Register D0.L : Contains the group.user ID if a get, or the new
group.user if a set. Could also possibly be one of
three errors:
-62 : Permission violation. Process tried to do a set but was not a
super user.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
Note: since the group.user ID can be any number, it is possible to
mistake a legitimate group.user ID for an error code. The solution to
this is to not allow a group ID to be > 32767.
In assembly language:
move.l new_group_user,-(sp)
move.w flag,-(sp)
move.w process_id,-(sp)
move.w #$80,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
7.3 81: Set or get the priority of given process
long Ppriority(process_id,new_priority)
word process_id;
word new_priority;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x81 | Word block addr)
+-------------------------------------+
| Process ID | Word 1
+-------------------------------------+
| New process priority, or read flag | Word 2
+-------------------------------------+ High memory
Note: you may change process priorities only of processes with the same
group.user id (your processes) or if you are a superuser.
Word 1 Process ID from which priority is to be read or changed. If this
value is a zero, then the priority to be read/changed is of the
calling process.
Word 2 If zero, is a read (zero is not a valid process priority), else
is the new priority for the process.
Return Parameter:
Register D0.L : If D0.l is positive (no error), then the lower word
is the current priority of the given process. If D0.l
is negative, represents an error:
-62 : Permission violation. Process tried to do a set priority but was
not a super user or owner.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
move.w new_priority,-(sp)
move.w process_id,-(sp)
move.w #$81,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.4 82: Get current process' process ID
word Pgetpid()
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x82 | Word block addr)
+-------------------------------------+ High memory
Return parameter:
Register D0.W : Process ID of calling process. This call never fails.
In assembly language:
move.w #$82,-(sp)
trap #1
addq.l #2,sp
+--------------------------------------------------------------------------+
7.5 83: Get current process' parent's process ID
long Pgetppid()
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x83 | Word block addr)
+-------------------------------------+ High memory
Return parameter:
Register D0.L : If D0.L is not negative, the lower word of D0 is
process ID of parent of calling process. If D0.L is
negative, then possible error is:
-87 : Orphaned process. The parent of the caller no longer exists.
In assembly language:
move.w #$83,-(sp)
trap #1
addq.l #2,sp
+--------------------------------------------------------------------------+
7.6 84: Return pointer to process descriptor of given process
void *Pgetpd(process_id)
word process_id;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x84 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+ High memory
Note: Only a super user process may directly examine or modify the
contents of a process descriptor.
Word ID of process whose process descriptor is being sought. If zero,
process descriptor of current process is returned.
Return Parameter:
Register D0.L : Pointer to the process descriptor of the given process
ID, or possible error codes (if negative):
-62 : Permission violation. Non super user process may not gain access
to the process descriptor of any process.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
move.w process_id,-(sp)
move.w #$84,-(sp)
trap #1
addq.l #4,sp
+--------------------------------------------------------------------------+
7.7 85: Find the process ID of a process with the given name
long Pfindpid(process_name)
char *process_name;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x85 | Word block addr)
+-------------------------------------+
| |
+ Pointer to process name + Long
| |
+-------------------------------------+ High memory
Long Pointer to name of process whose process ID is to be returned.
Name is a zero terminated ASCII string. Call is case
independent. If a process was created from a disk file, then its
name will be that of the disk file (i.e. WWRITER2.PRG). If this
is the case, the extension is not required for a match; The
string "wwriter2",0 will match the above example.
Return Parameter:
Register D0.L : If D0.L is not negative, then lower word is process ID
of process with matching name.
Possible error:
-75 : Process with given name not found.
In assembly language:
pea process_name
move.w #$85,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.8 86: Return information about process
typedef struct {
int pi_pid; /* Process ID */
int pi_ppid; /* Parents process ID */
int pi_sibling; /* First sibling's process ID (0=none) */
int pi_child; /* First child's process ID (0=none) */
unsigned long pi_gu; /* Group.user ID */
unsigned int pi_priority; /* Process priority */
unsigned int pi_age; /* Process current age if in r-t-r queue */
unsigned char pi_status; /* Various status bits */
unsigned char pi_queueID; /* Queue process resides in */
struct _psp *pi_basepage; /* Pointer to process basepage */
long pi_max_mem; /* Max memory returned for Malloc(-1) */
int pi_ucall; /* Last user state function call */
int pi_scall; /* Last system state function call */
unsigned long pi_ucpu; /* Number of user state milliseconds used */
unsigned long pi_scpu; /* Number of system state milliseconds used */
unsigned long pi_sleep; /* Number of milliseconds left if sleeping */
unsigned long pi_datetime; /* Date/time process started (XBIOS format) */
unsigned long pi_fcalls; /* Number of function calls executed */
unsigned long pi_iocalls; /* Number of i/o calls executed */
unsigned long pi_rbytes; /* Total bytes read from input calls */
unsigned long pi_wbytes; /* Total bytes written from output calls */
void *pi_vector; /* User defined vector */
struct dta *pi_dta; /* Disk transfer address */
char pi_name[14]; /* Process name (zero terminated ASCII) */
char pi_devname[8]; /* Current device name (A:, B:, C: etc) */
long pi_totmem; /* Total memory used by process */
void *pi_stack; /* Current supervisor stack top */
} PROCINFO;
long Pprocinf(process_id,buffer)
word process_id;
struct PROCINFO *buffer;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x86 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+
| Pointer to buffer which will |
+ + Long
| receive process information |
+-------------------------------------+ High memory
Word ID of process whose information is being read. If zero, the
information is for the calling process.
Long Pointer to a buffer into which the information will be
copied. The buffer must be sizeof(PROCINFO) bytes in length.
Register D0.L : Zero if call was successful, else error:
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
pea buffer
move.w process_id,-(sp)
move.w #$86,-(sp)
trap #1
addq.l #8,sp
+--------------------------------------------------------------------------+
87: Change process priority using a delta
long Pnice(process_id,delta)
word process_id;
word delta;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x87 | Word block addr)
+-------------------------------------+
| Process ID | Word 1
+-------------------------------------+
| Delta | Word 2
+-------------------------------------+ High memory
Word 1 Process ID from which priority is to be read or changed. If this
value is a zero, then the priority to be read/changed is of the
calling process.
Word 2 A delta (+/-) from the current process ID. If this value is zero,
no change is made; just returns the current priority.
Return Parameter:
Register D0.L : If D0.l is positive (no error), then the lower word
is the current priority of the given process. If D0.l
is negative, represents an error:
-62 : Permission violation. Process tried to change the priority but was
not a super user or owner.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
move.w delta,-(sp)
move.w process_id,-(sp)
move.w #$87,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.9 88: Allocate a block of system memory (top down)
char *Smalloc(mem_size)
long mem_size;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x88 | Word block addr)
+-------------------------------------+
| |
+ Size of memory to allocate + Long
| |
+-------------------------------------+ High memory
This call uses a top down memory allocation technique. Also, the block
allocated is NOT owned by the calling process, but belongs to the
operating system. This call is normally used to extend structures used
by the operating system.
Long Size of memory to allocate, or -1 to return size of largest
single memory fragment.
Return parameter
Register D0.L : If input parameter is -1, then is the size of the
largest block, or zero if no memory is available for
allocation. Else is the start of a memory block of
length mem_size, or zero if no block of sufficient size
is avaiable.
In assembly language:
move.l mem_size,-(sp)
move.w #$88,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.10 89: Assign a block of memory owned by calling process to process
of given process ID
long Massign(process_id,mem_start)
word process_id;
char *mem_start;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x89 | Word block addr)
+-------------------------------------+
| ID of process to assign memory to | Word
+-------------------------------------+
| |
+ Start address of memory to assign + Long
| |
+-------------------------------------+ High memory
This call is used to assign a block of memory owned by the calling
process to another process. The memory block to assign MUST be owned by
the caller (it can not have been allocated with Smalloc). Also, the
process to assign the memory to must exist and not be the same as the
caller. This call is used primarily by the Pexec routines to assign
memory allocated by the parent process during the Pexec call, to the
new process once it has been created.
Word Process ID of process to assign memory to.
Long Pointer to start of the memory block.
Return parameter
Register D0.L : Zero if no error (block was assigned properly), else
one of following errors:
-40 : Invalid memory block address. The calling process did not own the
memory it was trying to assign, or was not the start of a memory
block. Also caused by the calling process trying to assign its
base memory block (where its basepage is located) to another
process, which is illegal.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
pea mem_start
move.w process_id,-(sp)
move.w #$89,-(sp)
trap #1
addq.l #8,sp
+--------------------------------------------------------------------------+
7.11 8B: Perform various status operations on an open file
long Fstatus(handle,sub_function, ... )
word handle;
word sub_function;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x8b | Word block addr)
+-------------------------------------+
| File handle | Word 1
+-------------------------------------+
| Status function code | Word 2
+-------------------------------------+ High memory
| optional parameters |
+.....................................+
This call is primarily used to test for input or output available on an
open file, though it performs several other functions as well.
Word 1 Handle of an open file from which status information is being
sought.
Word 2 Status function to perform.
Sub function codes:
#define st_input 0 /* Test for input data available */
#define st_output 1 /* Test for device output ready */
#define st_size 2 /* Get size of file */
#define st_pos 3 /* Get r/w pointer position */
#define st_eof 4 /* Test for end of file */
#define st_rlock 5 /* Change record lock attributes */
/* Takes extra parameters; ????? */
#define st_extfile 6 /* Extend the files length */
/* Takes extra parameter; length to add to file */
#define st_readopt 7 /* Read options section of path desc */
/* Takes extra parameter; pointer to buffer to read parameters into */
#define st_wrtopt 8 /* Write options section of path desc */
/* Takes extra parameter; pointer to buffer to write parameters from */
#define st_name 9 /* Copy name of open file to buffer */
/* Takes extra parameter; pointer to buffer to read name into */
#define st_type 10 /* Return the file manager type for the file */
Return parameter
Register D0.L : The return from the call is dependent on the sub-
function desired. Also may return the following errors:
-32 : Invalid function number. In this case, the sub-function number
was not legal.
-37 : Invalid handle. The handle was not for a currently open file.
In assembly language:
move.w sub_function,-(sp)
move.w handle,-(sp)
move.w #$8b,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.12 8C: Perform Fsfirst function with index into directory structure
long Fsfirstidx(pathname,attributes,index)
char *pathname;
word attributes;
word index;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x8c | Word block addr)
+-------------------------------------+
| |
+ Pointer to pathname + Long
| |
+-------------------------------------+
| Attributes (as in Fsfirst) | Word 1
+-------------------------------------+
| Index of file to start at | Word 2
+-------------------------------------+ High memory
The primary purpose of this call is to simplify directory searching
over a network.
Long Pointer to null terminated pathname
Word 1 Attribute to search for (same as for Fsfirst)
Word 2 Index into directory of file to start at (0 is first file).
Return parameter
Register D0.L : Return code and errors are the same as for Fsfirst
In assembly language:
move.w index,-(sp)
move.w attributes,-(sp)
pea pathname
move #$8c,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
8D: Wake parent process of current process
long Wake_parent( code )
int code;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x8D | Word block addr)
+-------------------------------------+
| Code | Word
+-------------------------------------+ High memory
This call is used by the process terminate routine to reactivate the
parent of the teminating process. This call will only restart the
parent process if it is in the Wait queue. It has no effect otherwise.
May be used to reactivate parent process when child process wishes
to run concurrently.
Also see description of extended Pexec modes at the beginning of this
document.
Return parameter:
Register D0.L : If D0.L is zero, no error occurred. Possible error
is:
-87 : Orphaned process. The parent of the caller no longer exists.
In assembly language:
move.w #code,-(sp)
move.w #$8D,-(sp)
trap #1
addq.l #4,sp
+--------------------------------------------------------------------------+
7.13 8E: Wait for child process to terminate
long Wait()
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x8e | Word block addr)
+-------------------------------------+
This allows a process to block itself while awaiting the termination of
a child process, though a signal can also be used to unblock the
process. It is used by the Pexec function when using modes 0, 4 or 6.
Return parameter
Register D0.L : The error code of the terminating child process
(assuming it used Pterm or Ptermres). These error codes
are word in length, so the upper word of D0 will be
zero. If upper word of D0 is not zero, then it could be
a signal received through the Signal call, or a possible
error:
-72 : Process has no children to wait for.
In assembly language:
move.w #$8e,-(sp)
trap #1
addq.l #2,sp
+--------------------------------------------------------------------------+
7.14 8F: Sleep (block) for specified time, or indefinately
long Sleep(time)
long time;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x8f | Word block addr)
+-------------------------------------+
| |
+ Milliseconds or ticks to sleep + Long
| |
+-------------------------------------+ High memory
This is a general purpose CPU time management facility. It is also
called by several other PowerDOS function calls.
Long If zero, will sleep indifinately. A positive value is the number
of milliseconds to remain dormant. A negative value is taken as
the number of system ticks to remain dormant. A value of -1 causes
no sleep, but will cause a task switch if there is a process in
the ready-to-run queue with the same or higher priority.
Return parameter
Register D0.L : The number of ticks left to sleep (if it was a timed
sleep and a signal caused a premature activation).
In assembly language:
move.l time,-(sp)
move.w #$8f,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.15 90: Link to queue of processes waiting for access to I/O
long Ioqueue(process_id,time)
word process_id;
long time;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x90 | Word block addr)
+-------------------------------------+
| ID of process to link to | Word
+-------------------------------------+
| |
+ Milliseconds or ticks to sleep + Long
| |
+-------------------------------------+ High memory
This call is used to block while awaiting access to I/O which is
currently controlled by process_id.
Word ID of process to link to
Long Time to sleep (passed to the Sleep function call)
Return parameter
Register D0.L : Return parameter from Sleep function call, or possible
errors:
-76 : The process is trying to link to a process that is already linked
to it. This should never happen, but a check is made for it to
stop I/O deadlock from occurring.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
move.l time,-(sp)
move.w process_id,-(sp)
move.w #$90,-(sp)
trap #1
addq.l #8,sp
+--------------------------------------------------------------------------+
7.16 91: Wait (block) until a specified date/time
long Wait_dt(date_time)
unsigned long date_time;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x91 | Word block addr)
+-------------------------------------+
| Date/time (in XBIOS format) to |
+ + Long
| reactivate process at |
+-------------------------------------+ High memory
Long Date and time (in Xbios settime/gettime format) when process is
to be reactivated. If the date word is zero, then only the time
becomes significant (the date becomes a wildcard). Seconds are
not counted; the call will only return on the even minute. If a
date is used, but has already occurred, an immediate return
results (otherwise the process would never unblock).
Return parameter
Register D0.L : Always returns zero
In assembly language:
move.l date_time,-(sp)
move.w #$91,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.17 92: Create a new I/O device
long Dev_create(dev_name,fm_name,drv_name,path_vars,dev_vars,share)
char *dev_name;
char *fm_name;
char *drv_name;
char *path_vars;
char *dev_vars;
word share;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x92 | Word block addr)
+-------------------------------------+
| |
+ Pointer to name device will have + Long 1
| |
+-------------------------------------+
| |
+ Pointer to name of file manager + Long 2
| |
+-------------------------------------+
| |
+ Pointer to name of device driver + Long 3
| |
+-------------------------------------+
| |
+ Pointer to new path init vars + Long 4
| |
+-------------------------------------+
| |
+ Pointer to initial device vars + Long 5
| |
+-------------------------------------+
| Device share flag | Word
+-------------------------------------+ High memory
This function is used to create (add) a new device to PowerDOS.
For more information on this call, contact the PowerDOS authors.
Long 1 Pointer to name the new device will have. Must be seven
characters or less in length, and must be uppercase. String is
null terminated.
Long 2 Pointer to name of file manager for the device.
Long 3 Pointer to name of device driver for the device.
Long 4 Pointer to new path initialization vars. First word is number of
bytes to copy. Must be 40 or less.
Long 5 Pointer to device initialization vars. First word is number of
bytes to copy. Must be 40 or less.
Word Device share flag. If zero, device is shareable.
Return parameter
Register D0.L : Zero on success, else possible error codes:
-73 : I/O device table is full. No more devices may be added to the
system.
-74 : File manager or device driver was not found.
In assembly language:
move.w share-(sp)
pea dev_vars
pea path_vars
pea drv_name
pea fm_name
pea dev_name
move.w #$92,-(sp)
trap #1
lea 24(sp),sp
+--------------------------------------------------------------------------+
7.18 93: Add a new file manager to the system
long Fm_add(fm_name,subroutine_tab,fm_vars,fm_type)
char *fm_name;
char *subroutine_tab;
char *fm_vars;
word fm_type;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x93 | Word block addr)
+-------------------------------------+
| |
+ Pointer to file manager name + Long 1
| |
+-------------------------------------+
| |
+ Pointer to subroutine index table + Long 2
| |
+-------------------------------------+
| |
+ Pointer to file manager's variables + Long 3
| |
+-------------------------------------+
| File manager type | Word
+-------------------------------------+ High memory
This function is used to add a new file manager to PowerDOS. For
more information, panic and pick up the phone.
Long 1 Name by which the file manager will be known to the system. Must
be in uppercase, 7 characters max, null terminated.
Long 2 Pointer to subroutine index table. Each value in the table is a
signed int that is taken as an offset from the start of the
table to the service function (a relative offset).
Long 3 Pointer to any global variables that the file manager may
require. This value has no meaning to the kernal. It is simply
loaded into register a6 before calling the file manager service
routines.
Word File manager type code. Currently defined values are:
0 - Disk File Manager, FAT based storage allocation
1 - Pipe file manager
2 - Sequencial character file manager (CON:, AUX: PRN:, etc.)
3 - Network File Manager (PowerNET)
4 - Null file manager (sends data nowhere)
Return parameter
Register D0.L : Zero on success, else possible error code:
-73 : File manager table is full. No more file managers may be added
to the system.
In assembly language:
move.w fm_type,-(sp)
pea fm_vars
pea subroutine_tab
pea fm_name
move.w #$93,-(sp)
trap #1
lea 16(sp),sp
+--------------------------------------------------------------------------+
7.19 94: Add a new device driver to the system, or replace an old one
long Drv_add(drv_name,subroutine_tab,drv_vars)
char *drv_name;
char *subroutine_tab;
char *drv_vars;
{
}
dev_dd_add macro
+-------------------------------------+ Low memory (parameter
| Function Code 0x94 | Word block addr)
+-------------------------------------+
| |
+ Pointer to device driver name + Long 1
| |
+-------------------------------------+
| |
+ Pointer to subroutine index table + Long 2
| |
+-------------------------------------+
| |
+ Pointer to driver's variables + Long 3
| |
+-------------------------------------+ High memory
This function is used to add a new device driver to PowerDOS, or to
replace an existing one. The PowerDOS kernal does not use device
drivers directly; it merely notes their existance and allows them to be
logically tied to a file manager when a device is created with the
Dev_create call. For more information, call, but not collect.
Long 1 Name by which the driver will be known to the system. Must
be in uppercase, 7 characters max, null terminated.
Long 2 Pointer to subroutine index table. Each value in the table is a
signed int that is taken as an offset from the start of the
table to the service function (a relative offset). The meaning
of the entries in this table are dependant upon the file manager
for which the driver is designed to service.
Long 3 Pointer to any global variables that the device driver may
require. This value has no meaning to the file manager. It is
simply loaded into register a6 before calling the driver's
service routines.
Return parameter
Register D0.L : Zero on success, else possible error code:
-73 : Device driver table is full. No more drivers may be added
to the system.
In assembly language:
pea drv_vars
pea subroutine_tab
pea drv_name
move.w #$94,-(sp)
trap #1
lea 14(sp),sp
+--------------------------------------------------------------------------+
7.20 95: Return device info for requested device index
long Devinfo(idx,buffer)
word idx;
struct dev_info *buffer;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x95 | Word block addr)
+-------------------------------------+
| Index of device name to read | Word
+-------------------------------------+
| |
+ Pointer to buffer to receive info + Long
| |
+-------------------------------------+ High memory
This function returns three pieces of information about a device whose
device index number is provided. The information is placed into the
following structure:
struct dev_info {
char dev_name[8]; /* 7 char max device name, null terminated */
int fm_type; /* File manager type code */
int share_flag;
};
Word Index of device for which information is to be returned. Index
numbers start with zero.
Long Pointer to structure which will be filled in with information.
Return parameter
Register D0.L : Zero if no error, else possible error codes:
-85 : No device exists for this device number. The only cause for
this error is that a logical disk device was created at this
index number, but no physical device exists, therefore the device
is invalid.
-86 : No device exists for this or higher device index numbers, i.e. no
more devices exist.
In assembly language:
pea buffer
move.w idx,-(sp)
move.w #$95,-(sp)
trap #1
addq.l #8,sp
+--------------------------------------------------------------------------+
7.21 96: Send a signal to a process
long Send(process_id,signal_code)
word process_id;
long signal_code;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x96 | Word block addr)
+-------------------------------------+
| ID of process to send signal to | Word
+-------------------------------------+
| |
+ Signal to send to process + Long
| |
+-------------------------------------+ High memory
The Send function sends a signal to a specified process, and is similar
to the F$Send function call of OS-9. It can be used as a general
purpose interprocess communication facility, providing the information
to be exchanged can be represented in 32 bits or less. Also, there are
three predefined and reserved values that are interpreted by the Send
function itself. Currently, this call is used extensively by the
kernal and file managers to unblock processes that were blocked for
I/O. It is not as usefull as the Unix style signals, other than
passing a longword between processes. At some future date, a Unix like
signalling facility will probably be added to PowerDOS.
Word Process ID of the process to send the signal to. A process can
send a signal to itself.
Long The signal being sent. Three possible values are predefined:
0 - Kill
1 - Wake
2 - Keyboard abort
All other codes are user defined. If there is no signal intercept
routine installed, an error will be returned, although the
receiving process will be unblocked if it was blocked.
Return parameter
Register D0.L : Zero if no error, else possible error codes:
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
-88 : Process has no signal intercept routine installed. Signal cannot
be read by intended process.
In assembly language:
move.l signal_code,-(sp)
move.w process_id,-(sp)
move.w #$96,-(sp)
trap #1
addq.l #8,sp
+--------------------------------------------------------------------------+
7.22 97: Install signal intercept routine
long Sig_intercept(intercept_rtn,var_ptr)
int (*intercept_rtn)(long, void *);
long *var_ptr;
+-------------------------------------+ Low memory (parameter
| Function Code 0x97 | Word block addr)
+-------------------------------------+
| |
+ Address of signal intercept routine + Long 1
| |
+-------------------------------------+
| Pointer to pass to signal |
+ + Long 2
| intercept routine |
+-------------------------------------+ High memory
This routine allows a process to install a handler for signals that it
may receive from other processes. The handler must preserve registers
a3-a6/d3-d7. It will be executed in supervisor state, and must not
move to user state. It must not make any OS calls, just do what it
has to do to deal with the signal (like storing it for later
processing) and exit with an RTS.
Long 1 Address of a service routine.
Long 2 Pointer to any variables that the intercept routine may require.
When the service routine is called, this pointer will be passed
to it, along with the signal itself.
Return parameter
Register D0.L : Always zero, there is never an error
In assembly language:
pea var_ptr
pea intercept_rtn
move.w #$97,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
98: Suspend a process
long Suspend( process_id )
int process_id;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x98 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+ High memory
Note: only a super user process may suspend any process. Non-superuser
processes may only suspend processes with the same group.user id.
If the process to be suspended is in user state, it will be moved to
the event queue. If it is in system state, then it will be moved to the
event queue as soon as it reenters user state.
Word ID of process to suspend. If zero, the calling process will
suspend itself.
Return Parameter:
Register D0.L : If positive, then lowest byte is current queue of
process (if it was a process other than caller).
Possible error codes (if negative):
-62 : Permission violation. Non super user process may not suspend a
process with a different group.user id.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
move.w process_id,-(sp)
move.w #$98,-(sp)
trap #1
addq.l #4,sp
+--------------------------------------------------------------------------+
7.23 99: The Message Queue
int Q_message(mparams) /* Parameters are passed as a pointer to a structure */
struct mq_params {
int cmd; /* Command to execute (0-5) */
union {
char *name; /* 0 - Create, 1 - Open message queue */
int handle; /* 2 - Close, 3 - Delete queue */
struct {
int handle;
struct {
long data[4];
} *message;
long timeout;
} r_w; /* 4 - Read , 5 - Write message */
} cmd_blk;
} *mparams;
+-------------------------------------+ Low memory (parameter
| Function Code 0x99 | Word block addr)
+-------------------------------------+
| |
+ Pointer to parameter structure + Long
| |
+-------------------------------------+ High memory
This function provides access to the message queue. The messages passed
are represented by four longwords. A queue may be created, opened (if
it already exists), closed, deleted (if there are no other users), read
from and written to.
Long Pointer to a structure that contains parameters dependant upon
the function to perform.
/* To open an existing queue, or create it if it doesn't yet exist */
int q_make(name,q_parms)
char *name;
struct mq_params *q_parms;
{
int qh; /* Queue handle */
q_parms->cmd_blk.name = name;
q_parms->cmd = 1; /* Try to open existing queue */
if(qh = Q_message(q_parms) < 0){
q_parms->cmd = 0; /* If failed, try create */
if(qh = Q_message(q_parms) < 0)
return(-1);
}
return(qh); /* Queue handle back to caller */
}
/* Writing a message to a queue */
int q_write(qh,q_parms,q_msg)
int qh;
struct mq_params *q_parms;
struct qmsg {
long message[4];
} *q_msg;
{
q_parms->cmd_blk.r_w.handle = qh;
q_parms->cmd_blk.r_w.message = q_msg;
q_parms->cmd = 5;
return(Q_message(q_parms));
}
/* Reading from a queue */
int q_read(qh,q_parms,q_msg,timeout)
int qh;
struct mq_params *q_parms;
struct qmsg *q_msg;
long timeout; /* Used as parameter to Sleep function */
{
q_parms->cmd_blk.r_w.handle = qh;
q_parms->cmd_blk.r_w.message = q_msg;
q_parms->cmd_blk.r_w.timeout = timeout;
q_parms->cmd = 4;
return(Q_message(q_parms));
}
/* Closing and possibly deleting the queue */
int q_close(qh,q_parms)
int qh;
struct mq_params *q_parms;
{
int rc;
q_parms->cmd = 2;
q_parms->cmd_blk.handle = qh;
if(rc = Q_message(q_parms) == 0){ /* If we are last to close... */
q_parms->cmd = 3;
rc = Q_message(q_parms); /* Then delete the queue */
}
return(rc);
}
Return parameter
Register D0.W : Dependent upon function. If no errors, will return
queue handle (a positive integer) for create and open;
zero for delete, read and write; count of queue users
remaining for close (when close returns zero, no other
users of queue). Possible errors:
-52 : Bad name. Queue name passed to create or open was illegal.
-61 : Timeout. No message became available for read before timeout
expired. Returned on read command.
-73 : Table full; no room for another queue or message, and no memory
available to allow table expansion. Returned on create and
write.
-77 : Queue not found. There is no queue using the name passed in
queue open command.
-78 : Unknown queue. Handle passed in close, delete, read or write
does not represent a currently existing queue.
-79 : Queue in use. Cannot delete queue, as it is still opened by
another (or same) process.
-80 : Queue empty. There is no message to read. Returned from read
command when timeout is set to -1 (immediate exit if no message
available for read).
-81 : Queue already exists. Name passed as a parameter to the create
command is in use by another queue.
In assembly language:
pea mparams
move.w #$99,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.24 9A: The Semaphore function
int Semaphore(sparams) /* Parameters are passed as a pointer to a structure */
struct sparams {
int cmd; /* Command to execute (0-5) */
union {
char *name; /* Create, Open */
int handle; /* Close, Delete, Release */
struct {
int handle;
long timeout;
} own; /* Semaphore own */
} cmd_blk;
} *sparams;
+-------------------------------------+ Low memory (parameter
| Function Code 0x9a | Word block addr)
+-------------------------------------+
| |
+ Pointer to parameter structure + Long
| |
+-------------------------------------+ High memory
This function is exactly like the message queue, except there is no
message involved. Issuing a release command simply increments a count,
and issuing an own command decrements the count (a process doing an own
will be blocked if the count is less than one, for a time specified in
the timeout parameter).
Long Pointer to a structure that contains parameters dependant upon
the function to perform.
Return parameter
Register D0.W : Dependent upon function. If no errors, will return
semaphore handle (a positive integer) for create and
open; zero for delete, own and release; count of
semaphore users remaining for close (when close returns
zero, no other users of semaphore). Possible errors:
-52 : Bad name. Semaphore name passed to create or open was illegal.
-61 : Timeout. Count never became greater than zero before timeout
expired. Returned on own command.
-73 : Table full; no room for another semaphore, and no memory
available to allow table expansion. Returned on create.
-77 : Semaphore not found. There is no semaphore using the name passed
in open command.
-78 : Unknown semaphore. Handle passed in close, delete, own or
release does not represent a currently existing semaphore.
-79 : Semaphore in use. Cannot delete semaphore, as it is still opened
by another (or same) process.
-80 : Semaphore empty. Returned from own command when timeout is set
to -1 (immediate exit if count is less than one).
-81 : Semaphore already exists. Name passed as a parameter to the
create command is in use by another semaphore.
In assembly language:
pea sparams
move.w #$9a,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.25 9B: Shared memory
int Mem_share(msparams) /* Parameters are passed as a pointer to a structure */
struct msparams {
int cmd; /* Command to execute (0-3) */
union {
struct {
char *name;
char *start; /* Return: start of block */
long length; /* Input for create, return for open */
} c_o; /* Create, Open */
int handle; /* Close, Delete */
} cmd_blk;
} *msparams;
+-------------------------------------+ Low memory (parameter
| Function Code 0x9b | Word block addr)
+-------------------------------------+
| |
+ Pointer to parameter structure + Long
| |
+-------------------------------------+ High memory
This function provides for a named block of memory. This memory is not
owned by any process, but by the operating system; thus if a process
using the named memory terminates, the memory won't be freed.
Long Pointer to a structure that contains parameters dependant upon
the function to perform.
Return parameter
Register D0.W : Dependent upon function. If no errors, will return
shared memory handle (a positive integer) for create
and open; zero for delete; count of users remaining
for close (when close returns zero, no other users
of shared mamory). Possible errors:
-52 : Bad name. Shared memory name passed to create or open was
illegal.
-73 : Table full; no room for another name, and no memory available
to allow table expansion (so probably no memory available for
the actual shared memory block, either). Returned on create.
-77 : Memory name not found. There is no shared memory block using
the name passed in open command.
-78 : Unknown memory block. Handle passed in close or delete does
not represent a currently existing named memory block.
-79 : Named memory in use. Cannot delete, as it is still opened
by another (or same) process.
-81 : Named block already exists. Name passed as a parameter to the
create command is in use by another memory block.
In assembly language:
pea msparams
move.w #$9b,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
7.26 9E: Read or modify a GemDOS, BIOS or XBIOS function vector
long Chgvector(trap_num,vector_num,new_vector)
int trap_num;
int vector_num;
char *new_vector;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x9e | Word block addr)
+-------------------------------------+
| Trap number (1, 13 or 14) | Word
+-------------------------------------+
| Vector number to change | Word
+-------------------------------------+
| |
+ New vector or read only if -1 + Long
| |
+-------------------------------------+ High memory
This function allows a single function vector to be read or modified.
For instance, the trap #1 Fopen function could be intercepted, and
replaced by a whole new Fopen function.
Word Part of operating system for which function vector is to be
read or written, given as its trap number. Trap 1 is GemDOS,
trap 13 is the BIOS (Basic Input/Output System), and trap 14
is the XBIOS (eXtended Basic Input/Output System).
Word Function number of the vector to be read or written.
Long New vector, or -1 to denote a read only operation. Note: because
of the multitasking nature of PowerDOS, it is possible that
another running task could use the new function as soon as the
vector is modified. Therefore it is necessary to completely
initialize the replacement routine before its vector is
inserted into the function table. As soon as this call is made
to modify the function table, the replacement routine should be
able to handle requests made of it.
Return parameter
Register D0.L : If no errors (noted by a negative), will return the
previous contents of the vector. Possible errors:
-64 : Range error. Either an incorrect trap number was given (not
1, 13 or 14), or the vector number was too large.
In assembly language:
pea new_vector
move #vector_num,-(sp)
move #trap_num,-(sp)
move #$9e,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
7.27 9f: Read or modify a PowerDOS internal variable
long Chgsysvar(var_num,flag,new_value)
int var_num;
int flag;
long new_value;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0x9f | Word block addr)
+-------------------------------------+
| Number of variable to read/change | Word
+-------------------------------------+
| Read/change flag | Word
+-------------------------------------+
| New value if change flag <> 0 |
+ + Long
| (May be only lsb or lsw of long) |
+-------------------------------------+ High memory
Some of the internal PowerDOS variables may be read; others may be read
or written. This function call provides access to these values. In the
table below, a 'w' next to the number means it's a writeable value,
'r' means read only.
0 w = G_maxtpa long Max TPA size given to a new process
1 r = G_rsvmem long Artificial top of ram to limit m_alloc(-1)
2 w = G_rsvmaxbl long Max block size returned within topmem area
3 w = G_max_age word Max age to age a process
4 w = G_min_pty word Minimum ageable priority; if below, don't age
5 r = G_timeslice word Number of milliseconds per tick
6 r = G_idlecnt long Idle CPU time. In milliseconds
7 w = G_fastload long Amount of heap to clear on program startup
8 w = G_term long Vector jumped through on process termination
9 w = G_pexec long Vector jumped through on process creation
10 w = G_trace long Vector jumped through during function call trace
11 w = G_alias long Pointer to first in linked list of device aliases
12 w = G_pathcheck long Vector jumped through for path parse routine
13 w = G_extservic long Pointer to first in linked list of extended service function tables
14 r = G_version long GemDOS and PowerDOS version numbers
15 r = G_sysdate long Date/time of PowerDOS system build
16 unused
17 unused
18 unused
19 r = int_eos long Pointer to system interupt end-of-service handler
For G_term, G_pexec and G_trace, the vectors are initialized to 0, which
signals the kernal not to use the vector. Due to the fact that PowerDOS
uses preemptive multitasking, the only reliable way to grab one of these
vectors is to go into supervisor mode, set the IPL to 7, issue the call
to change (and return the old) vector, save the old vector (which may be
0L) then drop back to the previous IPL. The kernal will JSR through the
vector, and each program in the vector chain should do whatever processing
it needs to do, then fall through the saved vector, UNLESS IT WAS 0L. In
the later case, it should just RTS.
When a G_term vector is called, registers d5-d7/a5-a6 must be preserved.
a5 points to the process descriptor of the dying process. a6 points to
the kernals variables. G_term may be used to clean up a processes
environment or some such function.
G_pexec is called just before the following instructions, which execute
a new task:
movem.l (sp)+,d0-a6 Get new processes registers
rte Execute it
Thus any and all registers may be used. a5 points to the new processes
process descriptor, and a6 points to the kernals variables.
G_trace is called when a process makes a Trap #1 call, and has its
trace bit set (see function 0xa2 below). Register a4 will point to
the parameters to the call (thus 0(a4) will always be the function
number of the call being executed), a5 points to the process descriptor,
and a6 is the kernals variables; register d1 will be a 0 if this is the
start of the trace (trace is called before the execution of the
function, and again after the function is finished), or a -1 if this is
the end of the trace (a4 is undefined at the end of the trace). Registers
a4-a6 must be preserved. All others may be used (if d1 is -1, then d0 is
the return code from the function).
Word Variable that is to be read or possibly written. Numbered from
0 to 19. Currently numbers 16, 17 and 18 are not used, and will
return an error if you try to read or change them.
Word Read/change flag. Zero means read the variable only.
Long New value of variable if flag is not zero. Note that not all of
the variables are changeable. If you try to change a variable
that is read only, no error will be returned, just the contents
of the variable. Also, some of the variables are word, and some
are long. For word values, only the lower word of the long will
be used.
Register D0.L : If no errors (noted by a negative), will return the
previous contents of the variable. Possible errors:
-32 : Invalid variable number.
Note: no range checking is performed on the new value for a variable
(if flag is <> 0) so it is up to the caller to insure that the new
value is in range, else unpredictable results may occur.
In assembly language:
move.l new_value,-(sp)
move flag,-(sp)
move var_num,-(sp)
move #$9f,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
A0: Read or modify the name of a process
long Pname(proc_id,get_set,name)
int proc_id;
int get_set;
char *name;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0xA0 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+
| Get or set flag | Word
+-------------------------------------+
| |
+ Pointer to character array + Long
| |
+-------------------------------------+ High memory
This function allows you to read or change the name of a process.
Note that only the superuser may change the name of any process.
Non superusers may only change the name of processes with the
same group.user ID.
Word Process ID of the process whose name is to be read or written.
Zero stands for the current (calling) process.
Word Read or write flag. 0 means read.
Long Pointer to character buffer at least 14 bytes long for read,
(flag = 0), or null terminated string for new name (max
string length is 13 characrters).
Return parameter
Register D0.L : Zero if no errors detected. Possible errors:
-62 : Permission violation. Process tried to change the name but was
not a super user or did not have same owner ID.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
pea name
move #get_set,-(sp)
move #proc_id,-(sp)
move #$A0,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
A1: Read or modify a process' user vector
long Pvector(proc_id,vector)
int proc_id;
long vector;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0xA1 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+
| |
+ Vector + Long
| |
+-------------------------------------+ High memory
This function allows you to read or change a user defined vector for
any process. Note that the kernal doesn't look at or otherwise use
this vector. It is simply a very low level way to pass data between
processes. The long value could be a pointer to shared memory, or
just a longword value that has meaning to the processes involved.
Word Process ID of the process whose vector is to be read or
written. Zero stands for the current (calling) process.
Long If this is zero, then the call just returns the current
value of the user vector; else is the new value of the
vector. Thus the value zero cannot be used as a data
value.
Return parameter
Register D0.L : Old vector if no error. Possible errors:
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
Note: it is possible to confuse legitimate values with these two error
codes. It is therfore recomended that these values be avoided as
potential data.
In assembly language:
move.l #vector,-(sp)
move #proc_id,-(sp)
move #$A1,-(sp)
trap #1
addq.l #8,sp
+--------------------------------------------------------------------------+
A2: Set or clear bits in a process' attribute byte
long Pattrib(proc_id,flag,mask)
int proc_id;
unsigned char flag;
unsigned char mask;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0xA2 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+
| Set/Clear flag | Byte
+-------------------------------------+
| Bit mask for bits to change | Byte
+-------------------------------------+ High memory
This function allows you to selectively set or clear bits in the
processes attribute byte. Currently, these bits are defined:
#define B_redirect 0 /* Have BIOS check for con redirection */
#define N_redirect 1 /* Make negative handles redirect */
#define proc_trace 3 /* If set, jump through trace vector on function call */
Word Process ID of the process whose attribute byte is to be
changed. Zero stands for the current (calling) process.
byte Set or clear flag. If zero, is a clear bit operation, else is a
set bit operation.
byte Mask of bits to modify. If a bit is set in this byte, then that
particular attribute bit will be changed according to the flag
byte.
Return parameter
Register D0.L : If not negative, lower byte is attribute byte before
operation. Possible errors:
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
lsl.w #8,d0 d0 is flag byte
or.w d1,d0 d1 is mask
move d0,-(sp)
move #proc_id,-(sp)
move #$A2,-(sp)
trap #1
addq.l #6,sp
+--------------------------------------------------------------------------+
A3: Set or get the maximum memory returned for Malloc(-1) for a process
long Pmaxmem(proc_id,flag,size)
int proc_id;
int flag;
long size;
{
}
+-------------------------------------+ Low memory (parameter
| Function Code 0xA3 | Word block addr)
+-------------------------------------+
| Process ID | Word
+-------------------------------------+
| Set/get flag | Word
+-------------------------------------+
| |
+ New max memory value + Long
| |
+-------------------------------------+ High memory
This function allows you to set a maximum for a Malloc(-1) function
call made by a process. Since most programs will do a Malloc(-1) call
to determine how much memory is in the system, then malloc all of that
memory, this function can keep most memory hogs at bay. If this value
is set to zero for a process, then no maximum is in effect and the
kernal will return the size of the largest block of ram. Note: a
newly forked process will inherit its parent's max_mem setting.
Also, only a super user may change this value for all processes, else
only processes with the same group.user ID may be changed.
Word Process ID of the process whose max memory value is to be
read or written. Zero stands for the current (calling) process.
Word Set or get flag. If zero, is a get operation, else is a
set operation.
Long New max memory value for a set call.
Return parameter
Register D0.L : If not negative, is original setting before a set call.
Possible errors:
-62 : Permission violation. Process tried to change the max mem value
but was not a super user or did not have same owner ID.
-70 : Unknown process. Process ID is for a process that has never
existed (no process descriptor has been created for that PID).
-71 : Dead process. The process ID was for a process that has
terminated.
In assembly language:
move.l #size,-(sp)
move #flag,-(sp)
move #proc_id,-(sp)
move #$A3,-(sp)
trap #1
lea 10(sp),sp
+--------------------------------------------------------------------------+
Following are listings some important PowerDOS structures. These are
shown, not as C structures, but as Hisoft formatted assembly language
defines, since PowerDOS was written completely in assembly language.
The PowerDOS process descriptor:
Num_files equ 32 Number of open files per process
RSRESET
PD_ID rs.w 1 Process ID
PD_parent rs.w 1 Parent's ID
PD_sibling rs.w 1 Sibling's ID
PD_child rs.w 1 First child's ID
PD_group rs.w 1 Group ID
PD_user rs.w 1 User ID
PD_priority rs.w 1 Process priority
PD_age rs.w 1 Process age
PD_status rs.b 1 Process execution status
PD_queueID rs.b 1 Current queue (sleep, wait or active)
PD_basepage rs.l 1 First memory block of process (basepage)
PD_max_mem rs.l 1 Max mem size returned for Malloc #-1
PD_ucall rs.w 1 Last user state function call executed
PD_scall rs.w 1 Last system state function call executed
PD_uticks rs.l 1 Number of user state ticks elapsed
PD_sticks rs.l 1 Number of system state ticks elapsed
PD_sleep rs.l 1 Count of ticks to remain sleeping
PD_datetime rs.l 1 Date and time process started
PD_fcalls rs.l 1 Number of function calls executed
PD_iocalls rs.l 1 Number of i/o calls executed
PD_rbytes rs.l 1 Number of bytes read
PD_wbytes rs.l 1 Number of bytes written
PD_vector rs.l 1 User defined vector
PD_dta rs.l 1 Disk transfer address
PD_name rs.b 14 Name of process
PD_devname rs.b 8 Process current device name (currently only A, B, C, etc.)
PD_files rs.w Num_files Process local path handles
PD_reentry rs.b 1 Count of number of levels of reenterancy to kernal
PD_attrib rs.b 1 Various attributes
PD_memblk rs.w 1 Index of head of procs mdb's
PD_pqueue rs.l 1 Previous process queue pointer
PD_nqueue rs.l 1 Next process queue pointer
PD_pioq rs.w 1 ID of previous process in i/o queue
PD_nioq rs.w 1 ID of next process in i/o queue
PD_q_ptr rs.l 1 Pointer or flag for queue functions
PD_intcpt rs.l 1 Address of signal intercept routine
PD_intcptv rs.l 1 Address of vars needed for intercept
PD_signal rs.l 1 Signal code that caused death
PD_stack rs.l 1 Process stack pointer
PD_reg_save rs.l 1 Pointer to current (X)BIOS register save
PD_trap1 rs.l 1 Save area for "dirty" trap one vector
PD_alias rs.l 1 Pointer to alias being used for current i/o operation
PD_defdirs rs.l 26 Default directory of up to 26 drives
* Dir's first cluster number, 0 for root. Copied from parent when created
* Most file managers that use this feature require only words, but a long
* is allocated for future file managers.
PD_status2 rs.b 1 Place for new attributes to be stored
PD_reserve1 rs.b 1
PD_reserve2 rs.w 18 Space for additions in the future...
PD_stackbot rs.b 1000 Process supervisor stack space
PD_sstack equ __RS Top of process supervisor stack
rs.b 162 Allow for 3 levels of reentrancy to (X)BIOS
PD_bios_sav equ __RS
PD_size equ __RS Size of process descriptor
* Process descriptor block allocation size. First long is pointer to next
* block. Ten process descriptors per block allocated
PD_alloc equ 4+PD_size*10
* Status flag bits (for PD_status)
Sys_state equ 0 Executing in system state
Wake_sig equ 1 Process has pending wakeup signal
Time_out equ 2 Time slice has expired
Subtask equ 3 Process is a subtask (thread) of parent
Pexec4 equ 4 Assign base memory to parent on exit
Condemn equ 5 Process is condemned
Concurrent equ 6 Task is running concurrently with parent
Deskthread equ 7 Set if process is Desktop process or decendent
* Bit definitions for PD_attrib
B_redirect equ 0 Have BIOS check for con redirection
N_redirect equ 1 Make negative handles redirect
proc_trace equ 3 If set, jump through trace vector on function call
* Status flag bits for PD_status2
s2_preempt equ 0 Allow preemption when clear, even if process is in system state
s2_suspend equ 1 Suspend process at next entry to user state
* Defined signals
S_kill equ 0
S_wake equ 1
S_abort equ 2
* (Maybe someday PowerDOS will have a more Unix like signalling system)
* Queue ID codes (for PD_queueID)
Q_current equ 0 No queue, currently running
Q_active equ 1 Active process queue
Q_sleep equ 2 Sleeping process queue
Q_wait equ 3 Waiting process queue
Q_event equ 4 Waiting for an event
Q_dead equ 5 No queue, dead process
+--------------------------------------------------------------------------+
Error code definitions (some are only used internally)
Edskchg equ -14 Disk in drive was changed
Einvfn equ -32 Invalid function number
Efilnf equ -33 File not found
Epthnf equ -34 Pathname not found
Enhndl equ -35 No file handles left
Eaccdn equ -36 Access denied
Eihndl equ -37 Invalid handle number
Ensmem equ -39 Not enough memory left
Eimba equ -40 Invalid memory block address
Edrive equ -46 Invalid drive specification
Enmfil equ -49 No more matching files
Ebnam equ -52 Bad pathname element
Efaterr equ -53 Error with FAT table
Edskfull equ -54 Disk is full
Elpcl equ -55 Clusters looped
Erootful equ -56 Root directory is full
Edirex equ -57 Directory already exists
Elocked equ -58 Record is locked
Enslock equ -59 Can't find requested lock to remove
Eeof equ -60 End of file
Etime equ -61 Device timed out
Epermit equ -62 Permission violation
Enovol equ -63 No volume name, can't change attributes
Erange equ -64 Range error
Eintrn equ -65 Internal error
Eplfmt equ -66 Invalid program load format
Egsbf equ -67 Setblock failure
Eunknp equ -70 Unknown process
Edeadpr equ -71 ID is for dead process
Enochld equ -72 Process has no children
Etabfull equ -73 IO device table is full
Efmddne equ -74 File manager or device driver non-existant
Eprocnf equ -75 Process with this name not found
Eioqs equ -76 Process already part of this ioqueue chain
Eqnf equ -77 Queue not found (by name)
Eunknq equ -78 Unknown queue (by queue_id)
Eqinuse equ -79 Queue in use; can't delete
Eqempty equ -80 Queue has no message or count available
Eqexist equ -81 Can't create; queue w/ same name exists
Epipex equ -82 Can't create; pipe w/ same name exists
Epipenf equ -83 Named pipe not found for open
Epipewrt equ -84 Pipe write error: written data can't be read
Enodev equ -85 No device for given device number
Enomdev equ -86 No devices with given number or higher
Eorphan equ -87 Process is an orphan; it has no parent
Enosighand equ -88 Process has no signal handler installed
+--------------------------------------------------------------------------+
Kernal variables:
RSRESET
G_active rs.l 1 Head of active queue
G_sleep rs.l 1 Head of sleeping queue
G_wait rs.l 1 Head of waiting queue
G_event rs.l 1 Head of event queue
G_cur_pd rs.l 1 Process descriptor of current process
G_totram rs.l 1 Total ram found in system (TPA size)
G_bottpa rs.l 1 Bottom of TPA
G_toptpa rs.l 1 Top of TPA
G_maxtpa rs.l 1 Maximum tpa size given to process
G_rsvmem rs.l 1 High water mark of (S)Malloc(-1) calls
G_rsvmaxbl rs.l 1 Max block size returned in G_rsvmem area
G_mem_mdb rs.l 1 Points to 1st block of memory descriptor blocks
G_hmem_st rs.w 1 Index of head of memory segment list (ST ram)
G_tmem_st rs.w 1 Index of tail of memory segment list
G_sys_mem rs.w 1 Index of linked system memory blocks
G_memblks rs.w 1 Number of free memory block descriptors
* Extra ram that may be added to the system is allways considered fastram.
* When a block is added for the first time, the index to the head and tail
* of the memory (the next two variables) are defined. If any more memory
* is added after this, it will be added in to the same structure. (If it
* is not contiguous with previous added ram, there will be a gap, but the
* memory allocate and free routines deal with this situation properly.)
G_hmem_alt rs.w 1 Head of alternate (TT) memory
G_tmem_alt rs.w 1 Obviously the tail of said memory
G_pd rs.l 1 Points to 1st process descriptor block
G_pthd rs.l 1 Points to 1st path descriptor block
G_queue_dir rs.l 1 Points to 1st queue directory block
G_queue_buf rs.l 1 Points to 1st queue buffer block
G_max_age rs.w 1 Max age to age a process
G_min_pty rs.w 1 Min priority of ageable process
G_timeslice rs.w 1 Number of milliseconds per tick (20)
G_ticks rs.w 1 Number of ticks per second (50)
G_timeout rs.l 1 Global timeout added to 200 hz clock
G_idlecnt rs.l 1 Used to keep track of idle time in 5 ms periods
G_idlecntdn rs.w 1 Count till next increment
G_fastload rs.l 1 Number of k of heap to clear on prg load
G_aes_stack rs.l 1 Current aes stack top
G_term rs.l 1 Vector to jump through on proc term
G_pexec rs.l 1 Vector to jump through on proc create
G_trace rs.l 1 Vector to jump through to trace a process' function calls
G_alias rs.l 1 Pointer to any drive/path replacements
G_pathcheck rs.l 1 Vector to jump through before path parsing
* To allow PowerDOS to be expanded (or to emulate other OS's), a pointer
* to another table of vectors is available (zero when not used). The first
* long in this table is a pointer to another such table. The third word
* is the lowest sevice number in the table, and the fourth word is the
* highest service number. Following this is the long word pointers to
* the service functions. If a vector in this table is not used (an unused
* function) it should be set to zero.
G_extservic rs.l 1 Pointer to a table of extended services
G_p_run rs.l 1 GemDOS p_run pointer; points to basepage
G_version rs.w 1 Version number of GemDOS we are replacing
G_sysver rs.w 1 Version of PowerDOS
G_sysdate rs.l 1 Date of PowerDOS build (YYYYMMDD)
G_flags rs.b 1 Various flags bits that may be needed
* Definitions for the bits in G_flags.
Gf_cookjar equ 0 Set if PowerDOS installed the cookie jar
Gf_server equ 1 Set if system is being used as a network server
G_reserve rs.b 1
* When we launch a concurrent task, we give it clean OS vectors so no tsr
* programs will also be in the vectors. Such programs tend to fail when
* used in a multitasking environment. The following are the original
* vectors set when PowerDOS was installed.
G_trap1 rs.l 1 Vector for BDOS
G_trap13 rs.l 1 Vector for BIOS
G_trap14 rs.l 1 Vector for XBIOS
* The following is the special reserved block of memory used for video ram. Both
* its start address and index are given. This is for the Falcon only, to emulate
* the Mrealloc function call.
G_videomem rs.l 1 Start address of special videomem block
G_videoidx rs.w 1 Index of MDB of video memory
+--------------------------------------------------------------------------+