GRCLIB for Rex 6000 V1.4

This is a package which provides a library of useful functions for the Rex Addin programmer. This library is used by some of my other software and it may be required to make use of those other programs.

Installation

Copyright (C) 2002 Graham R. Cobb. The package is distributed under the GPL (see the copyright notices and the COPYING file).

GRCLIB For Rex 6000 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

GRCLIB For Rex 6000 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

The GRCLIB distribution contains four main files in the top level directory (as well as sources and some informational files):

The addin programmer has a choice of two forms of the library to use:

The package also contains the sources for the two forms of the library and the shareable library addin and also for two versions of a test addin: one linked with the self-contained library and one linked with the shareable library.

Documentation

For GRCLIB Version 1.4.

Hex display routines

These six routines all work similarly. They format a numeric value as a hex string in a supplied buffer.

The grc_ltoh and grc_ltoh_nox versions take an unsigned long value. The grc_utoh and grc_utoh_nox versions take an unsigned short value. The grc_btoh and grc_btoh_nox versions take an unsigned char value.

The ...toh_nox versions do not prefix the values with 0x. The other versions do.

Here is the more detailed documentation for grc_ltoh, the others are similar.

Prototype

unsigned char *grc_ltoh (unsigned char *str, unsigned long n)

Parameters

Return Value

Start address of buffer. The buffer will contain 0xNNNNNNNN\0 where N are the hex digits.

Hex parsing routines

These three routines all work similarly. They parse a hex string in a supplied buffer to create a value.

The grc_htol version creates a longword (32-bit) result. The grc_htou version creates a word (16-bit) result. The grc_htob version creates a byte (8-bit) result.

Here is the more detailed documentation for grc_htol, the others are similar.

Prototype

unsigned char *grc_htol (unsigned char *str, unsigned long *p_n)

Parameters

Return Value

Success: Remainder of buffer. This is a pointer to the first byte which is not part of the hex string.

Error: NULL. If the leading part of the buffer does not contain at least a single hex digit or if the hex string is too long for the value (i.e. more than 8 digits for a long), an error occurs.

Notes

  1. The string can optionally start "0x" (or "0X") or have no prefix.
  2. All digits can be lower or upper case.
  3. The value need not contain the maximum number of digits, as long as it contains at least one digit.

grc_select

Wait for a key press (actually a key release) or a button touch.

Prototype

int grc_select(void)

Return Value

Notes

  1. The routine handles long presses (event KEY_xxx_E) but converts such events to their short equivalent (KEY_xxx_C).
  2. CLOSE is converted into a HOME key press
  3. This routine is adapted from cMemo (Copyright 2001 Chris Harris)

grc_display_message

Display a long string (e.g. an "About" string) as a full-screen message, with intelligent line breaks.

Prototype

void grc_display_message (unsigned char *text)

Parameters

Notes

Waits for a key press before continuing.

grc_prompt and related macros

Display a message and up to three buttons. Indicate which button was pressed.

Prototype

int grc_prompt(unsigned char *title, unsigned char *text, unsigned char *positive_text, unsigned char *zero_text, unsigned char *negative_text, int def_value)

Parameters

Return value

Notes

  1. Any of the buttons may be NULL in which case it will not be displayed.
  2. DsDialogWindow is used to display the dialog box.

Macros

The macros provide convenient calls for common button combinations. In all cases, the macros specify no title and the caller just provides the text.

grc_trace, grc_debug and related macros

Display debug information on top line of screen and wait for a key to be pressed.

Prototypes

void grc_trace(unsigned short a, unsigned short b, unsigned short c)
void grc_debug(unsigned char *txt, unsigned short b, unsigned short c)

Parameters

Notes

grc_trace displays the text TRACE: followed by the three numbers in hexadecimal (with leading 0x).

grc_debug displays the text DEBUG: followed by the two numbers in hexadecimal (without leading 0x) and as much of the string as will fit on the remainder of the top line.

Both functions wait for a key press before continuing.

Macros

Two macros can optionally be defined to make it easy to conditionalise debugging output.

If you want to use this feature, create your debugging output using trace and debug. For example:
debug("Error writing",return_value,input);

Then compile with -DGRCDEBUG to enable debugging output and with -DGRCNODEBUG to disable it.

grc_get_long_pointer

Convert a virtual address into a long pointer, as required by DsDialogDisplay.

This is useful for passing the address to a Rex library routine which will map the address using Bank 1.

Prototype

unsigned long grc_get_long_pointer(void *addr)

Parameter

Return value

long pointer value: high word is bank number, low word is address.

Notes

  1. If the address is not in Bank 1 or Bank 2, the returned bank is 0 and the returned address is the input virtual address.
  2. If the address is in Bank 1, the returned bank is the value from the register (the logical bank number -- this is the physical bank number less 4). In this case the returned address is the same as the input virtual address.
  3. If the address is in Bank 2, the returned bank is the value from the register decremented by 4 (the logical bank number). The returned address is the input VA less 0x2000.
  4. These conventions match those used by DsDialogWindow and are convenient for code which will map the address using Bank 1. Note that these conventions are different from those used by grc_get_bank_and_offset (which are designed to be convenient for code which will map addresses using Bank 2).

grc_get_bank_and_offset

Provide the bank number and offset for a virtual address.

This is useful for passing the address to another addin (e.g. a subroutine library) which will map the address using Bank 2.

Prototype

unsigned short grc_get_bank_and_offset(void *addr, unsigned short *bank, unsigned short *offset)

Parameters

Return value

Bank number (a copy of the value returned in *bank).

Notes

  1. If the address is not in Bank 1 or Bank 2, *bank is 0 and *offset contains the input virtual address
  2. The bank number is always returned as the physical address shifted right 13 bits (divided by 0x2000). This is known as a physical bank number and is suitable for use directly when loading Bank 2; however it must be decremented by 4 when loading Bank 1.
  3. These conventions are convenient for code which will map addresses using Bank 2. Note that these conventions are different from those used by grc_get_long_pointer (which match those used by DsDialogWindow and are designed to be convenient for code which will map the address using Bank 1).

grc_map_bank_and_offset

Map a memory bank and return the adjusted virtual address. This is the inverse of grc_get_bank_and_offset.

This is useful when receiving a bank and offset from another add-in..

Prototype

void *grc_map_bank_and_offset(unsigned short bank, unsigned short offset)

Parameters

Return value

void *address -- mapped virtual address.

Notes

  1. If bank is 0, offset contains the VA and is just returned without doing any mapping.
  2. If the bank is non-zero it will be mapped as Bank 2 and an address in the range 0xA000 to 0xBFFF will be returned.
  3. The bank number is assumed to be the physical address shifted right 13 digits (divided by 0x2000). This is known as a physical bank number and is as returned by grc_get_bank_and_offset. If a logical bank number is known (e.g. from grc_get_long_pointer) this must be incremented by 4 for use with this routine.

grc_copy_string

Copy a string (e.g. input to a library routine) to a buffer (e.g. on the stack). The advantage of this routine over strncpy is that the copy is always properly terminated and that NULL input parameters are handled.

Prototype

unsigned char *grc_copy_string(unsigned char *in_string, unsigned char *buffer, unsigned short length)

Parameters

Return value

Address of buffer or NULL

Notes

If in_string is NULL, buffer will be set up to be an empty string (i.e. buffer[0]=0) but NULL (not buffer) will be returned. This is the only case where the routine returns anything other than the address of the buffer.

grc_choose_memo

Allow the user to select an existing Memo from the database.

Prototype

int grc_choose_memo(unsigned char *title, unsigned char *buffer, unsigned short length, unsigned char *memo_name)

Parameters

Return value

Notes

  1. If the buffer is too short no error is returned -- the leading part of the name of the selected memo will be stored.
  2. If the memo_name memo exists, it will be selected as the current memo and will be visible. If it does not exist,the following memo (if any) will be selected.
  3. The user can use the scrollbar or the up and down arrow buttons to navigate. The user can select a memo by tapping on the name or using the Enter button. Pressing the Back or Home keys cause an error to be returned (GRC_ERR_CANCEL or GRC_ERR_EXIT, respectively).
  4. This routine is adapted from cMemo (Copyright 2001 Chris Harris).

grc_list_memos

Return array of IDs of memos, in alphabetical order.

Prototype

int grc_list_memos(unsigned long *p_id_array, unsigned short max_ids)

Parameters

Return value

Notes

  1. If there are more than max_ids memos, the first max_ids will be returned.

grc_memo_id_to_name

Get the name of a memo from the ID.

Prototype

int grc_memo_id_to_name(unsigned long id, unsigned char *buffer, unsigned short max_length)

Parameters

Return value

Notes

  1. If the buffer is too short no error is returned -- the leading part of the memo name will be stored.

grc_find_library

Find the page number for a library addin. If the library is missing, an error message is displayed and, once the user presses a button, the caller addin exits.

Prototype

int grc_find_library(char *signature, char *library)

Parameters

Return value

Page number for library call.

Note

For obvious reasons, this routine should only be called directly, not in a library.

grclibmain.h

This is not a library routine but a header file.

This header file implements a generic LibMain procedure to dispatch library functions based on a dispatch table.

The header file is designed to be included at the start of the library LibMain function. If the function ID code is not found in the dispatch table this code will fall through. The programmer can then decide how to handle the error.

The dispatch table itself must be called LibEntryPoints and must be an array of grclibentry_t structures (defined in grclib.h), terminated by an entry in which the function address is NULL.

Example

grclibentry_t LibEntryPoints[] = {
	{ID1, func1},
	{ID2, func2},
	...
	{0, NULL}
	};

void LibMain(void)
{
#include <grclibmain.h>
... code to handle invalid ID code ...
}

Parameters

This code assumes a maximum number of parameters for the functions being called. Functions with fewer parameters work correctly (but waste some stack space). The default is 20 parameters (40 bytes in all). To override this just define MAXLIBPARAMS to the desired value before including this file.

Changes

In version 1.4

Add grclibmain.h.

In version 1.3

Add grc_find_library

In version 1.2

Release for new Rexdk library mechanism


Return to Graham's Rex page

This page has been accessed Access counter times.

Graham Cobb