The <system.h> header file


  
This header file contains the following functions:
AB_prodid           AB_prodname         AB_serno            ASM_call
ASM_fastcall        CB_fetchTEXT        CB_replaceTEXT      CU_restore
CU_start            CU_stop             enter_ghost_space   EX_patch
HelpKeys            idle                kbd_queue           NeedStack
off                 OSCheckBreak        OSClearBreak        OSContrastDn
OSContrastUp        OSdequeue           OSDisableBreak      OSEnableBreak
OSenqueue           OSFreeTimer         OSqclear            OSqhead
OSqinquire          OSSetSR             OSRegisterTimer     OSReset
OSTimerCurVal       OSTimerExpired      OSTimerRestart      OSVFreeTimer
OSVRegisterTimer    QModeKey            QSysKey             SumStoChkMem
WordInList          XR_stringPtr
and the following predefined types:
Bool                DEF_QUEUE           QUEUE               Timers

Functions


void ASM_fastcall (void *base_addr);

Calls a subroutine located on absolute address.

ASM_fastcall calls an assembly subroutine located at absolute address base_addr. As ASM_fastcall is a macro, not a function, base_addr need not to be a pointer. It can also be an unsigned (long) integer. In fact,
ASM_fastcall (base_addr);
is the same as
((void(*)(void))(base_addr))();
but much more readable. It performs just "jsr" to base_addr; it does not perform any relocation of relocatable items (to do this, see EX_patch).

ASM_fastcall assumes that called subroutine will not destroy any registers. If this assumption is not valid, use ASM_call instead. In fact, if you are not very sure about behaviour of called subroutine, it is highly recommended to avoid ASM_fastcall and to use ASM_call. In releases of TIGCCLIB prior to 2.1, ASM_call does exactly what ASM_fastcall does in this release.

NOTE: This function should be used with great care, because on HW2 calculators a stupid protection device does not allow that the program counter may be on arbitrary place, except if some special precausions are performed. Anyway, this function is not designed for common use: it is intended for very experienced system programmers. Don't use it if you don't know very well what are you doing!

void ASM_call (void *base_addr);

Calls a subroutine located on absolute address, with saving/restoring all registers.

ASM_call pushes all registers onto the stack, performs ASM_factcall, then restores all saved registers from the stack. Use ASM_call whenever you are not sure about behaviour of called subroutine. If you are sure that the called subroutine will preserve all registers, you can use ASM_factcall: it generates smaller and faster code.

void EX_patch (void *base_addr, void *tag_ptr);

Relocates an assembly program.

EX_patch relocates relocatable items in the assembly program (.89z or .9xz file), where tag_ptr points to the "PROGRAM" signature (tag) byte (byte 0xF3), and base_addr is the address from where the assembly program will be started. So, if handle is a handle of an .89z (or .9xz) file, you can execute it using
len = * (unsigned short*) (base_ptr = HLock (handle));
EX_patch (base_ptr + 2, base_ptr + len + 1);
ASM_call (base_ptr + 2);
HeapUnlock (handle);
In practice, some protection devices in HW2 calculators make the whole thing much more complicated (see the FAQ list for more info).

Note that the relocation table begins just below the signature byte.

void enter_ghost_space (void);

Transfers the execution into a "ghost address space".

enter_ghost_space transfers the program control into the "ghost address space" (i.e. into the area above address 0x40000, which does not exist physically on the calculator, but represents a "ghost" of the regular RAM space). This function is introduced to bypass some protections introduced in AMS 2.04 and AMS 2.05 (the protection device does not protect the "ghost space", so you have greater rights there). From the logical aspect of view, enter_ghost_space simply adds 0x40000 to the program counter. In practice, this is performed on very awkward way, because some new protections in AMS 2.04 and AMS 2.05 does not allow us to do this directly under all conditions. See the Frequently Asked Question list for the only example where you really should use this function. You should not to know anything more about it.

void OSSetSR (short SR);

Sets the processor status register

OSSetSR sets the processor status register to SR. Supervisor and trace bits cannot be set up using this routine. For example, use
OSSetSR (0x0700);
to disable all interrupts, and
OSSetSR (0x0000);
to enable them again. Note that any call to keyboard input routines like ngetchx etc. will enable interrupts again.

NOTE: Disabling Auto-Int 1 is often used for making the status line indicators not visible on the screen so that the status indicators do not mess up your graphics (status line indicators are updated from this interrupt). In this case, you need to read the keyboard using _rowread function, because functions like ngetchx are based on Auto-Int 1. However, if you disable interrupts, the grayscale will not work, because the grayscale is also based on Auto-Int 1. To solve this problem, instead of disabling Auto-Int 1, you may redirect it to nothing. See DUMMY_HANDLER in intr.h header file for more info.

void OSReset (void);

Resets the calculator.

OSReset resets the calculator without any warnings.

void OSContrastUp (void);

Increases the contrast.

OSContrastUp increases the display contrast.

void OSContrastDn (void);

Decreases the contrast.

OSContrastDn decreases the display contrast.

void OSEnableBreak (void);

Enables the BREAK key.

OSEnableBreak enables the BREAK key (of course, NOT during execution of assembly programs)! However, BREAK key may be read from assembly programs using OSCheckBreak.

NOTE: Although the BREAK (i.e. ON) key is disabled during execution of assembly programs, execution of some TIOS functions may be breaked by pressing BREAK key (usually functions which executes some internal loops with long or undeterminate duration, like various high-level linking functions, etc.). Usage of OSDisableBreak will disable BREAK key even in such cases.

void OSDisableBreak (void);

Disables the BREAK key.

OSDisableBreak disables the BREAK key. See also OSEnableBreak.

short OSCheckBreak (void);

Checks pressing of BREAK key.

OSCheckBreak returns TRUE if BREAK key was pressed (for this, BREAK must be enabled using OSEnableBreak), else returns FALSE. Note that OSCheckBreak will remain true until explicite call of OSClearBreak.

void OSClearBreak (void);

Clears "BREAK key pressed" flag.

OSClearBreak clears "BREAK key pressed" flag. See OSCheckBreak for more info.

void AB_prodid (char *buffer);

Determines the product ID code.

AB_prodid fills the buffer with the product ID code of the calculator. The ID string is in the form "p-h-r-b", where "p" is the product number (01 for TI-92 Plus, 03 for TI-89), "h" is the hardware revision level, "r" is the software revision level and "b" is the build number. All the above fields consist of hexadecimal digits. buffer must be at least 12 bytes long to accept the product ID string.

void AB_prodname (char *buffer);

Determines the product name.

AB_prodname fills the buffer with the product name, i.e. the name of the operating system software running on the calculator. This is the same name that appears on the second line of the "About" window. Not very useful, because it seems that so far the product name is always "Advanced Mathematics Software". buffer must be at least 40 bytes long to accept the product name.

short AB_serno (char *buffer);

Determines the serial number.

AB_prodname tries to fill the buffer with the serial number of the calculator. The serial number is constructed from the string returned from cgetsn function (with one space inserted in the middle), and from the hexadecimal value returned from FL_getVerNum function. Note that these routines are very cryptic, and do some ugly things with the Flash memory, so this probably works only on real TI (at least, it does not work under VTI). AB_serno returns TRUE if determining the serial number was successful, else returns FALSE (this is a case on VTI, for example). The serial number has the form "pphnn nnnnn vvvv", where "pp" is the platform number (01 for TI-92 Plus, 03 for TI-89), "h" is hardware revision level, "nnnnnnn" is an ID number which is unique to each calculator, and "vvvv" is a verification number. All the above fields consist of hexadecimal digits. buffer must be at least 17 bytes long to accept the serial number.

void off (void);

Turns the calculator off.

off turns the calculator off. asm("trap #4") does exactly same thing, but calling this routine is more official.

void idle (void);

Switches the calculator to "idle" state for a while.

While idle is running, the calculator rests. idle turns the calculator in "low power" state until the next interrupt occurs (then "low power" state will be disabled, and idle returns).

While calculator is in "idle" state, the power consumption decreases significantly. TIOS very often calls idle, whenever it is in a kind of "idle loop". So it is very useful to be used in programs which waits in a loop for something (waiting for specific keypress, timer expiring, etc.). Many programs should use idle to save the batteries (editors, reflexive games, explorers, debuggers etc.). Thanks to Julien Muchembled for this info.

NOTE: Thomas Nussbaumer informed me that idle interfere with the grayscale graphic, so usage of idle while grayscale mode is active is not recommended.

short OSRegisterTimer (short timer_no, unsigned long T);

Registers a notify (countdown) timer.

TIOS has a 6 notify (countdown) timers, numbered from 1 to 6. OSRegisterTimer initializes the timer which ID number is timer_no, and sets its initial value to T. Every time the Auto-Int 5 is triggered (20 times per second if you didn't change the programable rate generator), the current value of the timer is decremented by 1. When the current value reaches zero, nothing special happens, but a flag is set which indicates that the timer is expired. This flag may be check using function OSTimerExpired.

OSRegisterTimer returns timer_no if the registration was successful, else returns zero. This happens if you give wrong parameters, or if the timer timer_no is already in use. So, you must first free the timer using OSFreeTimer. Notify timers 2, 3, 4 and sometimes 5 are used in TIOS for internal purposes, and it seems that timers 1 and 6 are free for use (especially I expected that 6 are surely unused, and I am not so sure for timer 1). Timer 5 is sometimes used for measuring time in some TI-Basic functions like CyclePic. Timer 4 is used for cursor blinking. Timer 3 is used for link communication. Timer 2 is used for automatic power-down (APD) counting, so this is an official method to change APD rate to, for example, 100 seconds:
OSFreeTimer (APD_TIMER);
OSRegisterTimer (APD_TIMER, 100*20);
Legal timer numbers (like APD_TIMER) are defined in enum Timers, to make a program more readable. See also other timer functions for more info.

short OSFreeTimer (short timer_no);

Frees a notify (countdown) timer.

OSFreeTimer deactivates and frees the notify (countdown) timer timer_no. OSFreeTimer must be called before registering a timer using OSRegisterTimer if the timer was already in use. Returns FALSE in a case of error, else returns TRUE.

unsigned long OSTimerCurVal (short timer_no);

Determines a current value of a notify (countdown) timer.

OSTimerCurVal returns a current value of the timer timer_no.

short OSTimerExpired (short timer_no);

Determines whether a notify (countdown) timer expired.

OSTimerExpired returns TRUE if the notify (countdown) timer timer_no expired, else returns FALSE. See OSRegisterTimer for more info. For example, a legal way to make a 5-second delay is:
OSFreeTimer (USER_TIMER);
OSRegisterTimer (USER_TIMER, 5*20);
while (!OSTimerExpired (USER_TIMER));
OSTimerExpired also resets flag which tells that the timer was expired, so the calling this function again will return FALSE.

unsigned long OSTimerRestart (short timer_no);

Restarts a notify (countdown) timer.

OSTimerRestart resets the timer timer_no to its initial value, and returns the current value of the timer as was before reseting.

short OSVRegisterTimer (short timer_no, unsigned long T, void (*Action)(void));

Registers an event (vectored) timer.

Before release 2.04 of the AMS, TIOS also had two event (vectored) timers numbered as 1 and 2 (in addition to 6 notify timers which may be registered using OSRegisterTimer). In AMS 2.04, Texas Instruments decided from some strange reasons to remove vectored timer from the TIOS. I was very angry due to this decision, so I decided to reimplement these timers indepentently of the TIOS, to make them working on any AMS version. Well, now you have it. More precise, you now have two event (vetcored) timers which are numbered as 1 and 2, which works on any AMS release (TIOS based implementation as implemented in TIGCCLIB releases prior to 2.2 did not work on AMS 2.04 and AMS 2.05).

OSVRegisterTimer initializes the event timer which ID number is timer_no, and sets its initial value to T. Every time the Auto-Int 5 is triggered (20 times per second if you didn't change the programable rate generator), the current value of the timer is decremented by 1. When the current value reaches zero, a procedure specified by user will be called, then the timer starts counting again from its initial value. The parameter Action is the pointer to the procedure which will be triggered every time the timer reaches zero. So, the procedure Action will be called periodically, with a period determined by T.

Action need not to be an assembly language procedure; it may be any user-defined function written in C. Its body will be executed in the supervisor CPU mode and with disabled interrupts (th information is probably not important from the user point of view).

If the function Action changes any global variable in the program, such global variable must be declared as "volatile" to inform the compiler that its value may be changed asynchronously, i.e. in a way which is unexpected for the normal program flow.

OSVRegisterTimer returns a nonzero value if the registration was successful, else returns zero. This happens if you give wrong parameters, or if the timer timer_no is already in use. So, you must first free the timer using OSVFreeTimer (as I completely rewrote these routines, I also corrected some bugs in them which were presented in TIOS routines; you know about them if you read the documentation about OSVRegisterTimer in earlier releases of TIGCCLIB). As event timers now work indepentently of TIOS timers, both event timers (1 and 2) are free for use. Here is a simple example of the program which installs both event timers:
#include <tigcclib.h>

int _ti89, _ti92plus;

void Action1 (void)
{
  static int Counter = 0;
  printf_xy (50, 50, "Counter1=%d  ", ++Counter);
}

void Action2 (void)
{
  static int Counter = 0;
  printf_xy (70, 70, "Counter2=%d  ", ++Counter);
}

void _main(void)
{
  OSVRegisterTimer (1, 3, Action1);
  OSVRegisterTimer (2, 10, Action2);
  ngetchx ();
  OSVFreeTimer (1);
  OSVFreeTimer (2);
}
In this implementation of OSVRegisterTimer, it is not necessary to free timers using OSVFreeTimer before first usage of them, because they are free by default at the begining. However, nothing wrong will happen if you try to free them explicitely (which was necessary in previous releases of TIGCCLIB).

NOTE: As already mentioned above, all TIOS bugs in timer routines (dependence between notify and event timers, etc.) are now removed, because these routines are rewritten to be independent of the TIOS.

short OSVFreeTimer (short timer_no);

Frees an event (vectored) timer.

OSVFreeTimer deactivates and frees the event (vectored) timer timer_no. OSVFreeTimer must be called before registering a timer using OSVRegisterTimer if the timer was already in use. Returns FALSE in a case of error, else returns TRUE.

NOTE: Don't forget to free an event timer which was registered before exiting the program; else very bad things may happen later. I expect that you know why...

short OSenqueue (unsigned short data, void *Queue);

Insert a new element into a queue.

OSenqueue inserts the element data in a queue (FIFO - First In First Out) structure pointed to by Queue. Queue is usually a pointer to the structure of the type QUEUE or DEF_QUEUE. OSenqueue returns TRUE if the operation was sucessful, else return FALSE (for example, if the queue is full). See destription of queue types QUEUE and DEF_QUEUE for an example of usage.

short OSdequeue (unsigned short *dest, void *Queue);

Removes an element from a queue.

OSdequeue removes an element from a queue structure pointed to by Queue and stores them in the variable pointed to by dest. As queue is a FIFO structure, first removed element is the first element inserted in the queue; the next removed element is the second element inserted in the queue, etc. OSdequeue returns TRUE if the queue was empty, else returns FALSE. See also OSenqueue.

NOTE: This function may be used for fast keyboard reading: see kbd_queue.

short OSqinquire (unsigned short *dest, void *Queue);

Checks whether an element is waiting in a queue.

OSqinquire returns TRUE if the queue pointed to by Queue is not empty (i.e. if there is an element waiting in it), else returns FALSE. If the queue is not empty, OSqinquire also stores the first element which will be removed from the queue in the variable pointed to by dest, but in opposite to OSdequeue the element itself will not be removed from the queue. See also OSenqueue.

unsigned short OSqhead (unsigned short *dummy, void *Queue);

Gets an element from the head of a queue.

OSqhead returns an element from the head of a queue structure pointed to by Queue without removing it from the queue (the head element is the last element inserted in the queue, not the first one). dummy is the dummy parameter: it is not used in the routine. See also OSenqueue.

void OSqclear (void *Queue);

Clears a queue.

OSqclear empties and resets the queue structure pointed to by Queue. More precise, it resets the structure to {0, 0, 2, 0}. See also OSenqueue.

void *kbd_queue (void);

Returns a pointer to the keyboard queue.

kbd_queue returns a pointer to the queue used in TIOS for keyboard handling. It may be used as an argument to other queue-related functions. The main purpose of accessing to keyboard queue is to make a fast replacement for ngetchx and kbhit functions. This may be achieved using OSdequeue function. For example, suppose that you have the following declarations:
void *kbq = kbd_queue ();
int key;
Then, statements like
if (kbhit ())
  {
    key = ngetchx ();
    // Do something with key
  }
may be replaced with much faster equivalent:
if (!OSdequeue (&key, kbq))
  {
    // Do something with key
  }
NOTE: On the first look, it seems that the key repetition feature does not work with OSdequeue. But, Marcos Lopez informed me that this is not exactly true. Key repetition feature works even with OSdequeue, but it will not return the keycode itself for the repeated key, but sets an additional bit in the keycode, so value becomes value + 0x800. If you use standard ngetchx function, this additional bit is masked out and your program will get the keycodes it expects. But, it is very simple to mask out this bit manually and make the key repetition feature working even with OSdequeue.

short WordInList (unsigned short Word, const unsigned short *List);

Searches for a word in the list.

WordInList is an useful short routine which returns TRUE if the word Word is a member of the list (i.e. array) of words pointed to by List, otherwise returns FALSE. The list of words is terminaded by word 0.

void NeedStack (short Size);

Checks for a space on the stack.

NeedStack throws a memory error if there is no enough space on the processor stack for Size bytes (the hardware stack is 16K in size; when a function calls another function the system will throw an error if there is not enough hardware stack to make the call). Although this routine is used mainly internally in TIOS, sometimes it may be useful even in user programs. For example, a function may have a complex set of operations that may not be easily undone in a ONERR block. The function may also require that all of the operations do not fail due to a lack of hardware stack. In this case, the function can be started with a call to NeedStack to at least guarantee that the hardware stack will not overflow during the critical section of the function. Critical operations may be, say, direct modifying elements of the VAT table. So, if the function calls NeedStack first, this insures that none of the critical operations are partially completed due to a lack of hardware stack thus leaving the VAT table (for example) in an undefined state. The TI-Basic interpreter uses the hardware stack to make recursive calls and so all TI-Basic commands and functions cannot rely on the hardware stack being at any particular level.

char *XR_stringPtr (long XR_string_no);

Returns a pointer to a TIOS system message (XR string).

XR_stringPtr returns a pointer to the TIOS system message which number is given in XR_string_no. It is not recommended to make use of these ID's as they are not consistent across ROM versions, and are mainly used interally for efficiency (although it seems that these ID numbers are the same in all AMS versions starting from AMS 2.00). For example, dialog structures and EV_sendString use them. All tokens (like "sin" etc.) are also XR strings.

void HelpKeys (void);

Displays a keyboard help screen.

HelpKeys displays a keyboard help on the screen (the help screen which may be called by pressing Diamond+EE on TI-89), waits for a keypress, then restores the screen to the previous state.

short QSysKey (short code);

Checks whether argument is code of a system key.

QSysKey returns TRUE if code is code of a system key, else returns FALSE. It assumes that code is code as the function ngetchx for reading the keyboard returns. System keys are keys which opens menus, which may have as the result inserting characters or tokens in the editor. The following keys are system keys on the TI-89: MATH, CATALOG, CHAR and CUSTOM (codes 4149, 278, 4139 and 4373).

short QModeKey (short code);

Checks whether argument is code of a mode key.

QModeKey returns TRUE if code is code of a mode key, else returns FALSE. It assumes that code is code as the function ngetchx for reading the keyboard returns. Mode keys are keys which may cause change of the current application or the configuration of the calculator. The following keys are mode keys on the TI-89: HOME, APPS, MODE, VAR-LINK, SWITCH (2nd+APPS), MEM, QUIT, Y=, WINDOW, GRAPH, TblSet, TABLE and OFF (codes 277, 265, 266, 4141, 4361, 4150, 4360, 16652, 16653, 16654, 16655, 16656 and 4363). Note that codes returned by ngetchx are mostly equal like codes returned by BASIC command GetKey, but codes of arrow keys, and keys pressed together with Diamond keys are different. See ngetchx for more info.

short SumStoChkMem (void);

Checks memory content by making a checksum.

SumStoChkMem calculates a checksum of the user portion of the RAM memory (more precise, from address 0x400 to 0xFFF and from the bottom of the heap to the end of the RAM), and stores the calculated value in one internal system variable. Returns TRUE is calculated checksum is equal to the previous value of this system variable, else returns FALSE. So, SumStoChkMem may be used for checking whether the content of the memory was changed since the last call of SumStoChkMem (i.e. between two calls of SumStoChkMem).

short CU_start (void);

Starts the cursor.

CU_start restarts the cursor timer and sets an internal flag which tell that cursor is active. This does not mean that the cursor will be displayed on the screen immidiately. This mean only that if some routine wants to display cursor, it will be permitted. The main usage of this function is in conjuction with text editor functions (see textedit.h header file). CU_start returns TRUE or FALSE, depending of whether the cursor was enabled or disabled before calling this function.

short CU_stop (void);

Stops the cursor.

CU_stop resets an internal flag which tell that cursor is active, so after this function, displaying of the cursor will be denied. This function is called often from event driven and interrupt driven applications to stop the cursor blinking for a while. CU_stop returns TRUE or FALSE, depending of whether the cursor was enabled or disabled before calling this function.

void CU_restore (short State);

Restores the previous cursor state.

CU_restore restores the previous cursor state (active or inactive). Parameter State should be a value returned from CU_start or CU_stop function.

short CB_replaceTEXT (char *text, unsigned long len, short strip_CR);

Puts a text into the clipboard.

CB_replaceTEXT puts len bytes starting from the address text to the clipboard. TIOS only uses clipboard for storing text, but it is capable to store other types too. strip_CR is Boolean parameter: if it is TRUE, each byte which follows immidiately after '\r' character (0xD) will not be stored in the clipboard (this in fact stripes out command characters in text editor: see textedit.h header file). CB_replaceTEXT returns TRUE if the operation was successful, else returns FALSE (e.g. no enough memory). This routine may cause heap compression.

short CB_fetchTEXT (HANDLE *hText, unsigned long *len);

Fetches a text from the clipboard.

CB_fetchTEXT stores in the variable pointed to by hText the handle of the text stored in the clipboard (use HeapDeref to get actual pointer to the text). It also stores the length of the text in the variable pointed to by len. See also CB_replaceTEXT. CB_fetchTEXT returns TRUE if the operation was successful, else returns FALSE (i.e. if the clipboard is empty or trashed).


Predefined types


enum Bool

Bool is enumerated type for describing true or false values. It is defined as
enum Bool {FALSE, TRUE};

enum Timers

Timers is enumerated type for describing timer ID numbers. It is defined as
enum Timer {BATT_TIMER = 1, APD_TIMER = 2, LIO_TIMER = 3, CURSOR_TIMER = 4,
  MISC_TIMER = 5, USER_TIMER = 6};
See timer functions (OSRegisterTimer etc.) for more info.

type DEF_QUEUE

DEF_QUEUE is a structure which describes a header of a variable-sized queue. It is defined as
typedef struct
  {
    unsigned short Head;      // Offset to the head of the queue
    unsigned short Tail;      // Offset to the tail of the queue
    unsigned short Size;      // Max number of entries in the queue
    unsigned short Used;      // Actual number of entries in the queue
    unsigned short Buffer[0];
  } DEF_QUEUE;
Note that Buffer[0] is a GNU C extension for variable-sized arrays (TIGCC is GNU C). The main usage of DEF_QUEUE structure is when you want to allocate a queue dynamically on the heap (using malloc). The operator sizeof treats variable-sized arrays as zero-length arrays (this is a sense of zero in square brackets). So, the following example ilustrates correct allocating of a queue with 100-byte long buffer on the heap (note that 100-byte long buffer can store 50 entries, because each int entry is 2 bytes long):
DEF_QUEUE *qptr = malloc (sizeof (DEF_QUEUE) + 100);
OSqclear (qptr);
qptr->Size = 50;
OSenqueue (some_data, qptr);
From this example you can see that you need to fill field Size of the queue structure manually.

type QUEUE(n)

QUEUE(n) is a structure which describes a queue with n-byte long buffer. Strictly speaking, QUEUE(n) is not a type but a macro defined as
#define QUEUE(n) struct {unsigned short Head, Tail, Size, Used, Buffer[n/2];}
although it works exactly as a type, so you can treat it as a type. It is useful for definining a queue without dynamic allocation (i.e. without calling malloc), like in following example:
QUEUE(100) q;
OSqclear (&q);
q.Size = 50;
OSenqueue (some_data, &q);
Note that QUEUE(n) works exactly like type, so it can be used anywhere where type name is expected, for example in pointer declarations, and even as the argument of sizeof etc. This is ilustrated in following example:
QUEUE(100) *qptr = malloc (sizeof (QUEUE(100)));
OSqclear (qptr);
qptr->Size = 50;
OSenqueue (some_data, qptr);
See also DEF_QUEUE for more info.

Return to the main index