GFA-BASIC Library
Subject: Documentation/Programming
Author: Lonny Pursell
HTML conversion created with STG2HTML v0.75
Written by Lonny Pursell and ENCOM
Note: Images are not supported.
Index
Main
GFA-BASIC Compiler | Linker | Library | Interpreter
Introduction
Important notes
Emulation notes
Interpreter notes
Known problems
New features (Sorted A-Z -> index)
Library versions (68K/V4E)
Moving from older libs to GBE Lib
Writing a clean GEM application
Advanced debugging
Tutorials
Notes
Credits
Support
Info
License agreement
Compiler - change log
Linker - change log
Library - change log
Interpreter - change log
Development
Disclaimer
The Atari Compendium
The documentation for TOS (aka TOS.HYP)
NVDI 4.1 Programmer's Guide
WWW: http://gfabasic.net/
IRC: lp @ #Atariscne @ IRCnet
(C)2005-2023 Lonny Pursell and ENCOM
Document not found
The requested document was not found.
Please recheck your typing and try again or check the index for the page
you were looking for.
Help
The requested document was not found.
Please recheck your typing and try again or check the index for the page
you were looking for.
Info
How to use this HYPertext
At the end of most pages are external links to 'The Atari Compendium'
(compend.hyp) which should be placed in the same directory as this
document. The external links are denoted by the '+' sign after them.
These documents should also be installed:
tos_hyp.hyp
nvdi_410.hyp
Example:
appl_init()+ would be an external link to the page 'appl_init()' in the
compend.hyp.
The external links provide additional information which may be more
accurate than the information provided in this document.
If a page has no comments, it's safe to assume the parameter scheme is
identical to the official documentation. Anything special about the
command or function will be noted. External links are provided for additional
information as there's no need to duplicate what has already been documented
by others.
If a syntax definition shows void '~', this means the function returns
nothing useful.
String parameters are used where they make sense, paths and file names etc.
Null termination is handled internally by GFA making things a whole lot
easier.
None of the OS functions call GFA's built-in error handler. All error handling
must be managed by looking at the return values.
GFA-Basic
GFA-Basic is the best BASIC for the Atari!
Lonny Pursell
WWW: http://gfabasic.net/
DR
Digital Research
Misc
_0 to _9 _VERSION _BUILDINFO _CPUID _BOOTDEV
ACC? AUTO?
ARRAY() ARRAY!() ARRAY|() ARRAY&() ARRAY%()
ARRAYSIZE() INDEXCOUNT()
BCOMPARE() BCOMPARE&() BCOMPARE%()
BCOUNT() BCOUNT&() BCOUNT%()
BCRYPT CRYPT$()
BEXG MEMEXG& MEMEXG%
BFILL MEMFILL& MEMFILL%
BFIND() BFIND&() BFIND%()
BINSTR()
BMIRROR MEMMIRROR& MEMMIRROR% MEMMIRROR3 MIRROR$()
BMPSIZE() _BMPSIZE BPL() WDWIDTH()
BETWEEN() BOUND() CONSTRAIN()
BREPLACE MEMREPLACE& MEMREPLACE%
BSWAP&() BSWAP() BSWAP3()
BXLATE XLATE$()
BZERO MEMZERO& MEMZERO%
COMPILED? M68K?
CONTERM() KEYCLICK KEYREPEAT SYSBELL
CRC8() CRC16() CRC32() CHECKSUM()
CREAD CWRITE PREAD PWRITE
C2P
DIGITAL$()
ENDSEEK
ERL
FREEFILE()
GSTICK GSTICK() GSTRIG()
HINYBLE() HIBYTE() HIWORD() HICARD()
ISASCII() ISBLANK() ISCNTRL() ISPRINT() ISSPACE()
JOIN() SPLIT() GETSTR() SETSTR()
JOYPAD JOYPAD()
LOG_MSG LOG_SET LOG_FILE LOG_KILL
LOWER$() LCASE$() UCASE$()
LTRIM$() RTRIM$() ZTRIM$()
MAKE() MAKE|() MAKE&() MAKE%()
MDPOKE MDPEEK() LMPOKE MLPEEK()
MEMAND MEMOR MEMXOR
MEMBCHG| MEMBCHG& MEMBCHG%
MEMBCLR| MEMBCLR& MEMBCLR%
MEMBSET| MEMBSET& MEMBSET%
MEMBTST|() MEMBTST&() MEMBTST%()
MEMSWAP& MEMSWAP%
MIRROR() MIRROR|() MIRROR&() MIRROR3()
MNAM
MROUND()
NEAREST_RGB() AVERAGE_RGB GRAYSCALE()
NULL
NYBLE() SWAP|()
NYBLE{} HINYBLE{}
PIXEL1M PIXEL2P PIXEL4P PIXEL8P
PIXEL1M() PIXEL2P() PIXEL4P() PIXEL8P()
PIXEL8C PIXEL15 PIXEL16 PIXEL24 PIXEL32
PIXEL8C() PIXEL15() PIXEL16() PIXEL24() PIXEL32()
PCR()
RC_EQUAL()
REPLACE$()
RGB RGB() RGB256() RGB1000() RGB64K()
SBYTE() SBYTE{}
SCALL SUBPTR() S:
SNDH
STRARRAYFILL
STRPOKE STRPEEK$()
STRUCT()
STRUCT!() STRUCT|() STRUCT&() STRUCT%() STRUCT$()
SYSTAB SYSTAB() SYSTAB?
TRNFM()
UNPACK()
USERDEF!() USERDEF|() USERDEF&() USERDEF%()
USERDEFBIT USERDEFBYT USERDEFWRD USERDEFLNG
VER2STR
WAITVBL
CONTERM
old=CONTERM(new) (v3.7)
old: ivar
new: iexp
This function is used to read\write the system variable 'conterm' ($484).
This location contains a bit array which determines several system attributes
as follows:
If 'new' = -1 it does an inquire only.
Bit Meaning if Set
0 Enable key-click
1 Enable key repeat
2 Enable system bell
3 Cause BCONIN() to return, Shift status
See also KEYCLICK, KEYREPEAT, and SYSBELL.
MM: System Variables+
SYSTAB
value=SYSTAB(index) (v3.7)
addr=SYSTAB
flags=SYSTAB?
index: iexp
value: ivar
addr, flags: avar (able to hold a 32-bit value)
SYSTAB returns the address of an internal table. It's compatible with
ST-BASIC and HiSoft BASIC. GFABASIC further extends this table with more
information. Some entries assume the AES and/or VDI has been initialized.
SYSTAB -> as pointer
0-25 ST-BASIC (✓ = supported)
26-75 HiSoft BASIC (✓ = supported)
76-93 GFABASIC (all entries supported)
SYSTAB() -> as indexed word array
Any value for an index not listed generates error code #71.
Internal table layout:
SYSTAB SYSTAB() Size Description Value Support
0 0 word number of bit planes _B ✓
2 1 word edit ghost line style 2
4 2 word edit window AES handle 0
6 3 word list window AES handle 0
8 4 word output window AES handle 0
10 5 word command window AES handle 0
12 6 word edit window open flag 0
14 7 word list window open flag 0
16 8 word output window open flag 1
18 9 word command window open flag 0
20/22 10/11 word pointer to graphics buffer 0
24 12 word gem flag 0
26 13 word x left position of useable area 0
28 14 word y top position of usable area 0
30 15 word x right position of usable area _W-1
32 16 word y bottom position of usable area _H-1
34 17 word internal vdi handle V~H ✓
36 18 word default character pixel width GRAF_HANDLE ✓
38 19 word default character pixel height ... ✓
40 20 word workstation x position 0 ✓
42 21 word workstation y position 0 ✓
44 22 word workstation width _W ✓
46 23 word workstation height _H ✓
48 24 word library/interpreter version $0370=3.70 ✓
50 25/26 long screen address for PUT/GET 0
54 27/28 long basepage address BASEPAGE ✓
58 29 word desktop usable area x WIND_GET ✓
60 30 word desktop usable area y ... ✓
62 31 word desktop usable area width ... ✓
64 32 word desktop usable area height ... ✓
66 33 byte currency symbol for PRINT USING 36 -> $
67 33 byte append control-z at CLOSE flag 0
68 34/35 long LINE INPUT # buffer size 32767 ✓
72 36 word PRINT top margin of window 1
74 37 word PRINT bottom margin of window 1
76 38/39 long $Mx value at compile time (editor -> MaxMem setting)
80 40/41 long $Kx value (editor -> SysMem setting)
84 42/43 long Line-A ftab (a1) from Line-A init
88 44 word $Zx slow motion speed, line pause (50th of a second)
90 45 word current line number or -1
92 46 word program flags at compile time (editor -> 0)
SYSTAB? returns a 32-bit long, should be treated as a bit field:
Bit Description
0 compiled flag
1 started from auto folder
2 started as an accessory
3 LOG_SET status
4 debug symbols present via $D+
5 binary contains stack check code
6 binary contains line number data
7 save line number to crash report area
8 dump line number to screen
9 line step, wait for key
10 line pause, slow motion
11 to 31 reserved (always false)
Examples:
version&=SYSTAB(24)
' or
version&=WORD{SYSTAB+48}
IF BTST(SYSTAB?,0)
PRINT "compiled code"
ELSE
PRINT "interpreted"
ENDIF
BCOUNT
total=BCOUNT(addr,count,value) (v3.7)
total=BCOUNT&(addr,count,value)
total=BCOUNT%(addr,count,value)
total: ivar
addr, count, value: iexp
These functions will count the occurrences of a byte, word, or long value in a
block of memory.
BCOUNT() - count the occurrences of a byte value in a block of memory
if value is passed as word or long, only lower byte is considered
BCOUNT&() - count the occurrences of a word value in a block of memory
if value is passed as long, only the lower word is considered
BCOUNT%() - count the occurrences of a long value in a block of memory
addr - address of memory block
count - size of memory block in bytes
if count <= 0 then total = 0 (call is ignored)
value - byte value to be counted
if value is passed as word or long, only the lower byte is considered
total - if value is found it returns the number times it was encountered
if value is not found it returns 0
Notes about variants:
Word and long variants should start on an even address.
The word variant rounds count down to a value divisible by 2 if it's odd.
The long variant rounds count down to a value divisible by 4 if it's odd.
BCRYPT
BCRYPT addr,count,key$ (v3.7)
out$=CRYPT$(in$,key$)
addr, count: iexp
key$, in$: sexp
out$: svar
These commands and functions perform simple key based encryption on memory
blocks or strings. The data will be encrypted based on the supplied key. The
same exact key must be used to decrypt the data. The longer the key, the more
scrambled it becomes.
BCRYPT - Encrypt a memory block.
addr - address of buffer to be encrypted
count - the size of the buffer in bytes
if count <= 0 the command is ignored
key$ - unique key (or password)
if len(key$) = 0 the command is ignored
if len(key$) => 1 encryption will take place
CRYPT$() - Encrypt a string.
in$ - the data to be encrypted, left unchanged
if len(in$) = 0 then out$ will be a null string
key$ - unique key (or password)
if len(key$) = 0 then in$ is returned unchanged
if len(key$) => 1 encryption will take place
out$ - the result of the encryption
will always be the same length as in$
Example:
test$="GFA-BASIC 3.7 crypt test"
PRINT "before: ";test$
'
BCRYPT V:test$,LEN(test$),"fubar"
PRINT "after: ";test$ !prints garbage
'
BCRYPT V:test$,LEN(test$),"fubar", !undo it
PRINT "decoded: ";test$
BFIND
result=BFIND(addr,count,value) (v3.7)
result=BFIND&(addr,count,value)
result=BFIND%(addr,count,value)
result: ivar
addr, count, value: iexp
These functions will find the first occurrence of a byte, word, or long within
a memory block.
BFIND() - Find a byte value within a block of memory.
only the lower byte is considered if a word or long is passed
BFIND&() - Find a word value within a block of memory.
only the lower word is considered if a long is passed
must start on an even address
cnt is rounded down to an even number divisible by 2
BFIND%() - Find a long value within a block of memory.
must start on an even address
cnt is rounded down to an even number divisible by 4
addr - address of memory block
count - size of memory block in bytes
if count <= 0 then result = 0 (call is ignored)
value - value to be found
result - if value is found the address within the memory block is returned
if value isn't found 0 is returned
BINSTR
result=BINSTR(addr,count,target$) (v3.7)
result: ivar
addr, count: iexp
target$: sexp
This function will find the first occurrence of a string of characters within a
defined memory block.
addr - address of memory block
count - size of memory block in bytes
if count <= 0 then result = 0
target$ - character string to search for
if len(target$) = 0 then result = 0
if len(target$) > count then result = 0
result - if target$ is found the address within the memory block is returned
if target$ isn't found 0 is returned
BREPLACE
BREPLACE addr,count,obyt,nbyt (v3.7)
MEMREPLACE& addr,count,owrd,nwrd
MEMREPLACE% addr,count,olng,nlng
addr, count, obyt, nbyt: iexp
owrd, nwrd: iexp
olng, nlng: iexp
This commands replace occurrences of a byte, word, or long value in a block of
memory.
BREPLACE - Replaces all occurrences of a byte value in a block of memory.
addr - address of memory block
count - size of memory block in bytes
if count <= 0 then the function call is ignored (returns 0)
obyt - old byte value to search for
if a word or long is passed, only the lower byte is considered
nbyt - new byte value to replace it with
if a word or long is passed, only the lower byte is considered
MEMREPLACE& - Replaces all occurrences of a word value in a block of memory.
MEMREPLACE% - Replaces all occurrences of a long value in a block of memory.
Notes: MEMREPLACE& and MEMREPLACE% round count down to an even value and must
start on an even address.
Example:
n$=STR$(16,8) !pad to 8 places
BREPLACE V:n$,LEN(n$),32,48 !32 -> 48 / " " -> "0"
PRINT n$ !-> 00000016
BXLATE
BXLATE addr,count,table$ (v3.7)
out$=XLATE$(in$,table$)
addr, count: iexp
out$: svar
in$, table$: sexp
These command will remap characters in a block of memory or a string.
Useful for table based ASCII translation.
BXLATE - Translate a memory block.
addr - address of buffer to be remapped
count - size of buffer in bytes to be remapped
if count <= 0 the command is ignored
table$ - table used to translate the input string
this string must be exactly 256 bytes or error #60 occurs
The value of each byte at addr will be used as in index into the table.
The byte at that index will be used to replace the one in the buffer.
XLATE$() - Translate a string.
in$ - string to be translated, left unchanged
if len(in$) = 0 then out$ will also be null
table$ - table used to translate the input string
this string must be exactly 256 bytes or error #60 occurs
out$ - string result
Example:
' generates a table that remaps lower case characters to upper case
CLR table$
FOR i=0 TO 255
table$=table$+UPPER$(CHR$(i))
NEXT i
'
in$="gfa-basic 3.7 XLATE test"
'
PRINT in$
BXLATE V:in$,LEN(in$),table$
PRINT in$
Displays: gfa-basic 3.7 XLATE test
GFA-BASIC 3.7 XLATE TEST
BZERO
BZERO addr,count (v3.7)
MEMZERO& addr,count
MEMZERO% addr,count
addr, count: iexp
These commands fill a memory block with zero (0).
BZERO - Fills using bytes
addr can be odd
MEMZERO& - Fills using words
addr should be even
Will fill odd size blocks
MEMZERO% - Fills using longs (fastest variant)
addr should be even
Will fill odd size blocks
addr - Address of memory block
count - Size of memory block in bytes
if count <= 0 the command is ignored
Note: For max speed (assuming addr is even) use the MEMZERO% variant.
Commnad Writes Iterations
BZERO adr%,16 16 bytes 16
MEMZERO& adr%,16 8 words 8 iterations
MEMZERO% adr%,16 4 longs 4 iterations
BSWAP
vout=BSWAP&(vin) (v3.7)
vout=BSWAP3(vin)
vout=BSWAP(vin)
MEMSWAP& adr,cnt
MEMSWAP% adr,cnt
These functions and commands byte swap integer values. These are useful for
converting Intel format integers to Motorola format integers and vise versa.
vout: ivar
vin, adr, cnt: iexp
BSWAP&() - swap both bytes of a word
if a long is passed the upper word is dropped
BSWAP3() - swap only the lower 3 bytes of a long (upper byte is dropped)
useful for converting 24-bit BGR to RGB
BSWAP() - swap all 4 bytes of a long
MEMSWAP& - swap both bytes of all words in a memory block
cnt is rounded down to an even number divisible by 2
MEMSWAP% - swap all 4 bytes of all longs in a memory block
cnt is rounded down to an even number divisible by 4
Notes about command variants:
src must be even addresses
cnt is expressed in bytes
if cnt <= 0 the command is ignored
if cnt is odd remaining bytes without a matching pair won't be converted
Examples:
test%=&H1122
x%=BSWAP&(test%)
PRINT HEX$(x%,4) -> 2211
test%=&H11223344
x%=BSWAP(test%)
PRINT HEX$(x%,8) -> 44332211
'
test%=&H00112233
x%=BSWAP3(test%)
PRINT HEX$(x%,8) -> 00332211
t$="abcdefghijklmnop1"
o$=SPACE$(LEN(t$))
MEMSWAP& V:t$,V:o$,LEN(t$)
PRINT t$
PRINT o$ -> badcfehgjilknmpo
t$="abcdefghijklmnop123"
o$=SPACE$(LEN(t$))
MEMSWAP% V:t$,V:o$,LEN(t$)
PRINT t$
PRINT o$ -> dcbahgfelkjiponm
JOYPAD
JOYPAD mode (v3.7)
state=JOYPAD(port)
port, mode: iexp
state: ivar
This function reads Atari Jaguar controllers on the enhanced joystick ports.
Both ports are supported.
JOYPAD as a command - set the desired mode
mode: FALSE - JOYPAD() assumes processor is in user mode when called
Compatible with GEM. (default)
TRUE - JOYPAD() assumes processor is in supervisor mode when called
Used in games and demos for maximum speed.
JOYPAD() as function - reads a joypad
port: 0 = A
1 = B
If the port > 1 it will issue error code #71. If the hardware is not found
error code #98 is issued.
The return value represents a 32-bit long, each bit corresponds to a controller
state. Bits 10, 16, 22, and 24-31 are not used (always 0)
Note: It can return multiple bits, for example when the joypad is pressed at a
45 degree angle. The lower 4 bits are compatible with the STICK() command.
There's also a 'Pro Controller' which has three additional fire buttons, X, Y,
and Z, as well as a pair of 'sidestep' buttons, L and R, which are on the top
of the unit. To account for these extra buttons, they are mapped to the keypad
buttons. See table below.
Note: This command also supports modified Jaguar controllers with an added
digital paddle. In this case the lower 4 bits act as the rotary direction
indicator, see section 7.2 of the ejp_faq for more information.
This function assumes it's called from user mode.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
O 369#C 2580B 147*APRLDU
Bit State Pro
--- ------ ----------
0 Up
1 Down
2 Left
3 Right
4 Pause
5 A fire
6 *
7 7 Z
8 4 L sidestep
9 1
10
11 B fire
12 0
13 8 Y
14 5
15 2
16
17 C fire
18 #
19 9 X
20 6 R sidestep
21 3
22
23 Option
Examples:
joy%=JOYPAD(0) !read port a
IF BTST(joy%,23)
PRINT "option button detected"
ENDIF
joy%=JOYPAD(0) !read port a
stick&=AND(joy%,&X1111) !mask off the lower 4 bits
SELECT stick& !now we can use the familiar STICK() values
CASE 1
PRINT "up"
CASE 2
PRINT "down"
ENDSELECT
' supervisor mode example:
JOYPAD TRUE !somewhere in your init phase, set joypad for supervisor mode
stack%=SUPER(0) !then you program goes supervisor mode
joy0%=JOYPAD(0) !read joypad 0 in supervisor mode
Credits: Based on "The Atari Enhanced Joystick Ports" FAQ by Xav
http://www.gamesx.com/controldata/ejp_faq.htm
UNPACK
stat=UNPACK(sadr,dadr) (v3.7)
sadr, dadr: iexp
stat: ivar
This command is for unpacking compressed data files.
sadr - source address of packed data
dadr - destination address for unpacked data
If dadr = -1, inquire uncompressed size (does not unpack)
Returns 0 if file ID is unknown
If dadr <> -1, uncompress the file
Returns 0 if file ID is unknown
Returns file ID if ok
Data ID
Pack-Ice v2.1 Ice!
Pack-Ice v2.4 ICE!
Automation v5.01 AU5! (same as ICE!)
Speed Packer v3 SPv3
LZ77 v1.4 LZ77
Degas low .PC1
Degas medium .PC2
Degas high .PC3
size%=UNPACK(sadr%,-1) !inquire uncompressed size
size% = 0 -> unknown file ID
size% <> 0 -> uncompressed size
id%=UNPACK(sadr%,dadr%) !unpack the file
id% = 0 -> unknown file ID
id% <> 0 -> file ID, file uncompressed ok
The unpacking routines are optimized for speed. There isn't any error
checking other than a sanity check on the data ID.
Example:
OPEN "i",#1,"test.dat" !packed file
len%=LOF(#1)
sadr%=MALLOC(len%)
BGET #1,sadr%,len%
CLOSE #1
'
size%=UNPACK(sadr%,-1) !inquire
IF size%
dadr%=MALLOC(size%)
id%=UNPACK(sadr%,dadr%)
PRINT "ID: ";MKL$(id%)
ELSE
PRINT "unknown file ID or not packed!"
ENDIF
Note: Degas unpacking results in an uncompressed version of the file in the
destination buffer. See standard Degas file format for more information.
Credits: Hans Wessels for the Pack-Ice v2.1 optimized assembler.
https://sourceforge.net/projects/atari-icedpck/
Ray Dratwa for the LZ77 assembler.
http://s390174849.online.de/ray.tscc.de/code.htm#lz77
GT Turbo/rockyone for the Degas assembler.
Pack-Ice v2.4 assembler from unknown author.
Dis-assembled from 1020 byte INL.
Speed Packer v3 assembler by FIREHAWKS (©1992).
CRC8
crc=CRC8(addr,len) (v3.7)
crc=CRC16(addr,len)
crc=CRC32(addr,len)
crc=CHECKSUM(addr,len)
crc: ivar (at least a 32-bit long)
addr,len: iexp
These functions calculate CRC checksums.
CRC8() - len has maximum value of 255
returns an unsigned byte in the range of 0 to 255
CRC16() - len has maximum value of 65535
returns an unsigned word in the range of 0 to 65535
CRC32() - len can be a long
returns an unsigned long
CHECKSUM() - len can be a long
returns an unsigned word in the range of 0 to 65535
based on xmodem crc, smaller foot print and faster than CRCxx()
Note: If len = 0 these functions return 0.
These CRC functions generate the required data tables on the fly. This
means they are coded for space savings and not necessarily speed.
Recommend limits:
<64 bytes: 8-bit CRC
<16K bytes: 16-bit CRC
<512M bytes: 32-bit CRC
You run the risk of identical hash values for different data sets if
these limits are exceeded.
The algorithm used returns the same results as this online CRC calculator:
https://www.lammertbies.nl/comm/info/crc-calculation.html
CRC16 and CRC32 assembler source based on public domain code by Hans Wessels
GSTICK
GSTICK flag (v3.7)
stat=GSTICK()
stat=GSTRIG()
flag: iexp
stat: ivar
flag -> 0 (off)
1 (on)
GEM/MiNT friendly joystick handler. Also FireBee compatible. Only stick 1 is
supported. Return values are identical to STICK() and STRIG(). Unlike STICK()
and STRIG() the mouse is usable and active on port 0 at the same time.
Note: It's critical one calls GSTICK 0 before the program exits.
Mouse button #2 and GSTRIG() are the same.
GSTICK 1 !on
DO
s&=GSTICK()
b&=GSTRIG()
PRINT s&,b&
LOOP UNTIL ASC(INKEY$)=27 !esc to exit
GSTICK 0 !off
EDIT
Note: Command GSTIK flag assumes it's called from user mode.
LOG_MSG
LOG_MSG msg$ (v3.7)
LOG_SET flag
LOG_FILE path$
LOG_KILL
msg$, path$: sexp
flag: iexp
These commands are for generating debug logs. Sometimes it's ok to leave such
logging commands inside the application at all times, so long as it don't appear
to degrade the performance. With this built-in logging, it can be disabled and
the logging commands left in the application with minimal impact. In most cases
it would be completely transparent to the end user, except the binary is larger
than it would normally be.
LOG_MSG - if logging enabled, opens log file, appends message, closes log file
if logging is disabled, the command is ignored
if length of msg$ > 1024 characters error #60 will occur
LOG_SET - enable (TRUE) logging
disable (FALSE) logging (default)
LOG_FILE - set log file path
if length of path$ = 0 output is directed to the console (default)
if length of path$ > 256 characters error 60 will occur
LOG_KILL - silently delete log file if found
See also SYSTAB? to check the status of logging.
Note: The log is never kept open. There must be at least one free gemdos handle
or an error will occur. Use a full path if your app changes the default
path, otherwise the log file won't be found.
Example:
LOG_FILE "u:\ram\my.log" !set early on in your app, near the start
LOG_KILL !to start a fresh log at every run
' ... many lines of code ...
' by default logging is off
LOG_SET TRUE !turn on logging
' ... more code ...
LOG_MSG "message #1" !no need to pass cr/lf, added automatically
LOG_MSG "" !logs a blank line, cr/lf only
' ... more code ...
LOG_SET FALSE !turn logging off
LOG_MSG "message #2" !this line is ignored and not logged
LOG_SET TRUE !enable logging once again
' ...more code...
LOG_MSG "message #3" !this line is logged
EDIT
NULL
x=NULL (v3.7)
x: avar
The logical constant NULL returns the value 0.
This can be used to highlight variables or parameters that represent addresses
or pointers.
Example:
addr%=NULL
SUBPTR
adr=SUBPTR(proc) (v3.7)
adr=S:proc
SCALL ptr
adr: ivar (variable capable of holding a 32-bit value)
ptr: ivar (float or long only)
Advanced commands for calling procedures by address.
Note: Procedure 'proc' cannot have any parameters.
SUBPTR() -> returns address of 'proc'
If 'proc' is not defined error #19 occurs.
If 'proc' has parameters error #45 occurs.
S: -> short form of SUBPTR()
Same rules apply.
SCALL -> call procedure at 'ptr'
If 'adr' = 0 (null) error #64 occurs.
Example:
PRINT S:test
adr%=SUBPTR(test)
SCALL adr%
EDIT
PROCEDURE test
PRINT "here"
RETURN
--> address appears and then 'here' appears in the console
Notes: No checks are made when compiled.
Address returned is what exactly?
Interpreted -> pointer to token code
Compiled -> pointer to assembler code
Never ever write anything to the address returned from SUBPTR().
Doing so would be fatal in either case and cause a crash!
External calls from other apps are not supported.
Doing so usually results in error code #90.
This has to do with registers a3-a6 being out of context.
FREEFILE
ch=FREEFILE() (v3.7)
ch: ivar
This function returns the first free I/O channel that is not in use. This is
handy for avoiding channel conflicts.
Note: This function itself does not reserve a channel. For example calling it
twice in a row will return the same value:
PRINT FREEFILE()
PRINT FREEFILE()
-> Displays 0 twice.
Example:
rch&=FREEFILE() !returns #0
OPEN "i",#rch&,"o:\input.dat" !now #0 is considered in use
wch&=FREEFILE() !returns #1, since #0 is now in use
OPEN "o",#wch&,"o:\output.dat" !now #1 is considered in use
ERL
line=ERL (v3.7)
line: ivar (at least word size)
This function returns the line number where the last error occurred. Always
available in the interpreter.
Note: Only valid in compiled programs with certain compiler options.
Must be enabled. See $T+ option.
LTRIM$
out$=LTRIM$(in$) (v3.7)
out$=RTRIM$(in$)
in$: sexp
out$: string variable
Work similar to TRIM$() but trims only the left or right.
Example: PRINT ">";LTRIM$(" GFA ");"<" !displays: >GFA <
PRINT ">";RTRIM$(" GFA ");"<" !displays: > GFA<
ZTRIM$
out$=ZTRIM$(in$) (v3.7)
in$: sexp
out$: svar
This function returns all characters up to the first null encountered.
The null itself is not returned in 'out$'.
If no null is found the string is returned as is.
Examples: PRINT ">";ZTRIM$("GFA"+CHR$(0));"<" !displays: >GFA<
PRINT ">";ZTRIM$("GFA");"<" !displays: >GFA<
' can replace these 3 lines...
IF INSTR(test$,CHR$(0))
test$=CHAR{V:test$}
ENDIF
' with this 1 line
test$=ZTRIM$(test$)
LOWER$
out$=LOWER$(in$) (v3.7)
out$=LCASE$(in$)
out$=UCASE$(in$)
in$: sexp
out$: svar
These functions are used to alter the case of characters in strings.
LOWER$() - Opposite of UPPER$() (supports umlaut character)
LCASE$() - Similar to LOWER$() except umlaut characters are ignored.
UCASE$() - Similar to UPPER$() except umlaut characters are ignored.
Only characters A to Z are considered with LCASE$() and UCASE$(). Should be
slightly faster. More suitable for file names.
MROUND
result=MROUND(num,multiple) (v3.7)
result: ivar
num, multiple: iexp
This function will round 'num' up to the nearest 'multiple'. Only the lower
word of 'multiple' is used, thus 0 to 32767. Negative numbers can be used.
Example: (you want to align a screen buffer on a 256 byte boundary)
adr%=MALLOC(32000+256)
ptr%=MROUND(adr%,256)
' other examples:
PRINT MROUND(1,256) -> 256
PRINT MROUND(8,0) -> 8
PRINT MROUND(3,4) -> 4
PRINT MROUND(10,4) -> 12
PRINT MROUND(16,4) -> 16
MIRROR
result=MIRROR(num) (v3.7)
result=MIRROR|(num)
result=MIRROR&(num)
result=MIRROR3(num)
result: ivar
num: iexp
These functions perform a bitwise mirror.
MIRROR|() - mirror bits 0 to 7 (other bits are ignored)
MIRROR&() - mirror bits 0 to 15 (other bits are ignored)
MIRROR3() - mirror bits 0 to 24 (other bits are ignored)
MIRROR() - mirror bits 0 to 31
Example:
r%=218538125
PRINT BIN$(r%,8);" -> ";BIN$(MIRROR|(r%),8)
PRINT BIN$(r%,16);" -> ";BIN$(MIRROR&(r%),16)
PRINT BIN$(r%,24);" -> ";BIN$(MIRROR3(r%),24)
PRINT BIN$(r%,32);" -> ";BIN$(MIRROR(r%),32)
' output:
' 10001101 -> 10110001
' 1010000010001101 -> 1011000100000101
' 000001101010000010001101 -> 101100010000010101100000
' 00001101000001101010000010001101 -> 10110001000001010110000010110000
PCR
old=PCR(new) (v3.7)
old: ivar
new: iexp
This function can be used to read/write the MegaST's 'Processor Control
Register'. The CPU speed and cache settings can be changed.
The MEGA STE allows...
8 Mhz - No Cache
16 Mhz - No Cache
16 Mhz - Cache
DO NOT Set '8Mhz - Cache' EVER! Dire consequences will result.
Always preserve the other bits not being used.
Bit 0 - Cache Enable
Bit 1 - 16 Mhz Enable
Bit 1 Bit 0 Value Description
0 0 0 8 Mhz - no cache
0 1 1 Do not use
1 0 2 16 Mhz - No Cache
1 1 3 16 Mhz - Cache
MIRROR$
result$=MIRROR$(in$) (v3.7)
result: svar
in$: sexp
This function will reverse a string.
Example:
PRINT MIRROR$("Test") -> tseT
BMIRROR
BMIRROR address,count (v3.7)
MEMMIRROR& address,count
MEMMIRROR% address,count
MEMMIRROR3 address,count
address, count: iexp
These command will reverse a block of memory.
BMIRROR - Reverse block byte-wise, similar to MIRROR$()
MEMMIRROR& - Reverse block word-wise
MEMMIRROR% - Reverse block long-wise
MEMMIRROR3 - Reverse block built from 24-bit values
For example, flipping 24-bit RGB scan lines
If count <= 0 the command is ignored.
The word and long variants should be used on even address.
Example:
INLINE adr%,6
CHAR{adr%}="Test"
PRINT CHAR{adr%} !-> Test
BMIRROR adr%,4
PRINT CHAR{adr%} !-> tseT
STRPOKE
STRPOKE adr,t$ (v3.7)
result$=STRPEEK$(adr,len)
t$: sexp
adr, len: iexp
result: svar
This command and function is similar to CHAR{}, however they do not rely on
null terminated strings.
STRPOKE - Writes 't$' to 'adr' as is. No null byte is added.
STRPEEK$() - Returns exactly 'len' bytes at 'adr'.
If 'len' = 0 a null ("") string will be returned.
If 'len' > 32767 then error code #10 is issued.
If 'len' < 0 then error code #10 is issued.
Example:
INLINE adr%,8
STRPOKE adr%,"GFABASIC" !copy string to buffer
PRINT STRPEEK$(adr%,3) !displays "GFA"
MAKE
byt=MAKE|(hinyb,lonyb) (3.7)
wrd=MAKE&(hibyt,lobyt)
lng=MAKE%(hiwrd,lowrd)
lng=MAKE(hibyt,lobyt)
byt: ivar
wrd: ivar (able to hold at least 16 bits)
lng: ivar (able to hold at least 32 bits)
hinyb, lonyb: iexp (should be 0 to 15)
hibyt, lobyt: iexp (should be bytes)
hiwrd, lowrd: iexp (should be words)
These functions are used to reconstruct bytes, words, or longs that have been
spit into their respective high and low parts. This is useful for words or
longs read from uneven addresses or files.
MAKE|() reconstructs a byte from two nybles.
MAKE&() reconstructs a word from two bytes. -32768 to 32767 (signed)
MAKE%() reconstructs a long from two words.
MAKE() reconstructs a card from two bytes. 0 to 65535 (unsigned)
result could be long, r&=MAKE(255,255) will cause an error
Examples:
r|=MAKE|(&HA,&HB)
PRINT HEX$(r|,2),r| -> AB
'
r&=MAKE&(&HAA,&HBB)
PRINT HEX$(r&,4) -> AABB
'
r%=MAKE%(&HAAAA,&HBBBB)
PRINT HEX$(r%,8) -> AAAABBBB
r%=MAKE(&HFF,&HFF)
PRINT r% -> 65536
SNDH
SNDH addr,freq,subtune (v3.7)
addr: iexp (at least 32-bits)
freq, subtune: iexp
This command is used to play SNDH music files.
Version v2.10 of the SNDH format is supported.
A single SNDH music file can contain several sub tunes.
If 'addr' = 0 the music is stopped and the other parameters are ignored.
Parameter 'freq' should be 50 in most cases.
Parameter 'subtune':
File with a single tune:
This parameter has no meaning. Setting it to 0 or 1 should suffice.
File with several tunes:
If there are 4 tunes total, sub tunes are numbered 1 to 4.
If subtune is '0' the default tune is played. Not all files support this.
Example:
' *.sng file store here
INLINE sng%,8000
'
SNDH sng%,50,0 !music start
'
DO
LOOP UNTIL ASC(INKEY$)=27 !escape pressed?
'
SNDH NULL,0,0 !music stop
EDIT
Starting music automatically shuts off the key click sound, key repeat, and
system bell. These settings are restored to their previous state when music
is stopped.
Error #64 will occur if the header of the file doesn't contain the 'SNDH' id.
Internally it keeps track of the music status. Trying to play another music
file while it's already playing will be ignored. Likewise, if you try to stop
music from playing and it's already stopped, the stop command is ignored.
SNDH files contain assembler code which is the actual sound player. Loading
music files on the fly could be seen as self-modifying code on CPUs => 020.
If you experience crashes try the CPUFLUSH command after loading the music
file.
Important: SNDH files must not be played from fast ram.
Example: BLOAD "tune.snd",buf%
CPUFLUSH !ignored if CPU < 020
SNDH buf%,50,0
Since SNDH files contain the actual player code it's possible some music files
won't work on certain machines.
Note: Music must be stopped before the program exits! A crash is likely if
the music is left playing when the program exits. Other forms of
interrupt driven audio must not be attempted while the music is playing.
This command relies on Timer C.
Use of this command under a multitasking operating system could result
in strange and unstable behavior.
Commands QSORT/SSORT might cause sound glitches while music is playing
in the background. Internally they call CPUFLUSH which temporarily
toggles interrupts on/off. A custom written sort routine is the only
solution if this happens.
Credits: SNDH code by YesCREW/gwEm
NYBLE
bout=NYBLE(bin) (v3.7)
bout=SWAP|(bin)
bout: ivar
bin: iexp
These functions work with nybles (half-bytes).
NYBLE() - This function returns the lower 4 bits of numeric expression bin.
SWAP|() - This function swaps nybles in a byte. If the value passed is larger
than a byte the upper bytes are dropped.
Example:
test&=&HAB
PRINT HEX$(test&,2) -> AB
'
PRINT HEX$(NYBLE(test&),2) -> 0B
'
test&=SWAP|(test&)
'
PRINT HEX$(test&,2) -> BA
BOUND
vout=BOUND(vin,low,high) (v3.7)
vout: ivar
vin, low, high: iexp
This function checks whether parameter vin lies within bounds of low and high
(inclusive). This means when vin < low or vin > high an error message is
reported. Otherwise vin is returned unchanged.
Internally it calls the built in error handler, interpreted and compiled.
Triggers error #71.
Designed for integers, any decimal places will be dropped.
Note: This function is designed for quick debugging during development and
should not be left in finished programs. It generates an extra library
call and could impact performance.
~BOUND(vin,high,low) is also valid.
See also BETWEEN() and CONSTRAIN().
CONSTRAIN
vout=CONSTRAIN(vin,low,high) (v3.7)
vout: ivar
vin, low, high: iexp
This function checks whether parameter vin lies within range of low and high
(inclusive). If vin is out of range, it's forced into range. Otherwise vin is
returned unchanged.
Designed for integers, any decimal places will be dropped.
If vin => low and vin <= high -> returns vin unchanged
If vin < low -> returns low
If vin > high -> returns high
This could be useful for dialog entries where the end user can enter values
out of range. With this function you can easily enforce sane defaults.
Example:
DO
a&=RANDOM(100)
a&=CONSTRAIN(a&,20,80) !force 20 to 80
PRINT a&
LOOP UNTIL ASC(INKEY$)=27
' replaces this code segment
DO
a&=RANDOM(100)
IF a&<20
a&=20
ELSE IF a&>80
a&=80
ENDIF
PRINT a&
LOOP UNTIL ASC(INKEY$)=27
See also BETWEEN() and BOUND().
BETWEEN
flag=BETWEEN(val,low,high) (v3.7)
flag: ivar
val, low, high: iexp
This function determines whether val lies within range of low and high
(inclusive). Returns a boolean result.
Designed for integers, any decimal places will be dropped.
If val => low and val <= high -> returns TRUE
If val < low -> returns FALSE
If val > high -> returns FALSE
See also BOUND() and CONSTRAIN().
BCOMPARE
result=BCOMPARE(adr1,adr2,size) (v3.7)
result=BCOMPARE&(adr1,adr2,size)
result=BCOMPARE%(adr1,adr2,size)
result: ivar (able to hold 32-bits)
adr1, adr2: iexp
These functions compare two memory blocks to determine if they are identical.
The comparison can be done as bytes, words, or longs. If the two memory blocks
are identical they return TRUE (-1). Otherwise they return the address of the
first byte, word, or long in block one that doesn't match.
BCOMPARE() - Compare as bytes
adr1 - address of the first memory block
adr2 - address of the second memory block
size - size of memory block expressed in bytes
BCOMPARE&() - Compare as words
same parameter scheme as BCOMPARE()
an odd size will be round down to a value divisible by 2
BCOMPARE%() - Compare as longs
same parameter scheme as BCOMPARE()
an odd size will be round down to a value divisible by 4
Note: If size = zero (0) result will be TRUE (-1)
The two memory blocks must not overlap.
It returns the moment the two blocks don't match.
Word and long variants must start on even addresses.
DIGITAL$
sout$=DIGITAL$(sin$) (v3.7)
sout$: svar
sin$: sexp
This function converts standard number characters within strings to their
digital counterparts.
ASCII values 48 to 57 -> 16 to 25
ASCII values outside this range are untouched.
Example:
TEXT 20,20,DIGITAL$("Test: 023456789") -> Test: 0123456789
Note: ASCII values 16 to 25 are not normally PRINTable, but can be displayed
with the TEXT command.
BFILL
BFILL addr,count,value (v3.7)
MEMFILL& addr,count,value
MEMFILL% addr,count,value
addr, count, value: iexp
These commands fill a memory block with byte, word, or long values.
BFILL - Fill memory block with a byte value.
MEMFILL& - Fill memory block with a word value.
MEMFILL% - Fill memory block with a long value. (fastest variant)
addr - Address of memory block
count - Size of memory block in bytes
value - Value to fill memory block
Notes about command variants:
addr should be even for word and long variants
if count <= 0 the command is ignored
if count is odd a partial word or long will appear at the end of the block
if value is larger than the command allows, upper bytes are ignored
Examples:
FOR i&=0 TO 8
t$="--------"
MEMFILL& V:t$,i&,CVI("AB")
PRINT i&;" ";t$
NEXT i&
Displays:
0 --------
1 A-------
2 AB------
3 ABA-----
4 ABAB----
5 ABABA---
6 ABABAB--
7 ABABABA-
8 ABABABAB
FOR i&=0 TO 8
t$="--------"
MEMFILL% V:t$,i&,CVL("ABCD")
PRINT i&;" ";t$
NEXT i&
Displays:
0 --------
1 A-------
2 AB------
3 ABC-----
4 ABCD----
5 ABCDA---
6 ABCDAB--
7 ABCDABC-
8 ABCDABCD
MEMAND
MEMAND src,dst,cnt (v3.7)
MEMOR src,dst,cnt
MEMXOR src,dst,cnt
src, dst, cnt: iexp
These commands perform logical operations on memory blocks.
MEMAND - Logical AND two memory blocks.
MEMOR - Logical OR two memory blocks.
MEMXOR - Logical XOR two memory blocks.
Notes about command variants:
src and dst addresses should not overlay
if cnt <= 0 the command is ignored
Example:
DIM a!(16),b!(16)
a!(9)=TRUE
b!(9)=TRUE
b!(10)=TRUE
b!(12)=TRUE
@test
MEMAND V:a!(0),V:b!(0),(DIM?(a!())+7)\8
@test
EDIT
'
PROCEDURE test
LOCAL i&
PRINT
FOR i&=0 TO 15
PRINT STR$(a!(i&),2);" ";
NEXT i&
PRINT
FOR i&=0 TO 15
PRINT STR$(b!(i&),2);" ";
NEXT i&
PRINT
RETURN
Displays:
0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 -1 -1 0 -1 0 0 0
0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0
MEMBTST|
flag!=MEMBTST|(adr,bit) (v3.7)
flag!=MEMBTST&(adr,bit)
flag!=MEMBTST%(adr,bit)
MEMBCHG| adr,bit
MEMBCHG& adr,bit
MEMBCHG% adr,bit
MEMBCLR| adr,bit
MEMBCLR& adr,bit
MEMBCLR% adr,bit
MEMBSET| adr,bit
MEMBSET& adr,bit
MEMBSET% adr,bit
adr: iexp (at least 32-bits)
bit: iexp
These commands and functions allow direct testing and manipulation of bits at
memory locations.
MEMBTST|() - byte size bit testing
MEMBTST&() - word size bit testing
MEMBTST%() - long size bit testing
MEMBCHG|, MEMBCLR|, MEMBSET| - byte size bit manipulation
MEMBCHG&, MEMBCLR&, MEMBSET& - word size bit manipulation
MEMBCHG%, MEMBCLR%, MEMBSET% - long size bit manipulation
Notes about command/function variants:
word and long variants require an even address
byte variants limits bit range: 0 to 7
word variants limits bit range: 0 to 15
long variants limits bit range: 0 to 31
If bit is out of range error #71 is issued. No error handling is done when
compiled for maximum speed.
These only work in user mode. Addresses outside the applications memory
space can cause bombs.
Similar to BTST(), BCHG, BCLR, and BSET.
ISASCII
flag=ISASCII(in$) (v3.7)
flag=ISBLANK(in$)
flag=ISCNTRL(in$)
flag=ISPRINT(in$)
flag=ISSPACE(in$)
flag: ivar
in$: sexp
These functions test strings for specific ASCII values.
They return TRUE (-1) or FALSE (0).
ISASCII() - Determines if a string contains only 7-bit ASCII.
ASCII 0 to 127 -> TRUE
ASCII 128 to 255 -> FALSE
NULL string -> TRUE
ISBLANK() - Determines if a string contains any spaces or tabs.
ASCII 9 (TAB) -> TRUE
ASCII 32 (SPC) -> TRUE
NULL string -> FALSE
ISCNTRL() - Determines if a string contains any control characters.
Control characters are non-PRINTable.
ASCII 0 to 31 -> TRUE
ASCII 127 (DEL) -> TRUE
NULL string -> FALSE
ISPRINT() - Determines if a string contains only PRINTable characters.
ASCII 32 to 126 -> TRUE
ASCII 128 to 255 -> TRUE
NULL string -> TRUE
ISSPACE() - Determines if a string contains characters that generate
white-space.
ASCII 32 (SPC) -> TRUE
ASCII 9 (TB) -> TRUE
ASCII 10 (LF) -> TRUE
ASCII 11 (VT ) -> TRUE
ASCII 12 (FF) -> TRUE
ASCII 13 (CR) -> TRUE
NULL string -> FALSE
RGB
RGB compin,bits,rout,gout,bout (v3.7)
compout=RGB(rin,gin,bin,bits)
compout, rout, gout, bout: ivar
compin, bits, rin, gin, bin: iexp
These commands and functions allow the creation and breakdown of RGB composite
values.
RGB - Breaks an RGB composite into it's individual Red, Green, and Blue
component values.
compin - RGB composite to be broken down
bits - Number of bits in composite (see table below)
rout - Returns red component
gout - Returns green component
bout - Returns blue component
RGB() - Creates an RGB composite from individual Red, Green, and Blue
component values.
rin - Red component
gin - Green component
bin - Blue component
bits - Number of bits for result (see table below)
compout - Returns the composite result
bits R/G/B Range Palette Description
-9 7/7/7 512 ST bit order (9 bit stored as 12-bit -> x210)
-12 15/15/15 4096 STe bit order (0321) -> Setcolor()
12 15/15/15 4096 TT030 bit order (3210) -> EsetColor()
15 31/31/31 32768 standard high-color (xRRRRRGGGGGBBBBB)
16 31/63/31 65536 Falcon030 high-color (RRRRRGGGGGGBBBBB)
-24 255/255/255 16.7m Falcon030 RG0B -> VgetRGB()
24 255/255/255 16.7m standard true-color (RGB)
32 255/255/255 16.7m standard true-color/alpha (same as 24-bit -> ARGB)
Notes: Other values for 'bits' will generate error code #71.
R/G/B range is not checked, any extra bits are masked off.
comp%=RGB(16,31,63,31) !requires a long since the result is a CARD.
Examples:
ST:
col&=RGB(1,3,7,-9) !combine
RGB col&,-9,r&,g&,b& !split
PRINT r&,g&,b& !displays: 1 3 7
STe:
blue&=RGB(0,0,15,-12)
Falcon030:
red%=RGB(31,0,0,16)
green%=RGB(0,63,0,16)
24-bit video card:
green%=RGB(0,255,0,24)
white%=RGB(255,255,255,24)
Setcolor()+, EsetColor()+, VgetRGB()+
RGB256
out=RGB256(in,bits) (v3.7)
out=RGB1000(in,bits)
out=RGB64K(in,bits)
out: ivar
in, bits: iexp
These functions convert various RGB intensities to full 24-bit or to VDI
compatible values.
RGB256() - Converts RGB intensities to full 24-bit.
RGB1000() - Converts RGB intensities to standard VDI compatible values.
RGB64K() - Converts RGB intensities to NVDI 5 color table (ctab) values.
in - intensity to be converted
bits - number of bits used by 'in'
out - result of conversion
'bits' 'in' range RGB256 RGB1000 RGB64K Typical use
1 0 to 1 x x x mono 2 colors
2 0 to 3 x x x ST medium 4 colors
3 0 to 7 x x x 512 ST palette
4 0 to 15 x x x 4096 STe palete
5 0 to 31 x x x 32768 15-bit high-color
6 0 to 63 x x x 65536 16-bit high-color
7 0 to 127 x x x
8 0 to 255 n/a x x 16777216 24-bit true-color
-10 0 to 1000 x n/a x VDI standard
Notes: Other values for 'bits' will generate error code #71.
'in' range is not checked, any extra bits are masked off.
Shifting intensities to the right and dropping unwanted bits produces
similar results, but at a lesser quality. Shifting tends to produce
darker images. To avoid float-point math and multiplication
these functions use pre-calculated lookup tables for maximum quality
and speed.
Examples:
' assuming r& is the red component of a degas palette entry
r&=RGB256(r&,8) !convert red 0-7 to 0-255
' or convert it standard vdi
r&=RGB1000(r&,8) !convert red 0-7 to 0-1000
STRARRAYFILL
STRARRAYFILL array$(),str$ (v3.7)
array$(): string array
str$: sexp
This command can be used to quickly fill all elements of a string array.
Similar to ARRAYFILL.
Error #15 will be issued if the array has not been dimensioned.
Examples:
DIM a$(16)
STRARRAYFILL a$(),"GFA"
STRARRAYFILL a$(),"" !empty string
SPLIT
count=SPLIT(in$,delim,out$()) (v3.7)
count: ivar
in$: sexp
delim: iexp
out$(): string array (one dimension only)
This function breaks a string into substrings based on a delimiter and places
each substring into a one dimensional string array. See also command JOIN.
in$ String expression to be broken down into array elements
If LEN(in$)=0 -> count=0
delim ASCII value used to split expression into substrings
Only the lower byte is considered if a word or long is passed
delim=32 -> special case, empty substrings won't be returned
Extra whites space is removed
delim<>32 -> considered strict split, returns empty substrings
Extra white space is not removed
out$() Destination string array
Error #15 occurs if array not dimensioned
Error #28 occurs if array has more than one dimension
count Number of substrings returned after the split
count=0 -> No substrings found (LEN(in$)=0)
out$() is unchanged
count>0 -> Number of substrings returned
Only 'count' elements of out$() are changed
count<0 -> Result exceeds DIM of out$() (error condition)
Represents the index at which the error occurred
out$() is changed up until the error occurs
Note: in$ doesn't have to end with a delimiter.
"item 1|item 2" works just as well as "item 1|item 2|"
Examples:
DIM out$(6)
in$=""
count=SPLIT(in$,32,out$()) !returns 0
result -> out$() is unchanged
DIM out$(6)
in$="this is a test"
count=SPLIT(in$,32,out$()) !returns 4
result -> "this" "is" "a" "test"
DIM out$(2) !dim too small
in$="this is a test"
count=SPLIT(in$,32,out$()) !returns -4
result -> out$() is unchanged
DIM out$(6)
in$="this||is|a|test"
count=SPLIT(in$,124,out$()) !returns 5
result -> "this" "" "is" "a" "test"
DIM out$(6)
in$=" this is a test " !extra white space
count=SPLIT(in$,32,out$()) !returns 4
result -> "this" "is" "a" "test"
JOIN
flag=JOIN(in$(),delim,count,out$) (v3.7)
flag: ivar
in$(): string array (one dimension only)
delim, count: iexp
out$: svar
This command combines elements of a one dimensional string array with a
delimiter into a single string. See also function SPLIT().
in$() String array whos elements should be combined with a delimiter
Error #15 occurs if array not dimensioned
Error #28 occurs if array has more than one dimension
delim ASCII value used to separate the string array elements
Only the lower byte is considered if a word or long is passed
count Number of elements of in$() that should be combined
The value -1 (TRUE) forces all elements to be used
Equivalent to DIM?(in$()))
If count exceeds the dimensioned size of in$(), error #16 occurs
If count equals zero, out$ returns an empty string and flag = FALSE
out$ Returns the result
If the length of out$ exceeds 32767, the function returns TRUE
flag TRUE -> result is a string within normal limits (ok)
FALSE -> result exceeds string limit of 32767 characters (failed)
out$ will be left unchanged
Example:
m&=8
DIM a$(m&)
'
FOR i&=0 TO m&
a$(i&)=STR$(i&)
NEXT i&
'
~JOIN(a$(),ASC("-"),-1,t$) !force all (automatic)
'
PRINT
PRINT t$,LEN(t$) !displays -> 0-1-2-3-4-5-6-7-8 17
GETSTR
flag=GETSTR(in$,item,delim,out$) (v3.7)
flag: ivar
in$: sexp
out$: svar
item, delim: iexp
This function returns a single item from a list separated by a delimiter.
See also SETSTR().
in$ List of items separated with a delimiter
item requested item number (0 to ?)
delim ASCII value used to separate the items in the string
Only the lower byte is considered if a word or long is passed
out$ Returns the result if the item requested is found in the list
flag TRUE -> item was found in the list (ok)
FALSE -> item was not found in the list
out$ will be left unchanged
Note: in$ doesn't have to end with a delimiter.
"item 1|item 2" works just as well as "item 1|item 2|"
Example:
i$="item 0, item 1,item 2 , item 3 "
PRINT i$
'
PRINT
FOR i&=0 TO 4
r!=GETSTR(i$,i&,ASC(","),o$)
PRINT i&,r!,">";o$;"<",LEN(o$)
NEXT i&
Displays:
0 -1 >item 0< 6
1 -1 > item 1< 7
2 -1 >item 2 < 7
3 -1 > item 3 < 8
4 0 > item 3 < 8
REPLACE$
out$=REPLACE$(in$,old$,new$) (v3.7)
out$: svar
in$, old$, new$: sexp
This function does a left to right search and replace within a string.
in$ - string expression as input, left unchanged
if LEN(in$)=0 then an empty string is returned
old$ - string expression to search for
if LEN(old$)=0 then in$ is returned unchanged
if LEN(new$)>LEN(in$) then in$ is returned unchanged
new$ - string expression to replace old$
if LEN(new$)=0 then old$ is effectively removed from in$
out$ - string result
if LEN(out$) exceeds 32767 characters error #10 will occur
WAITVBL
WAITVBL (v3.7)
Alternative to VSYNC. In some cases (such as MiNT) VSYNC doesn't work.
Try using this command instead.
Equivalent to the code below, but more efficient.
PROCEDURE waitvbl
vbl_%=LPEEK(&H466) !global for max speed (local is slower)
WHILE LPEEK(&H466)=vbl_%
WEND
RETURN
Note: This command assumes you are not in supervisor mode.
HINYBLE
out=HINYBLE(in) (v3.7)
out=HIBYTE(in)
out=HIWORD(in)
out=HICARD(in)
in: ivar
out: iexp
These commands return the upper nyble, byte, word, or card of an expression.
They complement functions NYBLE(), BYTE(), WORD(), and CARD().
Upper Lower Notes
HINYBLE() NYBLE()
HIBYTE() BYTE()
HIWORD() WORD() sign extended
HICARD() CARD()
Examples:
byt|=&H21
PRINT HEX$(HINYBLE(byt|),8) !-> 00000002
'
wrd&=&H4321
PRINT HEX$(HIBYTE(wrd&),8) !-> 00000043
'
lng%=&H87654321
PRINT HEX$(HIWORD(lng%),8) !-> FFFF8765
'
lng%=&H87654321
PRINT HEX$(HICARD(lng%),8) !-> 00008765
' pass a long via AES message buffer
msg&(3)=HIWORD(adr%)
msg&(4)=WORD(adr%)
' or pass an address to the AES
~WIND_SET(blah,blah,HICARD(adr%),CARD(adr%),0,)
ARRAYSIZE
size=ARRAYSIZE(a()) (v3.7)
size: ivar
a(): any array type
This function calculates the total byte size of an array.
Includes:
Descriptors
Bytes used to keep structures aligned
Other parts used to manage arrays
Example:
PRINT ARRAYSIZE(test()) !not dimensioned -> 6 (only the descriptor exists)
DIM test$(1)
test$(1)="3.7"
test$(1)="GfA-Basic"
PRINT ARRAYSIZE(test$()) !-> 32
EDIT
' This can be used to help calculate compiler option $M:
CLR total_%
ADD total_%,ARRAYSIZE(px&())
ADD total_%,ARRAYSIZE(py&())
ADD total_%,ARRAYSIZE(player_names$())
ADD total_%,ARRAYSIZE(scores%())
ADD total_%,ARRAYSIZE(sprites$())
PRINT total_%
EDIT
INDEXCOUNT
number=INDEXCOUNT(a()) (v3.7)
number: ivar
a(): any array type
This function returns the number of field dimensions of an array.
Example:
DIM test$(4,6,8,10)
PRINT INDEXCOUNT(t$()) !displays -> 4
SBYTE
SBYTE{adr}=value (v3.7)
x=SBYTE{adr}
x=SBYTE(b)
adr, value, b: iexp
x: ivar
These are used to read and write signed bytes.
SBYTE{} - Works directly with memory addresses.
SBYTE() - Cast from a variable.
Note: SBYTE{} does not use supervisor mode. Internal representation:
$80 to $FF -> negative -128 to -1
$00 to $7F -> positive 0 to 127
Examples:
CLR b|
SBYTE{V:b|}=-2
PRINT SBYTE{V:b|} !displays -> -2
'
SBYTE{V:b|}=-2
PRINT SBYTE(b|) !displays -> -2
EDIT
SETSTR
flag=SETSTR(out$,item,delim,new$) (v3.7)
flag: ivar
out$: svar
new$: sexp
item, delim: iexp
This function overwrites a single item in a list separated by a delimiter.
See also GETSTR().
out$ List of items separated with a delimiter, might be changed by the
function
item Item number to be changed (0 to ?)
delim ASCII value used to separate the items in the string
Only the lower byte is considered if a word or long is passed
new$ String to overwite item with
If new$ is longer than the item, it will be cropped to fit
flag TRUE -> item was found in the list and changed (ok),
even if truncated
FALSE -> item is out of range, or out$ null, or new$ is null,
or substring within item$ is null
out$ will be left unchanged
Note: out$ doesn't have to end with a delimiter.
"item 1|item 2" works just as well as "item 1|item 2|"
Example:
in$="GFA|BASIC"
PRINT in$,LEN(in$)
ret!=SETSTR(in$,1,ASC("|"),"Basic is great!") !cropped
PRINT in$,LEN(in$),ret!
Displays:
GFA|BASIC 9
GFA|Basic 9 -1
NEAREST_RGB
index=NEAREST_RGB(red,green,blue,addr,count) (v3.7)
index: ivar
red, green, blue, addr, count: iexp
This funtion will find the nearest color in a supplied color palette based on
RGB values. Useful for color remapping. It works with various color spaces:
red - Red component
green - Green component
blue - Blue component
addr - Address of the palette
Layout must be in words, same layout used by VPALGET
R0,G0,B0, R1,G1,B1, R2,G2,B2, ...
count - Number of colors in the supplied palette (not the buffer size)
index - Returns the index of closest match from the supplied palatte
Color space Typical application
0 to 7 ST
0 to 15 STe
0 to 31 High color
0 to 256 True color
0 to 1000 VDI
Examples:
'assuming ST low resolution, _C retursn 16
DIM pal&(3*_C) !buffer
VPALGET V:pal&(0) !get vdi palette
PRINT NEAREST_RGB(1000,1000,1000,V:pal&(0),_C) !white
PRINT NEAREST_RGB(0,0,0,V:pal&(0),_C) !black
Note: The supplied palette must match the intensity of the components.
If a VDI palette is supplied, the components must be in the range of
0 to 1000
If rendering images in TC this commands isn't all that useful since
such modes have the full palette available.
GRAYSCALE
intensity=GRAYSCALE(red,green,blue,method) (v3.7)
intensity: ivar
red, green, blue, method: iexp
This function converts RGB values to grayscale. Works with all color spaces.
A couple different methods are available that affect image quality.
red - Red component
green - Green component
blue - Blue component
method - Conversion method (0 to 3, other values issue error #71)
0 = Fastest method, lowest quality (integer)
1 = Slightly slower weighted formula (integer)
2 = Older NTSC formula, better quality, slower (float)
3 = Newer sRGB formula for modern displays (float)
intensity - Returns the result
AVERAGE_RGB
AVERAGE_RGB r1,g1,b1,r2,g2,b2,rout,gout,bout (v3.7)
r1, g1, b1, r2, g2, b2: iexp
rout, gout, bout: ivar
This command will calculate the average between two colors.
Useful for anti-aliasing or dithering.
Works with any color space.
Example:
AVERAGE_RGB 1000,0,0,0,0,1000,ar&,ag&,ab& !red in/blue in
PRINT ar&,ag&,ab& !-> 500 0 500 = purple
_0
_0=v ... _9=v (v3.7)
x=_0 ... x=_9
v: iexp
x: ivar
The commands _0 to _9 are ten special variables. They are longwords like %,
not floating point numbers.
These variables are only erased by the NEW command, but not by CLEAR or RUN.
Example:
_0=22
test%=22
PRINT _0,test% !-> 22 22
CLEAR
PRINT _0,test% !-> 22 0
_VERSION
x=_VERSION (v3.7)
x=_CPUID
x=_BUILDINFO
x=_BOOTDEV
x=ACC?
x=AUTO?
x=M68K?
x=COMPILED?
x: ivar
Built in variables.
_VERSION - Returns GBE/GFA version. &H0370 -> v3.70
_BUILDINFO - Returns build date/time information (as a long).
Date/time of compilation in XBIOS(23) format.
_BOOTDEV - Returns the boot device (driver letter) in ASCII.
97 = "a", 98 = "b", 99 = "c", ...
_CPUID - Returns human readable CPU identification (as a long).
'M68K' = 680x0 family
'CV4E' = Coldfire
ACC? - Returns status of how the operating sees the running program.
TRUE = Running as a desk accessory
FALSE = Running as a program (interpreter always returns FALSE)
AUTO? - Returns AUTO folder status.
TRUE = Started from the AUTO folder
FALSE = Started from the Desktop or some other method
M68K? - Returns CPU type.
TRUE = 680x0 family
FALSE = Coldfire (CV4E)
COMPILED? - Returns status of the program execution.
TRUE = Compiled code
FALSE = Running interpreted
Example: PRINT HEX$(_VERSION) !-> 370
PRINT MKL$(_CPUID) !-> M68K
PRINT TIMESTAMP$(_BUILDINFO,"")
IF M68K?=FALSE
PRINT "Firebee"
ENDIF
IF COMPILED?=FALSE
RESERVE FRE(0)-65536
ENDIF
Gettime()+
BMPSIZE
size=BMPSIZE(width,height,planes) (v3.7)
size=_BMPSIZE
size: ivar
width, height, planes: iexp
These functions will calculate the size of a bitmap in bytes.
BMPSIZE():
width - If width = -1 the screen width is used
If width <= 0 it returns 0
height - If height = -1 the screen height is used
If height <= 0 it returns 0
planes - If planes = -1 the screen planes are used
If planes isn't valid it returns 0
Valid planes are: 1, 2, 4, 8, 15, 16, 24, and 32
15 is treated as 16
_BMPSIZE:
Always returns the size of the current screen mode
Note: Use BMPSIZE(width,height,1) to calculate a mask for transparent blits.
Example:
PRINT BMPSIZE(320,200,4) !-> 32000
PRINT BMPSIZE(-1,-1,-1) !-> size of current screen ram
PRINT _BMPSIZE !-> size of current screen ram
C2P
C2P type,src,dst,count (v3.7)
type, src, dst, count: iexp
This command will quickly transform video data from chunky to planar.
type count CPU Notes
0 = 1x1-8B-8P width*height 000
1 = 1x1-8B-8P width*height 060 Optimized for 060 superscalar
2 = 1x1-6B-8P width*height 000
3 = 1x1-4B-4P width*height 000
| |
| Destination (planar)
Source (chunky)
How to interpret type:
1x1 = means no pixel doubling
2x1 = every pixel is duplicated
1x2 = every scanline is doubled
2x2 = all the above
8P = 8 plane mode
8B = all 8 bits used
6B = 6 lower bits used
Notes: If type is out of range error #71 occurs.
The source (chunky) data is stored in bytes, where 1 byte = 1 pixel.
The destination (planar) is a standard Atari video mode.
0, 2, 3 -> Assembler code created by Mikael Kalms
1 -> Assembler code created by Mikael Kalms improved by MiKRO
BEXG
BEXG address1,address2,count (v3.7)
MEMEXG& address1,address2,count
MEMEXG% address1,address2,count
address1, address2, count: iexp
These commands will exchange two memory blocks.
BEXG - Exchange byte-wise
Suitable for odd addresses
MEMEXG& - Exchange word-wise
Addresses should be even
MEMEXG% - Exchange long-wise
Addresses should be even
Fastest variant
If count <= 0 the command is ignored.
Addresses should not overlap.
PIXEL24
PIXEL24 x,y,addr,bpl,rgbin (3.7)
PIXEL24 x,y,addr,bpl,rin,gin,bin
rgbout=PIXEL24(x,y,addr,bpl[,rout,gout,bout])
x, y, addr, bpl, rin, gin, bin: iexp
rgbin: iexp (32-bit)
rout, gout, bout: ivar
rgbout: ivar (32-bit)
These commands allow reading/writing 24-bit RGB pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in R(8), G(8), B(8) (Motorola) order:
rrrrrrrrggggggggbbbbbbbb (long)
PIXEL24 - set a 24-bit pixel via combined components (5 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rgbin - a long, where the upper byte isn't used: xRGB
example: a white pixel -> $00FFFFFF
PIXEL24 - set a 24-bit pixel via individual components (7 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rin - red component (0 to 255)
gin - green component (0 to 255)
bin - blue component (0 to 255)
PIXEL24() - get a 24-bit pixel via individual components
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rout - return red component
gout - return green component
bout - return blue component
rgbout - returns same format as rgbin, see above (combined components)
Notes: If 320 pixels wide, 'bpl' would be 320*3 = 960.
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL32
PIXEL32 x,y,addr,bpl,rgbin (3.7)
PIXEL32 x,y,addr,bpl,rin,gin,bin
rgbout=PIXEL32(x,y,addr,bpl[,rout,gout,bout])
x, y, addr, bpl, rin, gin, bin: iexp
rgbin: iexp (32-bit)
rout, gout, bout: ivar
rgbout: ivar (32-bit)
These commands allow reading/writing 32-bit RGB pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in A(8), R(8), G(8), B(8) (Motorola) order:
aaaaaaaarrrrrrrrggggggggbbbbbbbb (long)
PIXEL32 - set a 32-bit pixel via combined components (5 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rgbin - a long, where the upper byte isn't used: xRGB
example: a white pixel -> $00FFFFFF
PIXEL32 - set a 32-bit pixel via individual components (7 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rin - red component (0 to 255)
gin - green component (0 to 255)
bin - blue component (0 to 255)
PIXEL32() - get a 32-bit pixel via individual components
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rout - return red component
gout - return green component
bout - return blue component
rgbout - returns same format as rgbin, see above (combined components)
Notes: If 320 pixels wide, 'bpl' would be 320*4 = 1280).
Alpha channel is ignored. (upper byte)
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL16
PIXEL16 x,y,addr,bpl,rgbin (3.7)
PIXEL16 x,y,addr,bpl,rin,gin,bin
rgbout=PIXEL16(x,y,addr,bpl[,rout,gout,bout])
x, y, addr, bpl, rin, gin, bin: iexp
rgbin: iexp (minimum 16-bit)
rout, gout, bout: ivar
rgbout: ivar (minimum 16-bit)
These commands allow reading/writing 16-bit RGB pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in R(5), G(6), B(5) (Motorola) order:
rrrrrggggggbbbbb (card)
PIXEL16 - set a 16-bit pixel via combined components (5 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rgbin - a long, where the upper word isn't used
example: a white pixel -> $FFFF
PIXEL16 - set a 16-bit pixel via individual components (7 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rin - red component (0 to 31)
gin - green component (0 to 63)
bin - blue component (0 to 31)
PIXEL16() - get a 16-bit pixel via individual components
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rout - return red component
gout - return green component
bout - return blue component
rgbout - returns same format as rgbin, see above (combined components)
Notes: If 320 pixels wide, 'bpl' would be 320*2 = 640.
These commands assume Falcon030 16-bit high-color: R5/G6/B6
PIXELGET16() return value can trigger 'number not a word' error.
Use a long for the return variable.
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL15
PIXEL15 x,y,addr,bpl,rgbin (3.7)
PIXEL15 x,y,addr,bpl,rin,gin,bin
rgbout=PIXEL15(x,y,addr,bpl[,rout,gout,bout])
x, y, addr, bpl, rin, gin, bin: iexp
rgbin: iexp (minimum 16-bit)
rout, gout, bout: ivar
rgbout: ivar (minimum 16-bit)
These commands allow reading/writing 15-bit RGB pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in R(5), G(5), B(5) (Motorola) order:
xrrrrrgggggbbbbb (word)
PIXEL15 - set a 15-bit pixel via combined components (5 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rgbin - a long, where the upper word isn't used
example: a white pixel -> $FFFF
PIXEL15 - set a 15-bit pixel via individual components (7 parameters)
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rin - red component (0 to 31)
gin - green component (0 to 31)
bin - blue component (0 to 31)
PIXEL15() - get a 15-bit pixel via individual components
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
rout - return red component
gout - return green component
bout - return blue component
rgbout - returns same format as rgbin, see above (combined components)
Notes: If 320 pixels wide, 'bpl' would be 320*2 = 640.
Bit #15 is ignored.
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL8C
PIXEL8C x,y,addr,bpl,cin (3.7)
cout=PIXEL8C(x,y,addr,bpl)
x, y, addr, bpl, cin: iexp
cout: ivar
These commands allow reading/writing 8-bit color pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in chunky format as a single byte:
1 pixel = 1 byte (0 to 255)
PIXEL8C - set an 8-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cin - a byte
PIXEL8C() - get an 8-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cout - returns same format as cin, see above
Notes: If 320 pixels wide, 'bpl' would be 320*1 = 320).
Chunky format is typically used on VGA screens.
C2P can be used to transform image data to Atari 256 color format.
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL1M
PIXEL1M x,y,addr,bpl,cin (3.7)
cout=PIXEL1M(x,y,addr,bpl)
x, y, addr, bpl, cin: iexp
cout: ivar
These commands allow reading/writing mono pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in Atari mono 1-bit format byte:
1 bit = 1 pixel (0 = off, 1 = on)
PIXEL1M - set a mono pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cin - 0 or 1
PIXEL1M() - get a mono pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cout - returns same format as cin, see above
Notes: If 320 pixels wide, 'bpl' would be 320/8 = 40).
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL8P
PIXEL8P x,y,addr,bpl,cin (3.7)
cout=PIXEL8P(x,y,addr,bpl)
x, y, addr, bpl, cin: iexp
cout: ivar
These commands allow reading/writing 8-bit color pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in Atari planar format.
PIXEL8P - set an 8-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cin - 0 to 255, hardware (xbios) color order
PIXEL8P() - get an 8-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cout - returns same format as cin, see above
Notes: If 320 pixels wide, 'bpl' would be 320*1 = 320).
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL4P
PIXEL4P x,y,addr,bpl,cin (3.7)
cout=PIXEL4P(x,y,addr,bpl)
x, y, addr, bpl, cin: iexp
cout: ivar
These commands allow reading/writing 2-bit color pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in Atari planar format.
PIXEL4P - set an 4-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cin - 0 to 15, hardware (xbios) color order
PIXEL4P() - get an 4-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cout - returns same format as cin, see above
Notes: If 320 pixels wide, 'bpl' would be 320/2 = 160).
The VDI requires off screen buffers be evenly divisible by 16 pixels.
PIXEL2P
PIXEL2P x,y,addr,bpl,cin (3.7)
cout=PIXEL2P(x,y,addr,bpl)
x, y, addr, bpl, cin: iexp
cout: ivar
These commands allow reading/writing 2-bit color pixels.
Useful for NVDI off screen buffers.
There's no built in clipping, that's up to the caller.
Pixel data is read/written in Atari planar format.
PIXEL4P - set an 2-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cin - 0 to 3, hardware (xbios) color order
PIXEL4P() - get an 2-bit pixel via color register
x - x position
y - y position
addr - start address of image buffer
bpl - bytes per line
cout - returns same format as cin, see above
Notes: If 640 pixels wide, 'bpl' would be 640/4 = 160).
The VDI requires off screen buffers be evenly divisible by 16 pixels.
RC_EQUAL
flag=RC_EQUAL(x1,y1,w1,h1,x2,y2,w2,h2) (v3.7)
flag: ivar
x1, y1, w1, h1, x2, y2, w2, h2: iexp
This function determines if two rectangles are identical.
Also work with x1,y1,x2,y2, x3,y3,x4,y4 coordinates.
Results for 'flag':
TRUE (-1) -> Indentical
FALSE (0) -> Not a match
Equivalent to:
FUNCTION rc_equal(x1&,y1&,w1&,h1&,x2&,y2&,w2&,h2&)
$F%
IF x1&=x2& AND y1&=y2& AND w1&=w2& AND h1&=h2&
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
Examples:
PRINT RC_EQUAL(10,10,200,200,10,10,200,200) -> displays -1
PRINT RC_EQUAL(11,10,200,200,10,10,200,200) -> displays 0
STRUCT
STRUCT!(address,offset)=value (v3.7)
STRUCT|(address,offset)=value
STRUCT&(address,offset)=value
STRUCT%(address,offset)=value
STRUCT$(address,offset)=value$
STRUCT(address,offset)=value
var=STRUCT!(address,offset)
var=STRUCT|(address,offset)
var=STRUCT&(address,offset)
var=STRUCT%(address,offset)
var$=STRUCT$(address,offset)
var=STRUCT(address,offset)
address, offset, value: iexp
value$: sexp
var: ivar
var$: svar
These commands and functions are designed to help manage structures in a more
readable fashion.
Command Type Size in bytes Range
--------- ------- ------------- -------------------------
STRUCT!() boolean 1 0 (FALSE) or 255 (TRUE)
STRUCT|() byte 1 0 to 255
STRUCT&() word 2 -32768 to 32767
STRUCT%() long 4 -2147483648 to 2147483647
STRUCT$() string 0 to 32767 n/a
STRUCT() card 2 0 to 65535
Note: 'offset' is limited to word size.
STRUCT() requires a long else 'number not a word' error occurs.
Not supported: Float, Single, and Double.
If you need these in a structure use FLOAT{}, SINGLE{}, or DOUBLE{}.
Example:
' define the structure element offsets (constants that never change)
' standard Atari definitions for MFDB (a 20 byte structure)
' This part is very important, without meaningful labels the code becomes a
' nightmare to read months later and especially bad for anyone else!
REM #DC+
fd_addr&=0 !long
fd_w&=4 !word
fd_h&=6 !....
fd_wdwidth&=8
fd_stand&=10
fd_nplanes&=12
fd_r1&=14
fd_r2&=16
fd_r4&=18
REM #DC-
' ram for structures
INLINE smfdb%,20
INLINE dmfdb%,20
' fill the structures, with the labels it's very easy to understand the code
STRUCT%(smfdb%,fd_addr&)=XBOIS(2) !versus LONG{smfdb%+fd_addr&}=XBOIS(2) 'C' -> smfdb.fd_addr=xbios(2)
STRUCT&(smfdb%,fd_w&)=_SW !versus WORD{smfdb%+4}=_SW smfdb.fd_w=...
STRUCT&(smfdb%,fd_h&)=_SH
STRUCT&(smfdb%,fd_wdwidth&)=(_SW+15)\16
STRUCT&(smfdb%,fd_stand&)=0
STRUCT&(smfdb%,fd_nplanes&)=_B
STRUCT&(smfdb%,fd_r1&)=0
STRUCT&(smfdb%,fd_r2&)=0
STRUCT&(smfdb%,fd_r3&)=0
STRUCT%(dmfdb%,fd_addr&)=XBOIS(2)
STRUCT&(...
; just as easy to read back
PRINT STRUCT%(smfdb%,fd_addr&)
MDPOKE
MDPOKE addr,value (v3.7)
val=MDPEEK(addr)
MLPOKE addr,value
val=MLPEEK(addr)
addr, value: iexp
val: ivar
These commands and functions allow reading/writing misaligned (odd) addresses.
Avoid odd address error (3 bombs) if you know the address is not even.
MDPEEK()/MDPOKE - read/write a card
MLPEEK()/MLPOKE - read/write a long
Note: These don't use supervisor mode and should only be used within your own
programs address space.
MNAM
MNAM sout$ (v3.7)
sout$: svar
This command returns the machine name.
If MiNT is present it calls PSYSCTL().
If MiNT isn't present it looks for the 'MNAM' cookie.
Returns a null (empty) string if neither are available.
Example:
MNAM mach$
PRINT mach$ !-> ARAnyM
Psysctl()+
VER2STR
VER2STR version,sout$ (v3.7)
version: iexp
sout$: svar
This command converts a version number stored in hex notation to human readable
text. This is refered to as BCD format.
'version' must be stored as a word likes so: <major|><minor|>
&h0370 -> "3.7"
VER2STR _VERSION,ver$
PRINT ver$ !-> 3.72
USERDEF
addr=USERDEFBIT (v3.7)
addr=USERDEFBYT
addr=USERDEFWRD
addr=USERDEFLNG
USERDEF!(index)=value
USERDEF|(index)=value
USERDEF&(index)=value
USERDEF%(index)=value
val=USERDEF!(index)
val=USERDEF|(index)
val=USERDEF&(index)
val=USERDEF%(index)
addr: ivar (must be able to hold 32-bits)
val: ivar
index: iexp
These commands and funtions provide built-in arrays. Supports boolean, byte,
word, and long variable types.
Name Type Total 'index' range
USERDEF|() boolean 8192 0 to 8191 (packed 8 bits per byte)
USERDEF|() byte 1024 0 to 1023
USERDEF&() word 512 0 to 511
USERDEF%() long 256 0 to 256
In each case the array uses exactly 1kb (1024 bytes).
Parameters are range checked only when interpreted.
They start at index 0 regardless of OPTION BASE 1.
ERASE won't cause the array address to change.
They start out cleared (all zeros).
They are located in the text section of the binary.
USERDEFBIT - pointer to the base of the boolean array
USERDEFBYT - pointer to the base of the byte array
USERDEFWRD - pointer to the base of the word array
USERDEFLNG - pointer to the base of the long array
The address can be used with BZERO or BFILL to quickly fill an array.
Note: When using the array pointers, never write beyond 1024 bytes or
something behind the buffer will be clobbered. Could lead to
strange behavior or crashes.
Examples:
BZERO USERDEFBYT,1024 !clear byte array
MEMZERO& USERDEFWRD,1024 !clear word array
MEMZERO% USERDEFLNG,1024 !clear long array
Use case?
Perhaps a DIMensioned array is needed inside a funtion, which isn't allowed.
_A3
addr=_A3 (v3.7)
addr=_A4
addr=_A5
addr=_A6
addr=_A7
addr: ivar (capable of storing 32-bits)
These return GFA's reserved register (a3 to a6) contents. They are read only.
What they point to in the editor isn't necessarily the same in the library.
Their contents won't be discussed here.
These are used inhouse for debugging purposes. Never ever write anything to
these addresses, that's a recipe for disaster!
_A7 is the stack pointer (sp).
Note: a3 to a7 should not be used in distributed applications.
Example for _A7: (suspected stack overflow)
sp_limit%=_A7-(8*1024) !GBE has an 8kb stack, must be first line of app
' later in the code, to test if the stack space has been exhausted
IF _A7<sp_limit%
PRINT "WTF!"
ENDIF
ARRAY
ARRAY!(address,index)=value (v3.7)
ARRAY|(address,index)=value
ARRAY&(address,index)=value
ARRAY%(address,index)=value
ARRAY(address,index)=value
var=ARRAY!(address,index)
var=ARRAY|(address,index)
var=ARRAY&(address,index)
var=ARRAY%(address,index)
var=ARRAY(address,index)
address, index, value: iexp
var: ivar
These make it easier to use momory blocks as one dimensional arrays.
No error handling as the interpreter has no way of knowing the index range.
Starts at index 0 regardless of OPTION BASE.
Assuming 256 elements for all types: (index range would be 0 to 255)
Cmd/Fnc Type Dimension Notes
ARRAY!() Boolean MALLOC(MROUND(256,8)\8) TRUE (-1) or FALSE (0)
ARRAY|() Byte MALLOC(256) 0 to 255
ARRAY&() Word MALLOC(256*2) -32768 to 32767
ARRAY%() Long MALLOC(256*4) -2147483648 to 2147483647
ARRAY() Card MALLOC(256*2) 0 to 65535 (unsigned word)
Note: ARRAY!() are packed into 8 bits per byte. The size of the MALLOC()
must be rounded up to the nearest 8 bit boundary.
When using ARRAY(), a long should be used or 'Number not a word' error can
occur. Example: value%=ARRAY(base%,index%)
Example:
base%=MALLOC(128*4) !128 longs
IF base%=NULL
PRINT "malloc failed!"
EDIT
ENDIF
BZERO base%,128*4 !assume ram is dirty
' new way old way
ARRAY%(base%,index&)=value% !set -> LONG{base%+(index&*4)}=value%
'
value%=ARRAY%(base%,index&) !get -> value%=LONG{base%+(index&*4)}
NYBLE{}
NYBLE{address}=value (v3.7)
HINYBLE{address}=value
val=NYBLE{address}
val=HINYBLE{address}
address, value: iexp
val: ivar
These allow reading/writing a nyble directly from/to an address. They work
similar to the other pointer commands.
HINYBLE{} - Upper 4 bits
NYBLE{} - Lower 4 bits
Layout of a byte: &X11111111
UUUULLLL
Only the lower 4 bits of 'value' are considered, other bits are masked off.
Do not pre-shift 'value' when using HINYBLE{} as the command does that itself.
To write 3 in the upper nyble: HINYBLE{address%}=3
Warning: Protected addresses will cause a bus error.
KEYCLICK
KEYCLICK flag (v3.7)
KEYREPEAT flag
SYSBELL flag
flag: iexp
These allow changing certain TOS features.
KEYCLICK - Key click on or off
KEYREPEAT - Key repeat on or off (doesn't work in MiNT)
SYSBELL - System bell on or off (clicking outside a dialog)
Parameter: (only the lower byte is considered)
0 = Off (FALSE)
<>0 = On (TRUE)
See also CONTERM().
Example: old&=CONTERM(-1)
KEYCLICK FALSE
' do stuff...
~CONTERM(old&) !restore system settings
EDIT
MM: System Variables+
WDWIDTH
wdwidth=WDWIDTH(width) (v3.7)
bpl=BPL(width,planes)
wdwidth, bpl: ivar
width, planes: iexp
These calculate standard VDI structure elements.
WDWIDTH() - calculate fd_wdwidth for a given image (VRO_CPYFM())
If 'width' = -1 then current screen value is used
If 'width' <= 0 it returns 0
BPL() - calculate 'Bytes Per Line' for a given image (VR_TRANSFER_BITS())
If 'width' or 'planes' = -1 then current screen values are used
If 'width' <= 0 it returns 0
If 'planes' is out of range it returns 0
Example:
PRINT BPL(-1,-1) !if current screen is 640 pixels/256 colors, -> 640
PRINT BPL(320,16) !falcon high-color -> 640
VRO_CPYFM()+, VR_TRANSFER_BITS()+
TRNFM
stat=TRNFM(smfdb,dmfdb) (v3.7)
stat: ivar
smfdb,dmfdb: iexp (at least 32-bits)
Transforms a memory block from device-independent to device-dependent and
vice-versa. Works more or less like VDI function VR_TRNFM().
Bit planes 1, 2, 4, and 8 are supported.
Parameters are identical to VR_TRNFM(). A VDI workstation handle isn't
required and works independently of the current screen mode.
Note: device-dependent = standard Atari ST interleaved bitmap
Examples: ST low, ST med, etc
Return value: 0 -> Ok
-1 -> Error (MFDB contains bit plane value out of range)
vr_trnfm()+
API/Protocols
AV Protocol:
AV_INIT() AV_PROTOKOLL() AV_EXIT()
AV_SENDKEY()
AV_WHAT_IZIT()
AV_STARTPROG() AV_STARTED()
AV_ACCWINDOPEN() AV_ACCWINDCLOSED()
AV_PATH_UPDATE()
AV_OPENWIND() AV_XWIND()
AV_FILEINFO() AV_COPYFILE() AV_DELFILE()
VA_START()
DHST API:
DHST_INIT() DHST_ADD()
Font Protocol:
FONT_INIT() FONT_SELECT()
LDG API:
LDG_INIT() LDG_OPEN() LDG_FIND() LDG_CLOSE() LDG_LIBPATH() LDG_ERROR()
JPEGD API:
JPEGD_INIT() JPEGD_OPENDRIVER() JPEGD_CLOSEDRIVER()
JPEGD_GETSTRUCTSIZE() JPEGD_GETIMAGEINFO() JPEGD_GETIMAGESIZE()
JPEGD_DECODEIMAGE()
STiK API:
STIK_INIT()
STIK_KRFREE() STIK_KRGETFREE()
STIK_GET_ERR_TEXT() STIK_GETVSTR()
STIK_TCP_OPEN() STIK_TCP_CLOSE() STIK_TCP_SEND()
STIK_TCP_WAIT_STATE()
STIK_CNKICK()
STIK_CNBYTE_COUNT() STIK_CNGET_CHAR() STIK_CNGET_BLOCK()
STIK_RESOLVE()
STIK_CNGETINFO()
MiNT-Net Socket API:
See gemdos function FSOCKET() for a list of supported calls.
Plugin API:
PLUGIN_LOAD() PLUGIN_UNLOAD() PLUGIN_SET()
PLUGIN_OPEN() PLUGIN_RW() PLUGIN_CLOSE()
G.I.S.T. API:
GIST_INSTALL_INT() GIST_REMOVE_INT()
GIST_INIT_SNDS() GIST_STOP_SND()
GIST_SND_ON() GIST_SND_OFF()
GIST_GET_PRIOR()
Misc:
NETWORK?
AV_INIT
stat=AV_INIT() (v3.7)
stat=AV_PROTOKOLL(options&,name$)
stat=AV_SENDKEY(state,scancode)
stat=AV_OPENWIND(path$,mask$)
stat=AV_STARTPROG(name$,cmdline$,num)
stat=AV_ACCWINDOPEN(wh)
stat=AV_ACCWINDCLOSED(wh)
stat=AV_PATH_UPDATE(path$)
stat=AV_WHAT_IZIT(px,py)
stat=AV_EXIT()
stat=AV_STARTED(ptr)
stat=AV_XWIND(path$,mask$,flags)
stat=AV_FILEINFO(path$)
stat=AV_COPYFILE(src$,dst$,flags)
stat=AV_DELFILE(path$)
stat=VA_START(name$)
stat: ivar
name$, path$, mask$, cmdline$, src$, dst$: sexp
options, state, scancode, num, wh, px, py, ptr, flags: iexp
These functions aid in the use of the AV Protocol.
AV_INIT() initializes the AV Protocol and must be called at least once.
This function tries to allocate Global memory for an internal buffer.
Return: >0 appl_id of the AV Server (Ok)
0 Environment variable 'AVSERVER=' not found
-1 AV Server not found
-2 Malloc failure
-3 AV_INIT() was already called
AV_EXIT() also frees internal buffers allocated during AV_INIT().
AV_STARTPROG() can be used with an optional command line. Pass an empty string
("") to signal no command line.
AV_xxx() return codes:
>0 = Message sent Ok
0 = Message failed
-1 = Called without first calling AV_INIT()
Some AV Protocol functions send AES messages:
Call: Reply:
AV_PROTOKOLL VA_PROTOSTATUS
AV_SENDKEY -
AV_OPENWIND VA_OPENWIND
AV_STARTPROG VA_PROGSTART
AV_ACCWINDOPEN -
AV_ACCWINDCLOSED -
AV_PATH_UPDATE -
AV_WHAT_IZIT VA_THAT_IZIT
AV_EXIT -
AV_STARTED -
AV_XWIND VA_XOPN
AV_FILEINFO VA_FILECHANGED
AV_COPYFILE VA_FILECOPIED
AV_DELFILE VA_FILEDELETED
VA_START AV_STARTED
It's up to the coder to handle these response messages.
AV Protocol support is based on Thing Desktop which has a built-in AV Server.
For further information, see 'AV Protocol' used by Thing Desktop.
FONT_INIT
stat=FONT_INIT() (v3.7)
stat=FONT_SELECT(wh,id,points,color,effects)
stat: ivar
wh,id,points,color,effects: iexp
These functions aid in the use of the Font Protocol.
FONT_INIT() initializes the Font Protocol and must be called at least once.
Return: >0 = appl_id of the font server (Ok)
0 = Environment variable 'FONTSELECT=' not found
-1 = Font server application not found
-2 = FONT_INIT() was already called
This should be called once in the programs startup phase.
FONT_SELECT() calls the font selector, message returned: FONT_CHANGED
Return: >0 = Message sent Ok
0 = Failed to send message
-1 = FONT_INIT() was never called
It's up to the coder to handle to the AES message.
For further information, see 'Font Protocol' used by Thing Desktop.
LDG_INIT
stat=LDG_INIT() (v3.7)
stat=LDG_OPEN(name$)
stat=LDG_FIND(name$,desc)
stat=LDG_CLOSE(desc)
stat=LDG_LIBPATH(path$)
stat=LDG_ERROR()
stat: ivar
name$: sexp
desc: iexp
path$: svar
These functions allow the use of LDG libraries from GFABASIC. Libraries should
use LDG protocol v2.00 or better. A maximum of 100 libraries can be resident
at once.
LDG_INIT() must be called once before other LDG_xxx() functions are called.
Return: >0 = LDG version -> $0233 = v2.33 (Ok)
0 = LDG cookie not found (or no cookie jar found)
-1 = LDG version < v2.00
-2 = LDG_INIT() was already called
-3 = Unable to allocate descriptor memory pool
Note: If LDG_INIT() fails or not called at all, all other LDG_xxx() functions
will return error code -11 (LDG_NO_TSR).
LDG.PRG is not required, GFA manages libraries itself
Error code 0 is impossible, but left for compatibility reasons
Default library path is: c:\gemsys\ldg\
zView codecs are special and would be at c:\gemsys\ldg\codecs\
Environment LDGPATH=c:\gemsys\ldg\ can be used for custom paths
The other functions work as close as possible to the 'C' equivalents. The only
difference is the 'global' parameter is not needed as the library handles this
itself internally.
See LDG.HYP -> Client functions
For more information: http://ldg.sourceforge.net/
STIK_INIT
stat=STIK_INIT(tpl_out,cnf_out) (v3.7)
~STIK_KRFREE(block)
stat=STIK_KRGETFREE(flag)
stat=STIK_GET_ERR_TEXT(code)
stat=STIK_GETVSTR(var$)
stat=STIK_TCP_OPEN(rhost,rport,tos,obsize)
stat=STIK_TCP_CLOSE(cn,timeout)
stat=STIK_TCP_SEND(cn,buf,len)
stat=STIK_TCP_WAIT_STATE(cn,state,timeout)
stat=STIK_CNKICK(cn)
stat=STIK_CNBYTE_COUNT(cn)
stat=STIK_CNGET_CHAR(cn)
stat=STIK_CNGET_BLOCK(cn,buf,len)
stat=STIK_RESOLVE(dn$,rdn,alist,lsize)
stat=STIK_CNGETINFO(cn)
stat: ivar
tpl_out, cnf_out: ivar (float or long only)
block, flag, code, rhost, rport, tos, obsize, cn, timeout, buf, len: iexp
state, rdn, alist, lsize: iexp
var$, dn$: sexp
These functions allow internet/network programming using the STiK API.
Compatible with GlueSTiK, STinG, etc. Requires STiK v1.13 or better. The
version requirement insures compatibility with GlueSTiK.
STIK_INIT() must be called once before any other functions can be used.
Return: >0 STiK version $0113 -> v1.13 (Ok)
0 STiK cookie not found (or no cookie jar found)
-1 STiK version to old (requires v1.13 or better)
-2 Failed to get TPL function table
-3 STiK magic number not found (bad cookie)
-4 STiK disabled
-5 Malloc failure
-6 STIK_INIT() was already called
The parameters return pointers:
tpl pointer, transport layer function table (see STiK header files)
config pointer, internal config structure (see STiK docs)
If you need the module, author and version strings: (null terminated)
PRINT CHAR{LONG{tpl_out+0}} -> TRANSPORT_TCPIP
PRINT CHAR{LONG{tpl_out+4}} -> Frank Naumann (GlueSTiK™ v0.30)
PRINT CHAR{LONG{tpl_out+8}} -> 01.13
STIK_INIT() attempts to allocate Global ram under MiNT. This is required for
memory protection. The maximum length of a URL is 512 bytes.
STIK_TCP_CLOSE() is compatible with STinG's TCP_CLOSE(). Internally it always
sets STinG's added 3rd parameter to zero (0).
With the exception of STIK_INIT() all the rest of the functions work like
the 'C' equivalents. When working with MiNT and memory protection always
insure data buffers are allocated in Global memory.
See STIKPROG.HYP -> Contents for more information.
Note: Only a subset of the STiK API has been implemented. GFA currently
supports the most used STiK API functions. Please contact me if you
need any missing STiK API functions.
Implemented GlueSTiK notes
stik_cnkick() + (does nothing)
Not implemented GlueSTiK notes
stik_krmalloc() +
stik_krrealloc() +
stik_carrier_detect() ? (always returns '0')
stik_tcp_ack_wait() +
stik_udp_open() +
stik_udp_close() +
stik_udp_send() +
stik_cnget_ndb() +
stik_housekeep() ? (does nothing)
stik_ser_disable() ? (does nothing)
stik_ser_enable() ? (does nothing)
stik_set_flag() +
stik_clear_flag() +
stik_on_port() ? (do not use, returns E_NOROUTINE)
stik_off_port() ? (do not use, does nothing)
stik_setvstr() +
stik_query_port() ? (do not use, returns E_NOROUTINE)
stik_cngets() +
icmp_send() - (null entry in TPL table)
icmp_handler() - (null entry in TPL table)
icmp_discard() - (null entry in TPL table)
Key: + GlueSTiK supports this call
? GlueSTiK ignores this call
- GlueSTiK is missing this call
Note: GlueSTiK adds error codes -26 to -32.
DHST_INIT
stat=DHST_INIT() (v3.7)
stat=DHST_ADD(app_name$,app_path$,doc_name$,doc_path$)
app_name$, app_path$, doc_name$, doc_path$; sexp
These functions help with DHST (Document History Protocol).
DHST_INIT() - Must be called once before DHST_ADD() can be called.
Return values:
>=0 = APID of the DHST Server
-1 = DHST cookie not found or no cookie jar found
-2 = Internal malloc() failed, not enough free ram (global)
-3 = DHST_INIT() was already called
This should be called once in the applications startup phase.
DHST_ADD() - Send a document history message to the DHST Server.
Return values:
-1 = DHST_INIT() wasn't called first
0 = Failed to send message (appp_write() failed)
>0 = Message was sent Ok
If the message is sent successfully the application will receive a reply
message: DHST_ACK -> $DADE
For further information see the Document History Protocol documentation.
NETWORK?
flag=NETWORK? (v3.7)
flag: iexp
This function tries to detect if a network is installed. It cannot detect if
a network is active, but if one is installed, it's typically active.
Return value: TRUE -> Found
FALSE -> Not found
This is a generic function in that it does not detect any specific network
stack. It returns TRUE for:
MiNT-Net
MiNT-Net + GlueSTiK
MiNT-Net + Draconis gateway
STiK
STinG
Draconis
Draconis + IFusion (STiK gateway)
IConnect
IConnect + IFusion (STiK gateway)
If you are looking for a specific network stack search for these cookies:
Stack Cookie
STiK STiK
Draconis ICIP
IConnect SLIP
MiNT-Net is a special case. You can't rely on the MiNT cookie.
If MiNT-Net is installed entry u:\dev\inet appears.
JPEGD_INIT
version=JPEGD_INIT() (v3.7)
status=JPEGD_OPENDRIVER(struct)
status=JPEGD_CLOSEDRIVER(struct)
size=JPEGD_GETSTRUCTSIZE()
status=JPEGD_GETIMAGEINFO(struct)
status=JPEGD_GETIMAGESIZE(struct)
status=JPEGD_DECODEIMAGE(struct)
version, status, size: ivar
struct: iexp
These functions provide access to the Atari/Brainstorm JPEGD DSP Decoder.
This requires a Falcon030 and the installation of JPEGD.PRG in the auto
folder.
JPEGD_INIT() - Must be called before using the other functions.
Return: 1 = Ok, current version of the decoder
0 = '_JPD' cookie not found
-1 = Version is <> 1
-2 = JPGED_INIT() already called, called a 2nd time
-3 = Cookie data bad, not as expected
Note: If the other functions are used without JPEGD_INIT() first being
called, they will return error code #100. This isn't an offical error
code, it was added to avoid a system crash.
It's far beyond the scope of this document to explain the use of this API.
For further information see the JPEGD Developer Documentation and the JPEGD
source archive with 'C' and assembler example code.
Visit https://docs.dev-docs.org/ and search for: jpegd
PLUGIN_LOAD
desc=PLUGIN_LOAD(path$,fnctab) (v3.7)
stat=PLUGIN_UNLOAD(desc)
stat=PLUGIN_SET(fnctab)
stat=PLUGIN_OPEN(struct,path$)
stat=PLUGIN_RW(struct,buffer)
stat=PLUGIN_CLOSE(struct)
desc, struct, buffer, fnctab: ivar (must be at least 32-bits)
path$: sexp
stat: ivar
These are used to load/unload image read/write plugins.
Plugins can be found here: http://atari.gfabasic.net/htm/imgview.htm
PLUGIN_LOAD() - Load a plugin and return it's function table address
The last plugin loaded is the active plugin
Return: >0 = Plugin descriptor, used to identify it and free it (ok)
<0 = Gemdos error code, failed to load plugin
-1 = Plugin ID invalid, binary is not a plugin
functab will contain the address of the plugins function table
only if the call is ok
PLUGIN_UNLOAD() - Unload a plugin
Return: 0 = Ok
<0 = Gemdos error code, failed to free the plugin
PLUGIN_SET() - Set active plugin if more than one plugin is resident
If working with only one plugin this isn't needed.
Return: 0 = Ok
-1 = Plugin ID invalid or fnctab is NULL
Note: Internally plugin_init() are automatically handled.
Multiple plugins can be loaded and unloaded.
Plugins that require a large stack (> 8 kb) need to have the super bit set in the
program header.
See 'Plugin Developer's Kit' for more information.
GIST_INSTALL_INT
~GIST_INSTALL_INT() (v3.7)
~GIST_REMOVE_INT()
~GIST_INIT_SNDS()
ovoice=GIST_SND_ON(sndptr,voice,volume,pitch,priority)
~GIST_STOP_SND(voice)
~GIST_SND_OFF(voice)
opriority=GIST_GET_PRIOR(voice)
sndptr, voice, volume, pitch, priority: iexp
ovoice, opriority: ivar
These commands are identical to the G.I.S.T. commands.
The driver is built into GBE and GISTDRVR.PRG isn't needed.
Like the original there is no error handling and care must be taken when
using these functions.
The function names were taken from the G.I.S.T. documentation and prefixed
with 'GIST_' to make the code easier to read. They otherwise work just like
the originals except GISTDRVR.PRG isn't need anymore.
It's beyond the scope of this document to describe the G.I.S.T. interface.
Please see the G.I.S.T. documentation.
G.I.S.T. can be found at devdocs:
http://docs.dev-docs.org/
Permission granted by Lee Actor on 6/1/2023.
G.I.S.T. (G.I. Sound Tool) Driver v1.0
Exclusively for Antic
Design: Lee Actor and Gary Levenberg
Software: Lee Actor
Copyright (c) 1986 Synthetic Software
AES
_B _P _AES _CW _CH
_GLOBAL _DX _DY _DW _DH
_NAES
AESPB A~I G~H
ALERT()
AP_SEND()
BI_PDATA() BI_WB() BI_HL() BI_X() BI_Y()
BI_COLOR()
BF_OBSPEC() BF_CHARACTER() BF_FRAMESIZE() BF_FRAMECOL()
BF_TEXTCOL() BF_TEXTMODE() BF_FILLPATTERN() BF_INTERIORCOL()
CI_NUM_PLANES() CI_MAINLIST() CI_COL_DATA() CI_COL_MASK()
CI_SEL_DATA() CI_SEL_MASK() CI_NEXT_RES()
GEMSYS
GLOBAL GLOBAL() MSG() MSG
GMOUSE GMOUSEX GMOUSEY GMOUSEK
GHIDEM GSHOWM
IB_PMASK() IB_PDATA() IB_PTEXT() IB_CHAR()
IB_XCHAR() IB_YCHAR() IB_XICON() IB_YICON()
IB_WICON() IB_HICON() IB_XTEXT() IB_YTEXT()
IB_WTEXT() IB_HTEXT() IB_FCOLOR() IB_BCOLOR()
IB_LETTER()
INPUTBOX() INPUTRADIO() POPUP()
OB.FLAGS() OB.STATE() OB_RADIO() OB_TEXT$()
OB_SELECTED() OB_CROSSED() OB_CHECKED() OB_DISABLED()
OB_OUTLINED() OB_SHADOWED() OB_WHITEBAK()
OB_SELECTABLE() OB_DEFAULT() OB_EXIT() OB_EDITABLE()
OB_RBUTTON() OB_LASTOB() OB_TOUCHEXIT() OB_HIDETREE()
OB_INDIRECT() OB_FL3DIND() OB_FL3DACT() OB_FL3DBAK()
OB_SUBMENU() OB_EXTYPE()
OB_XYWH()
RC_REDRAW
SET.MENU
SLEEP
TE_PTEXT() TE_PTMPLT() TE_PVALID() TE_FONT()
TE_FONTID() TE_JUST() TE_COLOR() TE_FONTSIZE()
TE_THICKNESS() TE_TXTLEN() TE_TMPLEN() TE_FRAMECOL()
TE_TEXTCOL() TE_TEXTMODE() TE_FILLPATTERN() TE_INTERIORCOL()
UB_CODE() UB_PARM()
WF_NAME() WF_INFO() WF_TOP()
APPL_CONTROL() APPL_GETINFO() APPL_SEARCH()
APPL_YIELD() APPL.YIELD()
APPL.FIND()
FORM_POPUP() FORM.KEYBD()
FSEL_EXINPUT()
GRAF_MULTIRUBBER()
MENU.TEXT()
MENU_ATTACH() MENU_POPUP() MENU_ISTART() MENU_SETTINGS()
OBJC_SYSVAR() OBJC_XFIND()
RSRC_RCFIX()
SHEL_HELP() SHEL_WDEF() SHEL_RDEF() SHEL.WRITE()
WIND_NEW() WIND_SGET()
Notes: The AES support is at the level of NAES. AES v4.1 + some NAES calls.
XaAES or MagiC calls still require custom bindings.
GMOUSE
x=GMOUSEX (v3.7)
y=GMOUSEY
k=GMOUSEK
GHIDEM GSHOWM
GMOUSE x,y,k
x, y, k: ivar
AES equivalents of HIDEM, SHOWM, MOUSEX, MOUSEY, MOUSEK, and MOUSE.
These will also honor CLIP OFFSET.
graf_mkstate()+, graf_mouse()+
WIND_NEW
stat=WIND_NEW() (v3.7)
stat: ivar
This function closes and deletes all of the application's windows. In addition,
the state of wind_update(), and the mouse pointer hide count is reset.
Return value is always 1.
Note: This function should not be relied upon to clean up after an application.
It was designed for emergency cleanup of an application when recovery is not
possible.
wind_new()+
WIND_SGET
stat=WIND_SGET(handle,mode,tout$) (v3.7)
stat: ivar
handle, mode: iexp
tout$: svar
This function can be used to obtain the window title or info string.
handle - window handle
mode - WF_NAME (2) or WF_INFO (3)
tout$ - contains the result of the call
if the window has no associated string it returns an empty string
stat - 0 = window has no associated string
1 = string was successfully returned
This is an NAES call.
See documentation provided with NAES for further information.
OBJC_SYSVAR
stat=OBJC_SYSVAR(mode,which,in1,in2[,out1,out2]) (v3.7)
mode, which, in1, in2: iexp
stat, out1, out2: ivar
This function returns/modifies information about the color and placement of 3D
object effects.
The output variables are optional. The results can also be found in
GINTOUT(1-2).
objc_sysvar()+
APPL_YIELD
stat=APPL_YIELD() (v3.7)
~APPL.YIELD()
stat: ivar
These functions will force an AES process change.
APPL_YIELD() - Return value is always 1.
APPL.YIELD() - Return value is undefined.
Alternate version that works with SingleTOS.
It's equivalent to _appl_yield.
appl_yield()+, _appl_yield+
APPL_CONTROL
stat=APPL_CONTROL(apid,what,cout) (v3.7)
apid, what: iexp
stat, cout: ivar
This function can be used to control the activity of applications.
apid - application ID of the application to be controlled
what - determines the type of control
cout - returns or sends information
appl_control()+
APPL_GETINFO
stat=APPL_GETINFO(type[,out1,out2,out3,out4]) (v3.7)
type: iexp
stat, out1, out2, out3, out4: ivar
This function returns information about the AES.
type - determines the type of information requested
out1, out2, out3, out4 - returns the requested information
The output variables are optional. The results can also be found in
GINTOUT(1-4).
appl_getinfo()+
stat=FSEL_EXINPUT(pout$,fout$,bout,title$) (v3.7)
pout$, fout$: svar
title$, sexp
stat, bout: ivar
Available as of AES version 1.40.
Works nearly identical to FSEL_INPUT(). It adds one additional parameter for
the file selector title. The title is displayed at the top of the file selector
and is limited to a maximum of 30 characters.
fsel_exinput()+
OBJC_XFIND
stat=OBJC_XFIND(tree,start,depth,x,y) (v3.7)
objc_xfind()+
RSRC_RCFIX
stat=RSRC_RCFIX(addr) (v3.7)
rsrc_rcfix()+
APPL_SEARCH
stat=APPL_SEARCH(mode,fout$[,tout,aout]) (v3.7)
appl_search()+
stat=FORM_POPUP(tree,x,y) (v3.7)
form_popup()+
GRAF_MULTIRUBBER
stat=GRAF_MULTIRUBBER(x,y,minw,minh,xo,yo,wo,ho[,outw,outh]) (v3.7)
If xo and yo and wo and ho = 0 then the second box is disabled, then it works
just like GRAF_RUBBERBOX().
Note: Parameter scheme doesn't follow the official documentation. Adjusted to
eliminate the 'rec' structure. Does not work in XaAES or MaGiC.
graf_multirubber()+, graf_rubberbox()+
stat=MENU_ATTACH(flag,tree,item,mdata) (v3.7)
stat=MENU_POPUP(menu,x,y,mdata)
SET.MENU adr,tree,menu,item,scroll,keystate
adr, tree, menu, item, scroll, keystate: iexp
SET.MENU is a helper command to create sub-menu 'mdata' structures.
adr should point to a 12 byte buffer.
Example:
INLINE mdata%,12
SET.MENU mdata%,optiontree%,0,1,0,0
~MENU_ATTACH(1,menubartree%,options&,mdata%)
menu_attach()+, menu_popup()+
stat=MENU_ISTART(flag,tree,imenu,item) (v3.7)
menu_istart()+
stat=MENU_SETTINGS(flag,set) (v3.7)
menu_settings()+
GEMSYS
GEMSYS [opcode[,gintin_cnt,gintout_cnt,addrin_cnt,addrout_cnt]] (v3.7)
opcode, gintin_cnt, gintout_cnt, addrin_cnt, addrout_cnt; iexp
New variation of GEMSYS with 5 parameters which fills the GCONTRL() array in
one line of code. This is faster and produces less code than setting each index
line by line.
Note: This particular variant of GEMSYS is designed for AES functions not
built into the language and bindings are required, such as XaAES or MagiC
functions.
Example:
FUNCTION form_wbutton(handle&,tree%,object&,nclicks&,VAR nextob&)
$F%
'
GINTIN(0)=object&
GINTIN(1)=nclicks&
GINTIN(2)=handle&
'
ADDRIN(0)=tree%
'
GEMSYS 63,3,2,1,0
'
nextob&=GINTOUT(1)
RETURN GINTOUT(0)
ENDFUNC
_AES
x=_AES (v3.7)
x=_NAES
x=_B
x=_P
x=_CW
x=_CH
x=_DX
x=_DY
x=_DW
x=_DH
x=A~I
x=G~H
x=GLOBAL
x=GLOBAL(index)
x=_GLOBAL
_GLOBAL=val
x=MULTITASK?{b}
x: ivar
index, val: iexp
_AES - Returns the AES version. &H0320 -> 3.20
_NAES - Returns the version of N.AES. If not installed returns zero.
See N.AES documentation to decode the version number.
Note: XaAES's fake N.AES cookie is ignored and _NAES returns zero.
_B - Returns the bitplanes as reported by the AES, thus eliminating the need
to call vq_extnd() just for this one piece of information.
_P - Returns the palette as reported by the AES, unlike _C which returns the
pen count (256 for high-color and true-color).
Typical values returned: 2, 4, 16, 256, 32768, 65536, 16777216
Note: A 32-bit screen will report 16777216, since one byte of the RGB
data is normally used as an alpha channel.
_CW/_CH - Default character width/height in pixels used by the AES.
Obtained via GRAF_HANDLE().
_DX/_DY/_DW/_DH - Destop x/y position and width/height in pixels.
Equivalent to WF_WORKXYWH.
A~I - Returns the applications Application ID.
There's no need to call the dummy function APPL_INIT().
G~H - Returns the VDI handle used by the AES. Obtained from GRAF_HANDLE().
Used to open a virtual workstation.
GLOBAL - Returns a pointer to the applications global array.
GLOBAL() - Allows accessing the applications global array indexed (0-14).
Values outside this range generate error code #71.
_GLOBAL - Built in variable that's treated like a long (%).
It can be read and written.
It's stored in GLOBAL array entry _AESappglobal.
MULTITASK? - Returns TRUE or FALSE.
Internally uses GLOBAL array entry _AESnumapps.
Examples: ~MENU_REGISTER(A~I," MyAppName")
x=WORD{GLOBAL+2} !number of concurrent apps
x=GLOBAL(1) ! same...
'
_GLOBAL=2
PRINT _GLOBAL !-> displays '2'
appl_init()+, graf_handle()+
WF_NAME
stat=WF_NAME(whan,addr,str$) (v3.6)
stat=WF_INFO(whan,addr,str$)
whan, addr: iexp
str$: sexp
These functions are used to set window titles and info lines. The string is
copied to the buffer and null terminated automatically. Null strings are
allowed.
whan - window handle
addr - address of text buffer
str$ - string of text
stat = result of wind_set()
' buffer
INLINE adr%,82
' wh&=wind_create(...
~WF_NAME(wh&,adr%," GFA v3.7 test ")
wind_set()+
ALERT()
choice=ALERT(icon,message$,default,button$) (v3.7)
choice: ivar
icon, default: iexp
message$, button$: sexp
Works identical to the command ALERT, but as a function.
Allows lines up to 40 characters and buttons up to 20 characters.
Supports NAES limits.
This is now possible:
~ALERT(... ) !if you don't need to know what was clicked
or
IF ALERT(... )=2 !no variable required
Note: No checks are made to insure the parameters are valid for the version
of TOS it might be running on. That's left up to the coder.
form_alert()+, form_error()+
AP_SEND
stat=AP_SEND(ap_id,msg_type,item1,item2,item3,item4,item5) (v3.7)
ap_id, msg_type, item1, item2, item3, item4, item5: iexp
stat: ivar
This function is used to send a standard size AES message. The message size
is preset to 16 (standard) and the from application ID will be automatically
set. The function returns the result of APPL_WRITE().
Variable Index Meaning
-------- ----- ---------------------------------------------------------
ap_id send message to this application - APPL_WRITE() parameter
msg_type msg(0) Message type
msg(1) Senders application ID (preset)
msg(2) Message length beyond 16 bytes (preset)
item1 msg(3) Depends on message
item2 msg(4) Depends on message
item3 msg(5) Depends on message
item4 msg(6) Depends on message
item5 msg(7) Depends on message
' send yourself a window move message in one line of code
~AP_SEND(appl_id&,28,wh_&,x&,y&,w&,h&)
Replaces this chunk of code:
INLINE msg%,16
WORD{msg%+0}=28 !wm_moved
WORD{msg%+2}=appl_id& !from
WORD{msg%+4}=0 !standard size
WORD{msg%+6}=wh_& !handle
WORD{msg%+8}=x& !x
WORD{msg%+10}=y& !y
WORD{msg%+12}=w& !w
WORD{msg%+14}=h& !h
~APPL_WRITE(appl_id&,16,msg%)
Note: If you need to pass a long that uses 2 message elements do this:
' need to pass adr% in msg(3-4)
~AP_SEND(appl_id&,$2345,CARD(SWAP(adr%)),CARD(adr%),0,0,0)
appl_write()+
stat=MENU.TEXT(tree,obj,addr) (v3.7)
tree, obj, addr: iexp
stat: ivar
Alternate variant of MENU_TEXT() with correct parameter scheme.
menu_text()+
SHEL.WRITE
stat=SHEL.WRITE(mode,gr,cr,cmd,tail) (v3.7)
mode, gr ,cr, cmd, tail: iexp
stat: ivar
Alternate variant of SHEL_WRITE() with correct parameter scheme.
shel_write()+
APPL.FIND
stat=APPL.FIND(addr) (v3.7)
addr: iexp
stat: ivar
Alternate variant of APPL_FIND() with correct parameter scheme.
Values for addr:
High Low Return value
0 0 current apid
-1 ($FFFF) pid aid
-2 ($FFFE) aid pid
-3 ($FFFD) 0 aid of topped (focus) application
? ? pointer to c string padded to 8 chars with trailing spaces
appl_find()+
OB.STATE
OB.STATE(tree,obj,bit)=flag (v3.7)
OB.FLAGS(tree,obj,bit)=flag
stat=OB.STATE(tree,obj,bit)
stat=OB.FLAGS(tree,obj,bit)
tree, obj, bit, flag: iexp
stat: ivar
These commands and functions allow testing and setting single bits.
They do not redraw objects.
OB.STATE() and OB.FLAGS() allow access to all 16 bits.
'bit' should be in the range of 0-15, else error #71 occurs.
As a function they return boolean TRUE or FALSE.
As a command 'flag' is treated as boolean:
FALSE (0)
TRUE (<>0)
Examples:
IF OB.STATE(tree%,obj&,0) !object is selected?
' do something
ENDIF
OB.STATE(tree%,obj&,0)=TRUE !set selected bit
OB.STATE(tree%,obj&,0)=FALSE !clr selected bit
Typically replaces these code segments:
IF BTST(OB_STATE(tree,obj),0) -> IF OB.STATE(tree,obj,0)
OB_STATE(tree,obj)=BSET(OB_STATE(tree,obj),0) -> OB.STATE(tree,obj,0)=TRUE
ob_state+, ob_flags+
OB_RADIO
os=OB_RADIO(tree,objstart,objend) (v3.7)
OB_RADIO(tree,objstart,objend)=offset
tree, objstart, objend, offset: iexp
os: ivar
As command: OB_RADIO(tree,obstart,obend)=offset
As function: offset=OB_RADIO(tree,obstart,obend)
Explanation of offset:
Lets say you have a cnf file and some option you wish to save and load.
'offset' is saved and loaded
That offset is a value from 0 to 3, thus you need 4 radio buttons:
Simple dialog example:
+--------------------------------------------------------------+
| Title: |
| |
| +-----------+ +-----------+ +-----------+ +-----------+ |
| | rbutton 1 | | rbutton 2 | | rbutton 3 | | rbutton 4 | |
| +-----------+ +-----------+ +-----------+ +-----------+ |
| |
| +----+ |
| | Ok | |
| +----+ |
+--------------------------------------------------------------+
Note the rbuttons are surrounded by and invisible box.
This forces the rbuttons to be numbered consecutively.
Object indexes: (created by the rsc editor)
dbox = 0 ;root obj
title = 1
ibox = 2 ;invisible box
rbut1 = 3 ;start
rbut2 = 4
rbut3 = 5
rbut4 = 6 ;end
okbut = 7
For example sake, say: offset = 2
To initialize the dialog and set the correct rbutton:
OB_RADIO(tree,rbut1,rbut4)=offset
rbutton 3 will be selected.
This call will set the SELECTED state of the button based on an 'offset'
from 'obstart', and clear the SELECTED state of all other buttons.
To fetch the button that is selected:
offset=OB_RADIO(tree,rbut1,rbut4)
If the 1st button is selected it returns: 0
If the 2nd button is selected it returns: 1
If the 3nd button is selected it returns: 2
If the 4th button is selected it returns: 3 etc..
The actual object index selected is then easily computed with:
actual=rbut1+offset
OB_TEXT$
result$=OB_TEXT$(tree,obj) (v3.7)
OB_TEXT$(tree,obj)=text$
result$: svar
tree, obj: iexp
text$: sexp
These will look at the object type and handle reading/writing of the text
correctly for all object types that support text strings.
As a command: OB_TEXT$(tree,obj)=text$
This command adds a null terminator. Do not add a null byte!
If you accidentally do this:
OB_TEXT$(tree,obj)=mytext$+CHR$(0) !could overrun the buffer!
As a function: result$=OB_TEXT$(tree,obj)
The null byte is not returned with the result.
Some object types contain pointers to more than one text string. These commands
only work on the most commonly used string within a give object type.
See table below:
Type Name String read/written
20 G_BOX bfobspec -> char
21 G_TEXT tedinfo -> te_ptext
22 G_BOXTEXT tedinfo -> te_ptext
23 G_IMAGE error
24 G_USERDEF error
25 G_IBOX bfobspec -> char
26 G_BUTTON ob_spec
27 G_BOXCHAR bfobspec -> char
28 G_STRING ob_spec
29 G_FTEXT tedinfo -> te_ptext
30 G_FBOXTEXT tedinfo -> te_ptext
31 G_ICON conblk -> ib_ptext
32 G_TITLE ob_spec
33 G_CICON ciconblk -> ib_text
34 G_SWBUTTON swinfo -> sw_string
35 G_POPUP error
38 G_SHORTCUT ob_spec
bfobspec:
Only the 1st character of the string is considered. If the string happens to
be longer than 1 character the rest of the sting is ignored. It's impossible
to overrun a buffer in this particular case.
ob_spec, iconblk, ciconblk:
The coder must insure that the string passed in does not overrun the buffer
that was preallocated in the *.RSC file. To avoid buffer overruns one can do
something like this:
' assuming object has a 32 character buffer in the *.rsc file
OB_TEXT$(tree,obj)=MID$(mytext$,1,32) !insure text never exceeds 32!
tedinfo:
Text is clipped to the value of the te_txtlen entry within the structure.
error:
Objects with no string fields. These will generate error code #71.
Invalid object numbers will also issue the same error.
Note: To alter additional text strings associated with certain objects like
tedinfo -> te_pvalid, you will need to directly access those structures
yourself.
These command does not create the structures, then must already exists.
WF_TOP
stat=WF_TOP(handle) (v3.7)
stat: ivar
handle: iexp
This function sets or inquires the top most AES window.
If handle = -1 then it inquires the top most window
stat = 0 means the Desktop
stat > 0 means top most window
equivalent to ~WIN_GET(0,10,stat&,0,0,0)
If handle => 0 then it sets the top most window, stat returns an error code
stat = 0 means failed
stat = non-zero means ok
equivalent to stat&=WIND_SET(handle&,10,0,0,0,0)
wind_get()+, wind_set()+
SHEL_HELP
stat=SHEL_HELP(mode,file$,key$) (v3.7)
stat: ivar
mode: iexp
file$, key$: sexp
This function can be used to call help files.
This is an NAES call. See NAES documentation for more information.
Assuming one has similar entry in N_AES.CNF:
helpserver = hyp,ST-GUIDE,c:\st-guide.acc
Example:
stat&=SHEL_HELP(0,"*:\gbe_lib.hyp","BEEP") !open node 'BEEP'
shel_help()+
SHEL_WDEF
stat=SHEL_WDEF(cmd$,path$) (v3.7)
stat=SHEL_RDEF(cmd_out$,path_out$)
stat: ivar
cmd$, path$: sexp
cmd_out$, path_out$: svar
SHEL_WDEF() always returns one (1).
SHEL_RDEF() returns one (1) for ok and zero (0) for failure.
These are NAES calls. See NAES documentation for more information.
shel_wdef()+, shel_rdef()+
MSG
x=MSG(index) (v3.7)
adr=MSG
x, adr: ivar
index: iexp
These functions allow accessing GFA's built in message buffer using standard
indexing as seen in nearly all AES documentation.
MSG() - As an indexed array
Index can be 0 to 7 or error #71 occurs
MSG - As a pointer
This pointer should only be read
'C' GFA Description
MSG(0) msg[0] MENU(1) Message type
MSG(1) msg[1] MENU(2) Application ID of sender
MSG(2) msg[2] MENU(3) Length of message (0 for standard message size)
MSG(3) msg[3] MENU(4) Depends on message
MSG(4) msg[4] MENU(5) Depends on message
MSG(5) msg[5] MENU(6) Depends on message
MSG(6) msg[6] MENU(7) Depends on message
MSG(7) msg[7] MENU(8) Depends on message
Examples:
ptr%=MAKE%(MSG(3),MSG(4)) !perhaps more readable
ptr%=LONG{MSG+6} !tad faster
The Event Dispatcher+
stat=FORM.KEYBD(tree,obj,next_obj,char[,new_obj,new_char]) (v3.7)
This is a variant of FORM_KEYBD(). The parameter order matches all official
AES documents.
form_keybd()+
SLEEP
SLEEP [x] (v3.7)
x: iexp
This command will sleep a program for x amount of time or until any AES
message arrives. When a program sleeps it sits idle and yields time back to
other running processes.
Parameter x is expressed in milliseconds.
SLEEP : Program sleeps until any AES message arrives
The AES message can be found in MENU() or MSG()
SLEEP x : Program sleeps for x milliseconds
Examples:
SLEEP 2000 !sleep 2 seconds
'
SLEEP !sleep until an AES message arrives
PRINT MSG(0)
evnt_timer()+, evnt_mesag()+
index=POPUP(items$,xpos,ypos,scroll) (v3.70)
index: ivar (must be able to hold 32-bits)
item$: sexp
xpos, ypos, scroll: iexp
Generates a modal popup on the fly.
Requires AES v3.30 or higher. Error #98 occurs if the AES version is to old.
items$ - List of items separated by pipe '|' characters
Maximum of 32 items, with a maximum of 64 characters per item
Items beginning with a minus '-' will be a separators
Items beginning with a plus '+' will be check marked
Items beginning with a tilde '~' will be disabled
The widest item in the list determines the popup width
Error #60 occurs if any of the string limits are exceeded
xpos - x position of top/left corner of popup
ypos - y position of top/left corner of popup
If x/y are both -1 then use current mouse position instead
scroll - Determine popup style
FALSE = normal popup
TRUE = listbox (if under 8 items displays as normal popup)
index - Returns item selected as a long
upper-word = modifier keys
lower-word = item selected
0 = nothing selected, user aborted popup, clicked outside popup
1 to ? = index of the selected item
Notes: No adjustments are made to insure the popup is fully visible.
N.AES automatically adjusts the x/y coordinates if needed.
Other AES implementations might not do this.
MagiC seems to auto adjust the y but not the x.
Separators are not expanded to span the full width of the popup.
N.AES automatically adjusts the separators, so a single '-' can be used.
Other AES implementations might not do this.
MagiC does not.
If you need more elaborate popups or attached submenus then this command
isn't for you.
Examples:
index%=POPUP("index1|index2|index3",x,y,TRUE)
index%=POPUP("index1|index2|index3",-1,-1,FALSE) !at mouse position
' only want the item
IF WORD(item%)=2
@do_something
ENDIF
menu_popup()+
button=INPUTBOX(defbut,title$,prompt$,template$,pvalid$,sout$) (v3.7)
button: ivar
defbut: iexp
title$, prompt$, template$, pvalid$: sexp
sout$: svar
This function provides a simple modal GEM style input dialog.
It's limited to one line of input with a maximum of 35 characters.
Works on all AES versions.
defbut - Default button when the Return key is pressed
0 = None
1 = Ok
2 = Cancel
If defbut is out of range 'none' is used
title$ - Dialog title
prompt$ - Message stating what the user should enter
template$ - For each character that the user can enter, the text string should
contain a underscore character (ASCII 95). Other characters are
displayed but cannot be overwritten by the user
Determines the length of the editable field
Pass a null ("") for the default
pvalid$ - Validation characters for each character the user may enter
Pass a null string ("") for the default, all characters ("X")
sout$ - Returns edited/entered text
The contents of sout$ will be displayed when the dialog appears
Set sout$ to null ("") for an empty input field
button& - Returns button that ended the dialog
1 = Ok (sout$ returns the entered text)
2 = Cancel (sout$ is returned unchanged)
Notes: Strings that are too long will be cropped.
The dialog is always centered on the screen.
Looks a bit odd in MagiC, but it's functional.
There should be one character in pvalid for every underscore ("_") in
the template. Not following this rule might result in strange behavior.
If you need more characters or multiple lines of input then this
command isn't for you.
Examples:
Default if template$ and pvalid$ are null (""):
template$ = "___________________________________"
pvalid$ = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
For a date:
template$ = "__/__/____" 8 underscores
pvalid$ = "99999999" 8 characters
For a filename:
template$ = "________.___" 11 underscores
pvalid$ = "FFFFFFFFFFF" 11 characters
pvalid$ table:
Character Allows
9 Digits 0-9
A Uppercase letters A-Z plus space
a Upper and lowercase letters plus space
N Digits 0-9, uppercase letters A-Z, and space
n Digits 0-9, upper and lowercase letters A-Z, and space
F Valid GEMDOS filename characters plus question mark and asterisk
P Valid GEMDOS pathname characters plus backslash, colon,
question mark, and asterisk
p Valid GEMDOS pathname characters plus backslash and colon
X All characters
See AES documentation for further information regarding template$ and pvalid$.
form_do()+
OB_SELECTED
status=OB_SELECTED(tree,object) (v3.7)
status=OB_CROSSED(tree,object)
status=OB_CHECKED(tree,object)
status=OB_DISABLED(tree,object)
status=OB_OUTLINED(tree,object)
status=OB_SHADOWED(tree,object)
status=OB_WHITEBAK(tree,object)
OB_SELECTED(tree,object)=flag
OB_CROSSED(tree,object)=flag
OB_CHECKED(tree,object)=flag
OB_DISABLED(tree,object)=flag
OB_OUTLINED(tree,object)=flag
OB_SHADOWED(tree,object)=flag
OB_WHITEBAK(tree,object)=flag
status: ivar
tree, object, flag: iexp
Get or set various AES object states.
They do not redraw objects.
As a function they return boolean TRUE or FALSE.
As a command 'flag' is treated as boolean:
FALSE (0)
TRUE (<>0)
Example:
IF OB_SELECTED(dialog%,ok&) !ok button selected?
OB_SELECTED(dialog%,ok&)=FALSE !clr selected status
' redraw button or do whatever
ENDIF
Typically replaces these code segments:
IF BTST(OB_STATE(tree,obj),0) -> IF OB_SELECTED(tree,obj)
OB_STATE(tree,obj)=BSET(OB_STATE(tree,obj),0) -> OB_SELECTED(tree,obj)=TRUE
ob_state+
OB_SELECTABLE
status=OB_SELECTABLE(tree,object) (v3.7)
status=OB_DEFAULT(tree,object)
status=OB_EXIT(tree,object)
status=OB_EDITABLE(tree,object)
status=OB_RBUTTON(tree,object)
status=OB_LASTOB(tree,object)
status=OB_TOUCHEXIT(tree,object)
status=OB_HIDETREE(tree,object)
status=OB_INDIRECT(tree,object)
status=OB_FL3DIND(tree,object)
status=OB_FL3DACT(tree,object)
status=OB_SUBMENU(tree,object)
status=OB_FL3DBAK(tree,object)
OB_SELECTABLE(tree,object)=flag
OB_DEFAULT(tree,object)=flag
OB_EXIT(tree,object)=flag
OB_EDITABLE(tree,object)=flag
OB_RBUTTON(tree,object)=flag
OB_LASTOB(tree,object)=flag
OB_TOUCHEXIT(tree,object)=flag
OB_HIDETREE(tree,object)=flag
OB_INDIRECT(tree,object)=flag
OB_FL3DIND(tree,object)=flag
OB_FL3DACT(tree,object)=flag
OB_SUBMENU(tree,object)=flag
OB_FL3DBAK(tree,object)=flag
status: ivar
tree, object, flag: iexp
Get or set various AES object flags.
They do not redraw objects.
As a function they return boolean TRUE or FALSE.
As a command 'flag' is treated as boolean:
FALSE (0)
TRUE (<>0)
Example:
IF OB_HIDETREE(dialog%,ok&) !hidden tree?
OB_HIDETREE(dialog%,ok&)=FALSE !clr hidden status
' redraw or do whatever
ENDIF
ob_flags+
BF_OBSPEC
result=BF_OBSPEC(tree,object) (v3.7)
result=BF_CHARACTER(tree,object)
result=BF_FRAMESIZE(tree,object)
result=BF_FRAMECOL(tree,object)
result=BF_TEXTCOL(tree,object)
result=BF_TEXTMODE(tree,object)
result=BF_FILLPATTERN(tree,object)
result=BF_INTERIORCOL(tree,object)
BF_OBSPEC(tree,object)=value
BF_CHARACTER(tree,object)=value
BF_FRAMESIZE(tree,object)=value
BF_FRAMECOL(tree,object)=value
BF_TEXTCOL(tree,object)=value
BF_TEXTMODE(tree,object)=value
BF_FILLPATTERN(tree,object)=value
BF_INTERIORCOL(tree,object)=value
result: ivar
tree, object, value: iexp
Get or set elements of a BFOBSPEC structure.
Works on G_BOX, G_IBOX, and G_BOXCHAR object types.
'value's out of range are masked off and discarded with no error.
BF_OBSPEC() -> get/set the BFOBSPEC structure as a long
.... or get/set individual elements of the BFOBSPEC structure:
BF_CHARACTER() 0 to 255
BF_FRAMESIZE() -128 to 127
BF_FRAMECOL() 0 to 15
BF_TEXTCOL() 0 to 15
BF_TEXTMODE() 0 or 1
BF_FILLPATTERN() 0 to 7
BF_INTERIORCOL() 0 to 15
Note: These commands assume the OB_FLAGS -> INDIRECT bit is off.
bfobspec+, obspec+
BI_PDATA
result=BI_PDATA(tree,object) (v3.7)
result=BI_WB(tree,object)
result=BI_HL(tree,object)
result=BI_X(tree,object)
result=BI_Y(tree,object)
result=BI_COLOR(tree,object)
BI_PDATA(tree,object)=value
BI_WB(tree,object)=value
BI_HL(tree,object)=value
BI_X(tree,object)=value
BI_Y(tree,object)=value
BI_COLOR(tree,object)=value
result: ivar
tree, object, value: iexp
Get or set elements of a BITBLK structure.
Works on G_IMAGE object type.
'value's out of range are masked off and discarded with no error.
Note: These commands assume OB_FLAGS -> INDIRECT bit is off.
bitblk+
UB_CODE
result=UB_CODE(tree,object) (v3.7)
result=UB_PARM(tree,object)
UB_CODE(tree,object)=value
UB_PARM(tree,object)=value
result: ivar
tree, object, value: iexp
Get or set elements of a USERBLK structure.
This structure is 8 bytes.
Works on G_USERDEF object type.
'value's out of range are masked off and discarded with no error.
Note: These commands assume OB_FLAGS -> INDIRECT bit is off.
userblk+
TE_PTEXT
result=TE_PTEXT(tree,object) (v3.7)
result=TE_PTMPLT(tree,object)
result=TE_PVALID(tree,object)
result=TE_FONT(tree,object)
result=TE_FONTID(tree,object)
result=TE_JUST(tree,object)
result=TE_COLOR(tree,object)
result=TE_FONTSIZE(tree,object)
result=TE_THICKNESS(tree,object)
result=TE_TXTLEN(tree,object)
result=TE_TMPLEN(tree,object)
result=TE_FRAMECOL(tree,object)
result=TE_TEXTCOL(tree,object)
result=TE_TEXTMODE(tree,object)
result=TE_FILLPATTERN(tree,object)
result=TE_INTERIORCOL(tree,object)
TE_PTEXT(tree,object)=value
TE_PTMPLT(tree,object)=value
TE_PVALID(tree,object)=value
TE_FONT(tree,object)=value
TE_FONTID(tree,object)=value
TE_JUST(tree,object)=value
TE_COLOR(tree,object)=value
TE_FONTSIZE(tree,object)=value
TE_THICKNESS(tree,object)=value
TE_TXTLEN(tree,object)=value
TE_TMPLEN(tree,object)=value
TE_FRAMECOL(tree,object)=value
TE_TEXTCOL(tree,object)=value
TE_TEXTMODE(tree,object)=value
TE_FILLPATTERN(tree,object)=value
TE_INTERIORCOL(tree,object)=value
result: ivar
tree, object, value: iexp
Get or set elements of a TEDINFO structure.
Work on G_TEXT, G_FTEXT, G_BOXTEXT, and G_FBOXTEXT object types.
'value's out of range are masked off and discarded with no error.
TE_COLOR() -> get/set the te_color structure as a word
... or get/set individual elements of the te_color structure:
TE_FRAMECOL() 0 to 15
TE_TEXTCOL() 0 to 15
TE_TEXTMODE() 0 or 1
TE_FILLPATTERN() 0 to 7
TE_INTERIORCOL() 0 to 15
Note: These commands assume OB_FLAGS -> INDIRECT bit is off.
tedinfo+
IB_PMASK
result=IB_PMASK(tree,object) (v3.7)
result=IB_PDATA(tree,object)
result=IB_PTEXT(tree,object)
result=IB_CHAR(tree,object)
result=IB_XCHAR(tree,object)
result=IB_YCHAR(tree,object)
result=IB_XICON(tree,object)
result=IB_YICON(tree,object)
result=IB_WICON(tree,object)
result=IB_HICON(tree,object)
result=IB_XTEXT(tree,object)
result=IB_YTEXT(tree,object)
result=IB_WTEXT(tree,object)
result=IB_HTEXT(tree,object)
result=IB_FCOLOR(tree,object)
result=IB_BCOLOR(tree,object)
result=IB_LETTER(tree,object)
IB_PMASK(tree,object)=value
IB_PDATA(tree,object)=value
IB_PTEXT(tree,object)=value
IB_CHAR(tree,object)=value
IB_XCHAR(tree,object)=value
IB_YCHAR(tree,object)=value
IB_XICON(tree,object)=value
IB_YICON(tree,object)=value
IB_WICON(tree,object)=value
IB_HICON(tree,object)=value
IB_XTEXT(tree,object)=value
IB_YTEXT(tree,object)=value
IB_WTEXT(tree,object)=value
IB_HTEXT(tree,object)=value
IB_FCOLOR(tree,object)=value
IB_BCOLOR(tree,object)=value
IB_LETTER(tree,object)=value
result: ivar
tree, object, value: iexp
Get or set elements of an ICONBLK or CICONBLK structure.
Works on G_ICON and G_CICON object types.
'value's out of range are masked off and discarded with no error.
IB_CHAR() -> get/set the ib_char structure as a word
... or get/set individual elements of the ib_char structure:
IB_FCOLOR() 0 to 15
IB_BCOLOR() 0 to 15
IB_LETTER() 0 to 255
Note: These commands assume OB_FLAGS -> INDIRECT bit is off.
iconblk+, ciconblk+
CI_MAINLIST
value=CI_MAINLIST(tree,object) (v3.7)
value=CI_NUM_PLANES(tree,object)
value=CI_COL_DATA(tree,object)
value=CI_COL_MASK(tree,object)
value=CI_SEL_DATA(tree,object)
value=CI_SEL_MASK(tree,object)
value=CI_NEXT_RES(tree,object)
CI_MAINLIST(tree,object)=value
CI_NUM_PLANES(tree,object)=value
CI_COL_DATA(tree,object)=value
CI_COL_MASK(tree,object)=value
CI_SEL_DATA(tree,object)=value
CI_SEL_MASK(tree,object)=value
CI_NEXT_RES(tree,object)=value
result: ivar
tree, object, value: iexp
Get or set elements of a CICONBLK structure.
The CICONBLK structure shares the same basic structure as an ICONBLK.
To fully mananage a CICONBLK structure see also IB_xxx() commands.
Works on G_ICON object type.
'value's out of range are masked off and discarded with no error.
Note: These commands assume OB_FLAGS -> INDIRECT bit is off.
These access only the first cicon in the list if CI_MAINLIST()<>NULL
CI_NUM_PLANES()
CI_COL_DATA()
CI_COL_MASK()
CI_SEL_DATA()
CI_SEL_MASK()
CI_NEXT_RES()
ciconblk+
button=INPUTRADIO(dbutton,title$,rblist$,cur) (v3.7)
button: ivar
dbutton: iexp
title$, rblist$: sexp
cur: ivar
This function provides an easy to use GEM dialog with up to 6 radio buttons.
dbutton - Default exit button
0 = None (default if out of range)
1 = Ok
2 = Cancel
title$ - Dialog title up to 35 characters, clipped if longer
rblist$ - Radio button list separated with vertical bar characters '|'
Examples: "B1|B2" or "B1|B2|"
Maximum length of 11 characters each, clipped if longer
Extra spaces are not trimmed
An empty string causes error #60
cur - Radio button to highlighted at start
Returns the button user selected if Ok is clicked
They are numbered 0 to 5 (out of range defaults to 0)
button - Returns exit button that ended the dialog
1 = Ok
2 = Cancel (variable cur is unchanged)
Notes: The dialog is always centered.
The background is saved and restored automatically.
Example:
cur&=1 !gif
but&=@inputradio(2,"Select file format:","Degas|GIF|Targa|JPEG|TIFF",cur&)
PRINT but&,cur&
OB_XYWH
stat=OB_XYWH(tree,object[,xout,yout,wout,hout]) (v3.7)
stat, xout, yout, wout, hout: ivar
tree, object: iexp
This function returns the true screen coordinates of an AES object.
Return value is the same as OBJC_OFFSET().
Results can also be found in GINTOUT(0) to GINTOUT(4):
GINTOUT(0) stat
GINTOUT(1) xout
GINTOUT(2) yout
GINTOUT(3) wout
GINTOUT(4) hout
objc_offset()+
RC_REDRAW
RC_REDRAW [x,y,w,h] (v3.7)
x, y, w, h: iexp
This command can be used to force the desktop area to redraw.
It will not work on the menu bar area.
Requires GEM.
RC_REDRAW with no parameters is equivalent to passing _DX,_DY,_DW,_DH.
Use case? Perhaps you wrote a game that takes over the GEM screen, assuming
MiNT, when it exists this can be used to force the destop area to redraw.
This command shouldn't be relied on except were no other solution will work.
Internally it calls FORM_DIAL(FMD_START,...) and FORM_DIAL(FMD_FINISH,...).
form_dial()+
OB_EXTYPE
ex=OB_EXTYPE(tree,object) (v3.7)
OB_EXTYPE(tree,object)=val
ex: ivar
tree, object, val: iexp
These are used to read and write the extended object type of an AES object.
It's limited to a single byte value.
The AES uses the lower byte of OB_TYPE() when looking at objects.
The upper byte is the so called extended type.
Often used for rendering custom objects via user defined object types.
Note: As a command only the lower byte of 'val' is considered.
Do not change sub menu entries as the AES uses this to track sub menus.
If it's not a sub menu this can be freely used to store custom data.
ob_type+
AESPB
addr=AESPB (v3.7)
addr: ivar (able to hold 32-bits)
Returns address of GFA's internal AES parameter block.
AES Function Calling Procedure+
VDI
_SW _SH _NVDI _PX_FORMAT CLUT?
BAR PBAR RBAR PRBAR P3DBAR
C_XBIOS() C_VDI()
GETSIZE()
SET.GCBITMAP SET.RXYWH SET.SXYWH SET.DXYWH
SET.MFDB SET.PXYWH SET.SXYXY SET.DXYXY SET.PXYXY
STEXT
TBITBLT
TRIANGLE
VBOX VPLOT VLINE VPBAR VCURVE
VCLS
VDIPB
VGET VPUT
VPALGET VPALSET
VRC_COPY
VSGET VSPUT
WORK.OUT()
V_ARC() V_CIRCLE() V_PIESLICE()
V_BAR() V_RBOX() V_RFBOX() VR_RECFL()
V_BEZ() V_BEZ_FILL() V_BEZ_QUAL() V_BEZ_ON() V_BEZ_OFF()
V_CONTOURFILL()
V_CURADDRESS() VQ_CURADDRESS()
V_CURTEXT() VQ_CHCELLS() VQ_TABSTATUS()
V_CURUP() V_CURDOWN() V_CURRIGHT() V_CURLEFT() V_CURHOME()
V_ELLARC() V_ELLPIE() V_ELLIPSE()
V_ENTER_CUR() V_EXIT_CUR() V_DSPCUR() V_RMCUR()
V_GET_PIXEL()
V_GTEXT() V_JUSTIFIED()
V_HARDCOPY()
V_PLINE() V_PMARKER() V_FILLAREA() V_CLEAR_DISP_LIST()
V_RVON() V_RVOFF() V_EEOL() V_EEOS()
VEX_TIMV() VEX_BUTV() VEX_MOTV() VEX_CURV()
VQ_EXTND() VQ_SCRNINFO()
VQ_MOUSE() VQ_KEY_S() V_HIDE_C() V_SHOW_C()
VQ_VGDOS()
VS_CLIP()
VS_COLOR() VQ_COLOR()
VST_POINT()
VST_ALIGNMENT()
VQF_ATTRIBUTES() VQL_ATTRIBUTES()
VQM_ATTRIBUTES() VQT_ATTRIBUTES()
VQT_FONTINFO()
VQT_WIDTH()
VRO_CPYFM() VRT_CPYFM() VR_TRNFM()
VSC_FORM()
VSF_COLOR() VSF_INTERIOR() VSF_PERIMETER() VSF_STYLE() VSF_UDPAT()
VSL_COLOR() VSL_TYPE() VSL_WIDTH() VSL_ENDS() VSL_UDSTY()
VSM_COLOR() VSM_HEIGHT() VSM_TYPE()
VST_COLOR() VST_EFFECTS() VST_ROTATION() VST_HEIGHT() VST_FONT()
VSWR_MODE()
V_OPNBM() V_CLSBM()
V_CREATE_CTAB() V_DELETE_CTAB() V_CREATE_ITAB() V_DELETE_ITAB()
V_OPEN_BM() V_RESIZE_BM()
V_COLOR2VALUE() V_VALUE2COLOR() V_COLOR2NEAREST()
V_SETRGB()
V_CTAB_IDX2VALUE() V_GET_CTAB_ID() V_CTAB_VDI2IDX() V_CTAB_IDX2VDI()
VQ_CTAB()
VQ_PX_FORMAT() VQ_DFLT_CTAB() VQ_CTAB_ID() VQ_CTAB_ENTRY()
VS_CTAB() VS_CTAB_ENTRY() VS_DFLT_CTAB()
VS_HILITE_COLOR() VS_MIN_COLOR() VS_MAX_COLOR() VS_WEIGHT_COLOR()
VQ_HILITE_COLOR() VQ_MIN_COLOR() VQ_MAX_COLOR() VQ_WEIGHT_COLOR()
VQT_EXT_NAME() VQT_XFNTINFO() VQT_FONTHEADER() VQT_NAME_AND_ID()
VST_NAME() VST_WIDTH()
VST_BG_COLOR() VSF_BG_COLOR() VSL_BG_COLOR() VSM_BG_COLOR()
VSR_BG_COLOR()
VQT_BG_COLOR() VQF_BG_COLOR() VQL_BG_COLOR() VQM_BG_COLOR()
VQR_BG_COLOR()
VST_FG_COLOR() VSF_FG_COLOR() VSL_FG_COLOR() VSM_FG_COLOR()
VSR_FG_COLOR()
VQT_FG_COLOR() VQF_FG_COLOR() VQL_FG_COLOR() VQM_FG_COLOR()
VQR_FG_COLOR()
VR_TRANSFER_BITS()
VR_CLIP_RECTS_BY_DST() VR_CLIP_RECTS_BY_SRC()
Note: Functions that are direct VDI calls do not honor CLIP OFFSET. The last
x/y coordinate will also not be remembered for auto connecting certain line
drawing functions. If you need these features use the normal graphics
commands, like PLOT, LINE, DRAW, etc. Not honoring these yields a small speed
improvement.
The VDI API is somewhat daft in that nearly all functions that require an
array of points or data take that information and then copy it to the VDI
parameter block array. This wastes time. To yield better performance these
functions have a modified parameter scheme. They expect the PTSIN() or INTIN()
array to be pre-filled before the call, thus eliminating the need to copy the
data to the VDI parameter block array. It's already there. The same applies
to functions that output arrays of data. Instead of copying the data to a user
array, these functions expect one to integrate the VDI parameter block array
after the call. Again, this saves time. In most cases the coder is only
interested in 1 or 2 items that are returned anyway.
Why was the handle parameter removed? Short answer, to be compatible with the
scheme already in place. GFA keeps the current default VDI handle in CONTRL(6)
at all times. The built in VDI commands will stop working if CONTRL(6) is
changed. Every fucntion would have to save and restore the contents of
CONTRL(6) if a handle was passed. This would add unwanted overhead. As it
turns out, the current scheme yields a small performance boost since the
handle isn't passed to each function.
GETSIZE
count=GETSIZE(x1,y1,x2,y2,planes) (v3.7)
x1, y1, x2, y2, planes: iexp
count: ivar
Enhanced GETSIZE() that allows calculating bitmaps of any size and color
depth regardless of the current video mode.
GETSIZE() with 5 parameters calculates image sizes based on VDI values.
x1 - top left x
y1 - top left y
x2 - bottom right x
y2 - bottom right y
planes - bit planes (1, 2, 4, 8, 15, 16, 24, 32)
if planes = -1, current screen planes are used
if planes is none of the above, 'count' returns 0
count - returns screen ram size in bytes required to hold the image
if count = 0, bit plane error or w/h or both are 0
6 extra bytes are always added to account for VGET/VPUT buffer sizes
If planes = 15 it's treated as 16, since the unused bit takes up space.
Examples: ' 4 planes
size%=GETSIZE(0,0,319,199,4) !-> 32006
size%=GETSIZE(319,199,0,0,4) !-> 32006 (corners reversed)
' current mode
size%=GETSIZE(0,0,319,199,-1)
If you need to calculate image buffer sizes based on w/h, do like so:
size%=GETSIZE(0,0,w&-1,h&-1)
Note: GETSIZE() with 4 parameters is unchanged.
v_opnvwk()+, vq_extnd()+, vq_scrninfo()+
VPALGET
VPALGET addr (v3.7)
VPALSET addr
addr: iexp
These commands are used to save and restore a color palette. The palette is
copied to the buffer in VDI order/format. Internally VQ_COLOR() and VS_COLOR()
are used.
Buffer layout: r0, g0, b0, r1, g1, b1, r2, g2, b2, ... (words)
Each palette entry is 6 bytes.
Example:
pal%=MALLOC(_C*6) !calc size in bytes
'
VPALGET pal% !save current palette
'
FOR i&=0 to _C-1 !go black
VSETCOLOR i&,0,0,0
NEXT i&
PAUSE 50
'
VPALSET pal% !restore palette
~MFREE(pal%)
EDIT
Alternately you could use an array:
DIM pal&(_C*3) !calc size in words
PALGET V:pal&(0)
vq_color()+, vs_color()+,
EgetPalette()+, EsetPalette()+, VgetRGB()+, VsetRGB()+
VCLS
VCLS [c] (v3.7)
c: iexp
Equivalent to CLS but calls V_BAR() instead.
Internally calls VSF_INTERIOR(solid) and VSF_COLOR(c)
The optional parameter defaults to 0 if not specified. This is the pen color
that should be used to clear the screen.
Just like CLS it does not honor CLIP OFFSET.
Note: CLS can be caught by Toswin2 were as VCLS will not.
v_bar()+, vsf_interior()+, vsf_color()+
VCURVE
VCURVE x1,y1,x2,y2,x3,y3,x4,y4 (v3.7)
x1, y1, x2, y2, x3, y3, x4, y4: iexp
VDI equivalent of CURVE using V_BEZ().
The quality of the curve can be adjusted with V_BEZ_QUAL().
Does not honor CLIP OFFSET.
v_bez()+, v_bez_qual()+
VGET
VGET x1,y1,x2,y2,adr (v3.7)
VPUT x,y,adr[,mode]
x1, y1, x2, y2, mode: iexp
adr: avar (able to hold a 32-bit value)
Equivalent to GET/PUT, but calls VRO_CPYFM() instead. These work in any mode
and there is no 32kb limit. If mode is not specified the default is 3.
Example:
adr%=MALLOC(6+BMPSIZE(-1,-1,-1))
VGET 20,20,20+w-1,20+h-1,adr%
VPUT 200,200,adr% !mode is optional (3 is the default)
VPUT 200,200,adr%,3
A 3 byte header (3 words) is added just like PUT/GET does. If the call fails
to grab a block, falls outside the screen, header planes = 0.
Image data is stored like so:
<width.w-1><height.w-1><planes.w><image-data...>
vro_cpyfm()+
VQ_VGDOS
result=VQ_VGDOS() (v3.7)
result: iexp (returns a long)
This function returns the GDOS installed.
Returns -2 if no GDOS is installed.
Example: PRINT MKL$(VQ_VGDOS())
NVDI returns: &H5F46534D -> '_FSM'
vq_gdos()+
VSGET
VSGET addr (v3.7)
VSPUT addr
addr: iexp
These commands are similar to SGET and SPUT, however they work with any screen
mode. Internally they work much the same, using a high speed memory copy. The
only difference is the parameter. To support screens over 32kb a memory block
must be used. The caller must supply a memory block large enough to hold the
screen memory. See BMPSIZE() for further information.
Example:
buf%=MALLOC(BMPSIZE(-1,-1,-1)) !create screen size buffer
'
GHIDEM
VSGET buf% ;save screen
'
PBOX 0,0,_SW-1,_SH-1 !destroy the screen
PAUSE 50 !wait a little bit
'
VSPUT buf% !restore the screen
GSHOWM
'
~MFREE(buf%)
EDIT
vro_cpyfm()+
VS_COLOR
~VS_COLOR(index,r,g,b) (v3.7)
stat=VQ_COLOR(index,flag,rout,gout,bout)
index, flag, r, g, b: iexp
stat, rout, gout, bout: ivar
These functions are for setting or inquiring palette entries. Unlike VSETCOLOR
the allowable range is 0-1000.
Variables rout, gout, and bout, must be able to store a value in the range of
0-1000.
Note: The parameter scheme was altered to eliminate the 'rgb' structure.
vs_color()+, vq_color()+
VST_POINT
stat=VST_POINT(point[,cwout,chout,wout,hout]) (v3.7)
stat, cwout, chout, wout, hout: ivar
point: iexp
This function sets the height of the current text face in points (1/72 inch).
The output parameters are optional and the results can also be found in
PTSOUT(0-3).
vst_point()+
VST_ALIGNMENT
~VST_ALIGNMENT(h,v[,hout,vout]) (v3.7)
h, v: iexp
hout, vout: ivar
This function affects the vertical and horizontal alignment of normal and
justified text.
The output variables are optional. The results can also be found in
INTOUT(0-1).
vst_alignment()+
VQT_WIDTH
index=VQT_WIDTH(ch,cout,lout,rout) (v3.7)
ch: iexp
index, cout, lout, rout: ivar
This function returns information regarding the width of a character cell.
vqt_width()+
VQT_FONTINFO
~VQT_FONTINFO(minch,maxch,maxw) (v3.7)
minch, maxch, maxw: ivar
Results can always be found in arrays INTOUT() and PTSOUT().
Note: Parameter scheme altered to eliminate structures 'dis' and 'eff'.
Example:
~VQT_FONTINFO(minch&,maxch&,maxw&)
effects&=PTSOUT(2)
vqt_fontinfo()+
V_GET_PIXEL
~V_GET_PIXEL(x&,y&[,pindex&,vindex&]) (v3.7)
x, y: iexp
pindex, vindex: ivar
This function returns the color for a specified coordinate on the screen.
POINT() doesn't work in high or true-color, use this instead.
The return parameters are optional and the results can also be found in
INTOUT(0-1).
v_get_pixel()+
VRC_COPY
VRC_COPY src,sx,sy,w,h TO dst,dx,dy[,mode] (v3.7)
src, sx, sy, w, h, dst, dx, dy, mode: iexp
Equivalent to RC_COPY but calls VDI VRO_CPYFM() instead.
Example:
VRC_COPY 0,0,0,_SW,_SH\2 TO 0,0,_SH\2,3
Copies the upper half of screen to lower half of the screen. If the source
or destination address is zero, the screen is address is assumed.
vro_cpyfm()+
V_OPNBM
vhan=V_OPNBM(mfdb,ahan) (v3.7)
~V_CLSBM()
mfdb, ahan: iexp
vhan: ivar
These commands are for managing NVDI offscreen bitmaps.
mfdb - pointer to a Memory Form Definition Block to be filled in by the call
ahan - VDI handle of the Physical Workstation use by the AES
The INTIN(0-19) array must be used to pass in the work_in values.
Work_out values can be found in arrays INTOUT(0-44) and PTSOUT(0-11) after the
call.
To close a bitmap do this:
V~H=handle
~V_CLSBM()
Afterwards V~H will be reset back to the handle opened by GFA's startup code.
Typical work_in defaults for a device specific off-screen buffer:
Index: Value:
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 2
11 screen width in pixels -> current screen
12 screen height in pixels -> current screen
13 width of pixel in microns -> current screen
14 height of pixel in microns -> current screen
15 0
16 0
17 0
18 0
19 0
v_opnbm()+, v_clsbm()+
VRO_CPYFM
~VRO_CPYFM(mode,smfdb,dmfdb) (v3.7)
~VRT_CPYFM(mode,smfdb,dmfdb,c0,c1)
~VR_TRNFM(smfdb,dmfdb)
SET.MFDB addr,screen,w,h,format,planes
SET.SXYXY sx,sy,sw,sh
SET.DXYXY dx,dy,dw,dh
SET.SXYWH sx,sy,sw,sh
SET.DXYWH dx,dy,dw,dh
SET.PXYWH sx,sy,sw,sh,dx,dy
SET.PXYXY x1,y1,x2,y2,x3,y3,x4,y4
SET.RXYWH sx,sy,sw,sh,dx,dy,dw,dh
mode, smfdb, dmfdb, colors: iexp
addr, screen, w, h, format, planes: iexp
sx, sy, sw, sh, dx, dy, dw, dh: iexp
x1, y1, x2, y2, x3, y3, x4, y4: iexp
c0, c1: iexp
VDI blit commands.
SET.MFDB - helper for creating a Memory Form Definition Block (20 bytes)
wdwidth is auto set
VDI coordinate system:
SET.SXYXY - helper for source structure PTSIN(0 to 3)
SET.DXYXY - helper for destination structure PTSIN(4 to 7)
SET.PXYXY - helper for creating a coordinate structure PTSIN(4 to 7)
AES coordinate system:
SET.SXYWH - helper for source structure PTSIN(0 to 3)
SET.DXYWH - helper for destination structure PTSIN(4 to 7)
SET.PXYWH - helper for creating a coordinate structure PTSIN(4 to 7)
SET.RXYWH - helper for creating a coordinate structure PTSIN(4 to 7)
The coordinates can also be passed in PTSIN(0-7).
Note: VRO_CYPFM() and VRT_CPYFM() parameter schemes don't follow the official
documentation. Adjusted to eliminate the 'pxy' and 'color' structures.
vro_cpyfm()+, vrt_cpyfm()+, vr_trnfm()+
VQF_ATTRIBUTES
~VQF_ATTRIBUTES() (v3.7)
~VQL_ATTRIBUTES()
~VQM_ATTRIBUTES()
~VQT_ATTRIBUTES()
Results are always found in the INTOUT() and PTSOUT() arrays.
Note: Parameter scheme doesn't match official documentation in order to
eliminate the 'attr' structure.
vqf_attributes()+, vql_attributes()+, vqm_attributes()+, vqt_attributes()+
VQ_EXTND
~VQ_EXTND(flag) (v3.7)
Results can be found in the INTOUT(0-44) and PTSOUT(0-11) arrays.
Note: Parameter scheme doesn't match official documentation in order to
eliminate the 'wout' structure.
vq_extnd()+
VQ_MOUSE
~V_HIDE_C() (v3.7)
~V_SHOW_C()
~VQ_KEY_S(sout)
~VQ_MOUSE(mk,mx,my)
vq_mouse()+, vq_key_s()+, v_hide_c()+, v_show_c()+
VS_CLIP
~VS_CLIP(flag,x1,y1,x2,y2) (v3.7)
Note: Parameter scheme modified to eliminate the 'pxy' structure.
vs_clip()+
VQ_SCRNINFO
~VQ_SCRNINFO(wout) (v3.7)
This function returns more information than GFA's INTOUT() array can handle.
It requires a valid buffer address with enough room for 272 words.
Example:
DIM work_out&(272)
~VQ_SCRNINFO(V:work_out&(0))
FOR i&=0 TO 271
PRINT work_out&(i&);" ";
NEXT i&
PRINT
vq_scrninfo()+
V_BEZ
~V_BEZ(count[,pout,mout]) (v3.7)
~V_BEZ_FILL(count[,pout,mout])
~V_BEZ_QUAL(qual,oqual)
ret=V_BEZ_ON()
~V_BEZ_OFF()
Use PTSIN() array for coordinate input.
Use INTIN() array for 'bezarr' data.
Results can be found in the PTSOUT() array.
Note: V_BEZ() and V_BEZ_FILL() parameter scheme does not match the official
documentation. This was done to eliminate the structures 'pxy',
'bezarr', and 'extent'.
v_bez()+, v_bez_fill()+, v_bez_qual()+, v_bez_on()+, v_bez_off()+
~VSC_FORM() (v3.7)
The mouse form should be passed with the INTIN(0-36) array.
Note: Parameter scheme does not match the official documentation.
vsc_form()+
VSWR_MODE
stat=VSWR_MODE(mode) (v3.7)
vswr_mode()+
V_BAR
~V_BAR(x1,y1,x2,y2) (v3.7)
~V_RBOX(x1,y1,x2,y2)
~V_RFBOX(x1,y1,x2,y2)
~VR_RECFL(x1,y1,x2,y2)
Note: Parameter scheme doesn't follow the official documentation. Adjusted to
eliminate the 'pxy' structure.
v_bar()+, v_rbox()+, v_rfbox()+, vr_recfl()+
V_GTEXT
~V_GTEXT(x,y,str$) (v3.7)
~V_JUSTIFIED(x,y,str$,len,wflag,cflag)
v_gtext()+, v_justified()+
V_PLINE
~V_PLINE(count) (v3.7)
~V_PMARKER(count)
~V_FILLAREA(count)
Note: Parameter scheme doesn't follow the official documentation. Adjusted to
eliminate the 'pxy' structure.
Coordinates should be passed with the PTSIN() array.
v_pline()+, v_pmarker()+, v_fillarea()+
V_CONTOURFILL
~V_CONTOURFILL(x,y,color) (v3.7)
v_contourfill()+
V_CIRCLE
~V_ARC(x,y,radius,sangle,eangle) (v3.7)
~V_CIRCLE(x,y,radius)
~V_PIESLICE(x,y,radius,sangle,eangle)
v_arc()+, v_circle()+, v_pieslice()+
V_ELLIPSE
~V_ELLARC(x,y,xradius,yradius,sangle,eangle) (v3.6)
~V_ELLPIE(x,y,xradius,yradius,sangle,eangle)
~V_ELLIPSE(x,y,xradius,yradius)
v_ellarc()+, v_ellpie()+, v_ellipse()+
V_CURTEXT
~V_CURTEXT(str$) (v3.7)
~VQ_CHCELLS(rows_out,columns_out)
~V_CURADDRESS(row,column)
~VQ_CURADDRESS(row_out,column_out)
~V_RVON()
~V_RVOFF()
~V_ENTER_CUR()
~V_EXIT_CUR()
~V_CURUP()
~V_CURDONW()
~V_CURRIGHT()
~V_CURLEFT()
~V_CURHOME()
~V_EEOL
~V_EEOS
~V_DSPCUR(x,y)
~V_RMCUR()
stat=VQ_TABSTATUS()
v_curtext()+, vq_chcells()+, vq_tabstatus()+,
v_curaddress()+, vq_curaddress()+,
v_rvon()+, v_rvoff()+, v_eeol()+, v_eeos()+,
v_enter_cur()+, v_exit_cur()+, v_dspcur()+, v_rmcur()+,
v_curup()+, v_curdown()+, v_curright()+, v_curleft()+, v_curhome()+
VST_COLOR
stat=VST_COLOR(ndx) (v3.7)
stat=VST_EFFECTS(effect)
stat=VST_ROTATION(angle)
~VST_HEIGHT(height[,wchar,hchar,wcell,hcell])
stat=VST_FONT(ndx)
vst_color()+, vst_effects()+, vst_rotation()+, vst_height()+, vst_font()+
VSM_COLOR
stat=VSM_COLOR(color) (v3.7)
stat=VSM_HEIGHT(height)
stat=VSM_TYPE(type)
vsm_color()+, vsm_height()+, vsm_type()+
VSF_COLOR
stat=VSF_COLOR(index) (v3.7)
stat=VSF_INTERIOR(interior)
stat=VSF_PERIMETER(flag)
stat=VSF_STYLE(style)
~VSF_UDPAT(planes)
VSF_UDPAT() parameter scheme doesn't match the official documentation.
VSF_UDPAT() expects the pattern to be passed with the INTIN() array.
vsf_color()+, vsf_interior()+, vsf_perimeter()+, vsf_style()+, vsf_udpat()+
VSL_COLOR
stat=VSL_COLOR(index) (v3.7)
stat=VSL_TYPE(type)
stat=VSL_WIDTH(width)
~VSL_ENDS(start,end)
~VSL_UDSTY(pattern)
vsl_color()+, vsl_type()+, vsl_width()+, vsl_ends()+, vsl_udsty()+
_SW
w=_SW (v3.7)
h=_SH
w, h: ivar
_SW - Returns the screen width in pixels.
_SH - Returns the screen height in pixels.
Unlike _X and _Y they never change.
Example: PRINT _SW;"x";_SH
v_opnvwk()+
VBOX
VBOX x1,y1,x2,y2 (v3.7)
VLINE x1,y1,x2,y2
VPLOT x,y
VPBAR x,y,w,h
x1, y1, x2, y2, x, y ,w, h: iexp
The VDI does not provide these as direct commands, instead one has to do a
more complex V_PLINE() call with more setup. They gain some speed by not
honoring CLIP OFFSET or remembering the last x/y coordinate used.
VBOX -> BOX
VLINE -> LINE
VPLOT -> PLOT
VPBAR -> PBOX (fastest variant of PBOX)
To speed up other stuff:
PBOX -> V_BAR() if you need x1,y1,x2,y2 coordinate system
TEXT -> V_GTEXT() or V_JUSTIFIED()
TBITBLT
TBITBLT mask_smfdb,data_smfdb,dmfdb (v3.7)
mask_smfdb, data_smfdb, dmfdb: iexp
This command is for blitting images with transparency.
mask_smfdb - source MFDB (mask)
data_smfdb - source MFDB (data)
dmfdb - destination MFDB
Internally the transparent colors are calculated like so:
c0 - color applied to all set bits in the source image
c1 - color applied to all cleared bits
c0: If _B>8 then c0=1 else c0=0
c1: Always c1=0
If you need this information:
trans_color&=ABS(_B>8)
See also TPUT.
vro_cpyfm()+, vrt_cpyfm()+
C_XBIOS
xbios_ndx=C_XBIOS(#vdi_index,pens) (v3.7)
vdi_ndx=C_VDI(#xbios_index,pens)
xbios_ndx, vdi_ndx: ivar
vdi_index, xbios_index, pens: iexp
These functions convert color ordering between XBIOS and VDI.
C_XBIOS() - VDI order to XBIOS (hardware) order.
C_VDI() - XBIOS (hardware) order to VDI order.
vdi_index/xbios_index can range from 0 to 255
extra bits are maked off, no error will be reported
pens can be 2,4,16, or 256
error #71 occurs if out of range
Lookup tables are used for maximum speed.
Examples:
' make VDI command use XBIOS (hardware) color order
COLOR C_VDI(#1,_C)
PLOT 0,0
' make Line-A command use VDI color order
PSET 0,0,C_XBIOS(#1,_C)
VR_TRANSFER_BITS
@aliAS "V_RESIZE_BM"
~VR_TRANSFER_BITS(src_bm,dst_bm,mode) (v3.7)
handle=V_OPEN_BM(screen_handle,bitmap,color_flgs,unit_flgs,pixel_width,pixel_height)
stat=V_RESIZE_BM(width,height,byte_width,addr)
stat=VR_CLIP_RECTS_BY_DST()
stst=VR_CLIP_RECTS_BY_SRC()
SET.GCBITMAP ptr,addr,px_format,width,height,ctab,itab
These functions require NVDI v5.
VR_TRANSFER_BITS() can be used to dither, scale, or transform bitmaps.
Requires NVDI 5.03 minimum as lesser versions are bugged.
SET.GCBITMAP is a helper command for creating 'gcbitmap' structures.
It may not work for all situations. Must be 64 bytes in length.
The helper commands at VRO_CPYFM() can also be used to set VR_TRANSFER_BITS()
coordinates. Using the AES coordinate system makes scaling easier.
Notes for V_OPEN_BM():
'screen_handle' should be V~H.
color_flags: &X0 = do not share color tables
&X1 = share color tables
See source to openbm demo (openbm.c) from archive nvdi5doc_ger.lzh
See also WORK.OUT()
Notes for VR_CLIP_RECTS_BY_DST() and VR_CLIP_RECTS_BY_SRC():
Rectangle coordinates should be passed in PTSIN(0 to 11)
Results can be found in PTSOUT(0 to 7)
Notes about fVDI:
fVDI can install a fake NVDI cookie, but this isn't much of a problem
since it will fail a proper raster test, see WORK.OUT().
fVDI is baked into the firmware when dealing with the Radeon add-on. It
doesn't install an fVDI cookie. However, cookies '_PCI' + 'CT60' = Radeon.
Some NVDI v5 features are incomplete. fVDI + NVDI works better, but isn't
always a 100% fix, so your mildage may vary. If you can avoid fVDI, do it!
vr_transfer_bits()+, v_open_bm()+, v_resize_bm()+,
vr_clip_rects_by_dst()+, vr_clip_rects_by_src()+
V_SETRGB
~V_SETRGB(type,red,green,blue) (v3.7)
count=VS_CTAB(ctab)
count=VS_CTAB_ENTRY(index,color_space,ce0,ce1,ce2,ce3)
count=VS_DFLT_CTAB()
stat=VQ_CTAB(length,ctab)
color_space=VQ_CTAB_ENTRY(index,oce0,oce1,oce2,oce3)
ctab_id=VQ_CTAB_ID()
vdi_index=V_CTAB_IDX2VDI(index)
index=V_CTAB_VDI2IDX(vdi_index)
value=V_CTAB_IDX2VALUE(index)
ctab_id=V_GET_CTAB_ID()
stat=VQ_DFLT_CTAB(length,ctab)
ctab=V_CREATE_CTAB(color_space,px_format)
stat=V_DELETE_CTAB(ctab)
itab=V_CREATE_ITAB(ctab,bits)
stat=V_DELETE_ITAB(itab)
These functions require NVDI v5.
Some functions were modified to avoid the color_entry structure.
v_setrgb()+,
vs_ctab()+, vs_ctab_entry()+, vs_dflt_ctab()+,
vq_ctab()+, vq_ctab_entry()+, vq_ctab_id()+,
v_ctab_idx2vdi()+, v_ctab_vdi2idx()+, v_ctab_idx2value()+,
v_get_ctab_id()+, vq_dflt_ctab()+,
v_create_ctab()+, v_delete_ctab()+, v_create_itab()+, v_delete_itab()+
VST_NAME
id=VST_NAME(font_format,font_name$,oret_name$) (v3.7)
id=VQT_EXT_NAME(index&,oname$,ofont_format,oflags)
id=VQT_NAME_AND_ID(font_format,font_name$,oret_name$)
id=VQT_XFNTINF(flags,id,index,info)
~VQT_FONTHEADER(buffer,otdf_name$)
~VST_WIDTH(width,ocell_width[,ocell_height,ochar_width,ochar_height])
These are NVDI v3 function calls.
Notes about VQT_EXT_NAME():
Extended version of VQT_NAME().
This call doesn't work exactly like it's 'C' counterpart.
It doesn't append the font type to the end of 'oname$'. Instead it's placed
in the upper byte of 'flags'. It will be either 0 or 1.
Notes about VQT_XFNTINFO():
Structure 'info' must be at least 890 bytes.
Notes about VST_WIDTH():
Doesn't work with system fonts or older bitmapped fonts.
vst_name()+, vst_width()+, vqt_ext_name()+, vqt_name_and_id()+,
vqt_xfntinfo()+, vqt_fontheader()+
V_HARDCOPY
~V_HARDCOPY() (v3.7)
~V_CLEAR_DISP_LIST()
v_hardcopy()+, v_clear_disp_list()+
VST_FG_COLOR
stat=VST_FG_COLOR(color_space,ce0,ce1,ce2,ce3) (v3.7)
stat=VSF_FG_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VSL_FG_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VSM_FG_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VSR_FG_COLOR(color_space,ce0,ce1,ce2,ce3)
color_space=VQT_FG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQF_FG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQL_FG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQM_FG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQR_FG_COLOR(oce0,oce1,oce2,oce3)
These are NVDI v5 function calls.
The functions were modified to avoid the color_entry structure.
vst_fg_color()+, vsf_fg_color()+, vsl_fg_color()+, vsm_fg_color()+,
vsr_fg_color()+
vqt_fg_color()+, vqf_fg_color()+, vql_fg_color()+, vqm_fg_color()+,
vqr_fg_color()+
VST_BG_COLOR
stat=VST_BG_COLOR(color_space,ce0,ce1,ce2,ce3) (v3.7)
stat=VSF_BG_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VSL_BG_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VSM_BG_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VSR_BG_COLOR(color_space,ce0,ce1,ce2,ce3)
color_space=VQT_BG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQF_BG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQL_BG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQM_BG_COLOR(oce0,oce1,oce2,oce3)
color_space=VQR_BG_COLOR(oce0,oce1,oce2,oce3)
These are NVDI v5 function calls.
The functions were modified to avoid the color_entry structure.
vst_bg_color()+, vsf_bg_color()+, vsl_bg_color()+, vsm_bg_color()+,
vsr_bg_color()+
vqt_bg_color()+, vqf_bg_color()+, vql_bg_color()+, vqm_bg_color()+,
vqr_bg_color()+
VS_HILITE_COLOR
stat=VS_HILITE_COLOR(color_space,ce0,ce1,ce2,ce3) (v3.7)
stat=VS_MIN_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VS_MAX_COLOR(color_space,ce0,ce1,ce2,ce3)
stat=VS_WEIGHT_COLOR(color_space,ce0,ce1,ce2,ce3)
color_space=VQ_HILITE_COLOR(oce0,oce1,oce2,oce3)
color_space=VQ_MIN_COLOR(oce0,oce1,oce2,oce3)
color_space=VQ_MAX_COLOR(oce0,oce1,oce2,oce3)
color_space=VQ_WEIGHT_COLOR(oce0,oce1,oce2,oce3)
These are NVDI v5 function calls.
The functions were modified to avoid the color_entry structure.
vs_hilite_color()+, vs_min_color()+, vs_max_color()+, vs_weight_color()+
vq_hilite_color()+, vq_min_color()+, vq_max_color()+, vq_weight_color()+
color_space=VQ_PX_FORMAT(out_px_format) (v3.7)
value=V_COLOR2VALUE(color_space,ce0,ce1,ce2,ce3)
color_space=V_VALUE2COLOR(value,oce0,oce1,oce2,oce3)
nearest_space=V_COLOR2NEAREST(color_space,ce0,ce1,ce2,ce3,oce0,oce1,oce2,oce3)
These are NVDI v5 functions.
Some functions were modified to avoid the color_entry structure.
px_format%: &X----CCCCFFFF--PP--UUUUUU--BBBBBB
| | | | |
| | | | PX_BITS
| | | PX_USED
| | PX_PACKING
| PX_FLAGS
PX_CMPNTS
vq_px_format()+, v_color2value()+, v_value2color()+, v_color2nearest()+
VEX_TIMV
~VEX_TIMV(timv,old_timv,ompt) (v3.7)
~VEX_BUTV(butv,old_butv)
~VEX_MOTV(motv,old_motv)
~VEX_CURV(curv,old_curv)
vex_timv()+, vex_butv()+, vex_motv()+, vex_curv()+
BAR
BAR x,y,w,h (v3.7)
PBAR x,y,w,h
RBAR x,y,w,h
PRBAR x,y,w,h
x, y, w, h: iexp
Similar to other graphics commands except they use width and height.
CLIP OFFSET is honored.
x - x position upper/left corner
y - y position upper/left corner
w - width in pixels
h - height in pixels
BAR -> BOX
PBAR -> PBOX
RBAR -> RBOX
PRBAR -> PRBOX
STEXT
STEXT x,y,xo,yo,bgc,text$ (v3.7)
x, y, xo, yo, bgc: iexp
text$: sexp
Draw shadowed text. CLIP OFFSET is honored. Foreground text is drawn with
the current text color as defined by DEFTEXT. The current text color is not
disturbed. GRAPHMODE 2 is the most useful.
x - x position
y - y position
xo - xo offset of shadow
yo - yo offset of shadow
bgc - shadow color (VDI color index)
text$ - text to be rendered
Positive offsets shift the shadow down/right.
Negative offsets shift the shadow up/left.
v_gtext()+
P3DBAR
P3DBAR x,y,w,h,ulc,lrc (3.7)
x, y, w, h, ulc, lrc: iexp
Draw a filled 3D box. CLIP OFFSET is honored. The filled area is drawn with
the current fill color as defined by DEFFILL. The current line color is not
disturbed.
x - x position upper/left corner
y - y position upper/left corner
w - width in pixels
h - height in pixels
ulc - upper/left edge color (VDI color index)
lrc - lower/right edge color (VDI color index)
The coordinates are the position/size of the filled box area. The borders is
is not account for and drawn relative to the box.
v_bar()+
_NVDI
version=_NVDI (v3.7)
version: ivar
This built-in variable returns the version of NVDI that's installed.
If NVDI isn't installed it returns zero.
Example:
IF _NVDI=0
PRINT "NVDI not installed!"
EDIT
ELSE IF _NVDI<&H503 !v5.03?
PRINT "NVDI is too old!"
EDIT
ENDIF
See also VER2STR.
CLUT?
flag=CLUT? (v3.7)
flag: ivar
This function detects color mapped video modes. Any mode <= 8 bit planes is
considered color mapped. Any mode > 8 planes is considered direct color.
CLUT stands for Color Look Up Table thus it has a palette.
Return value: TRUE (-1) -> bit planes: 1, 2, 4, 8 (color mapped)
FALSE (0) -> bit planes: 15, 16, 24, 32 (direct color)
It's equivalent to: clut!=_B<=8
Example:
IF CLUT?
' it's color mapped
ELSE
' it's high-color/true-color (aka direct color)
ENDIF
TRIANGLE
TRIANGLE x1,y1,x2,y2,x3,y3 (v3.7)
PTRIANGLE x1,y1,x2,y2,x3,y3
x1, y1, x2, y2, x3, y3: iexp
These commands draw a triangle in the current line color or fill color.
CLIP OFFSET is applied.
Three coordinates are needed:
2
x2,y2
/\
/ \
/ \
/______\
1 3
x1,y1 x3,y3
Points 3 & 1 are auto connected.
v_pline()+, v_fillarea()+
x=_PX_FORMAT (v3.7)
x: ivar (able to hold 32-bits)
This built-in variable returns NVDI's pixel format of the current video mode.
This will always be the video mode associated with handle V~H.
If bit #1 of WORK.OUT(30) is set, then this variable is valid.
Note: Only version 5.03 of NVDI is bug free. If the NVDI cookie exists the
version should be checked before using the new raster functions.
If the VDI isn't initialized (compiled only) it returns zero.
vq_px_format()+
WORK.OUT
x=WORK.OUT(index) (v3.7)
x: ivar
index: iexp
This built-in array returns the contents of vq_extnd(1).
This will always be the extended info associated with handle V~H.
Note: Index can be 0 to 56, anything else will throw error #71.
Compiled code does not range check the index.
Most docs list 19-56 as reserved, but NVDI adds new entries.
See NVDI v4.10 docs and NVDI 5 docs for mode details.
If the VDI isn't initialized (compiled only) all indexes return zero.
Added by NVDI:
WORK.OUT(30) bit #0 -> vro_cpyfm() supports scaling
bit #1 -> vr_transfer_bits()
bit #2 -> vr_clip_rects_xx()
WORK.OUT(32) bit #0 -> color management
vq_extnd()+
VDIPB
addr=VDIPB (v3.7)
addr: ivar (able to hold 32-bits)
Returns address of GFA's internal VDI parameter block.
VDI Function Calling Procedure+
BIOS
_TOS _CPU _FPU _MCH _CF_ _MINT
BEEP
COLDBOOT WARMBOOT
CPU020() FPU882() CPUFLUSH CPU020? FPU?
DEXIST()
DMASND? EJP?
IKBD
GETCOOKIE() SETCOOKIE() DELCOOKIE()
SUPERSCALAR() PCR?
SND?
BCONIN() BCONOUT()
BCOSTAT() BCONSTAT()
DRVMAP()
GETBPB() GETMPB()
KBSHIFT()
MEDIACH()
RWABS() LRWABS()
SETEXC()
TICKCAL()
SUPERSCALAR
old=SUPERSCALAR(mode) (v3.7)
x=PCR?
old, x: ivar
mode: iexp
These functions work with the PCR register of the 68060 processor.
SUPERSCALAR() - Allows turning on, turning off, and inquiring the state of the
superscalar bit of the PCR register. If the cpu is other than
an 060 it returns 0.
mode = 0 -> off (returns old status)
mode = 1 -> on (returns old status)
mode = -1 -> inquire (returns 0=off 1=on)
PCR? - Reads the Processor Control Register (060 only). This is useful for
reading the ID and revision information and more. If the cpu is other
than an 060 it returns 0.
See the Motorola MC68060 User's Manual for more information.
Examples:
PRINT SUPERSCALAR(-1)
PRINT "ID: ";CARD(SWAP(PCR?))
Note: These function use supervisor mode.
BEEP
BEEP (v3.7)
Play the bell sound.
Same sound that is heard when clicking outside an alert box.
Equivalent to BCONOUT(2,7).
Bconout()+
DMASND?
flag=DMASND? (v3.7)
flag=EJP?
flag: ivar
These functions return information about the hardware detected by the startup
code.
DMASND? - TRUE if 8-bit stereo DMA SouND is supported, otherwise FALSE
EJP? - TRUE if Enhanced Joystick Ports are supported, otherwise FALSE
The Cookie Jar+
GETCOOKIE
stat=GETCOOKIE(id[,dout]) (v3.7)
stat=SETCOOKIE(id,value)
stat=DELCOOKIE(id)
id, value: iexp
stat: ivar
dout: ivar (float or long only)
These functions are used to manage the system cookie jar.
GETCOOKIE() - Find and retrieve data from the system cookie jar.
Return: TRUE = 'id' found
FALSE = 'id' not found
Variable 'dout' must be capable of storing at least 32-bits.
This variable is also optional.
A null cookie is valid, in this case it returns TRUE and the
size of the cookie jar in 'dout'.
SETCOOKIE() - Add new cookie or set the value of an existing cookie.
Return: 0 = Ok - cookie added
-1 = No cookie jar or null id
-39 = Full cookie jar
DELCOOKIE() - Delete a cookie from the cookie jar.
Return: 0 = Ok - cookie removed
-1 = Full cookie jar or cookie not found or null id
Note: They first try to use a clean MiNT call, if that fails it uses the old
school method.
Example: found!=GETCOOKIE(CVL("_CPU"),cpu%)
PRINT found!,cpu% !aranym dumps: -1 40
'
naes!=GETCOOKIE(CVL("nAES")) !don't need the cookie contents
'
stat&=SETCOOKIE(CVL("DHST"),A~I)
The Cookie Jar+
CPUFLUSH
stat=CPU020() (v3.7)
stat=FPU882()
stat=FPU?
stat=CPU020?
CPUFLUSH
status: ivar
FPU? - Determines if an FPU is detected.
TRUE = Detected
FALSE = Not detected
CPU020? - Detemines if the CPU => 020.
TRUE = CPU is equal to or greater than a 68020
FALSE = CPU is 68000 or 68010
CPU020() - Activate only the CPU options.
FPU882() - Activate only the FPU options.
If the option is actually enabled it returns true, else false.
These functions allow activation of the CPU and FPU enhancements independently
of each other, unlike the TT? function.
CPUFLUSH - Flush all caches (data and instruction)
This is good for module loading schemes where the relocations are
not handled by the operating system.
These commands are safe to use on any processor and ignored if the hardware
isn't present.
Examples:
~CPU020() !ignore return value, automatically apply if available
IF CPU020?=FALSE
ALERT "Sorry, need and 020 or better!" !an asm add-on requires an 020 or up
EDIT
ENDIF
The Cookie Jar+
KBSHIFT
stat=KBSHIFT(mode) (v3.7)
Kbshift()+
DRVMAP
dmap=DRVMAP() (v3.7)
Drvmap()+
SETEXC
ovec=SETEXC(num,nvec) (v3.7)
Setexc()+
TICKCAL
msec=TICKCAL() (v3.7)
Tickcal()+
stat=MEDIACH(dev) (v3.7)
Mediach()+
GETBPB
bpb=GETBPB(dev) (v3.7)
~GETMPB(mpb)
Getbpb()+, Getmpb()+
RWABS
stat=RWABS(mode,addr,count,recno,dev) (v3.7)
stat=LRWABS(mode,addr,count,recno,dev,lrecno)
When using LRWABS() 'recno' must be set to -1.
Rwabs()+
BCONIN
stat=BCONIN(dev) (v3.7)
stat=BCONOUT(dev,chr)
Bconin()+, Bconout()+
BCOSTAT
stat=BCOSTAT(dev) (v3.7)
stat=BCONSTAT(dev)
Bcostat()+, Bconstat()+
_TOS
x=_TOS (v3.7)
x=_CPU
x=_FPU
x=_MCH
x=_CF_
x=_MINT
x=SND?
x: ivar
_TOS - Returns the TOS version. $0404 -> 4.04
_CPU - Returns the processor type, 680xx: 00 10 20 30 40 50 60
This is the contents of the _CPU cookie.
If the machine has no cookie jar, it returns 0 (assume 68000).
_MINT - Returns MiNT version in hex: $0116 -> 1.16
This function is based on the proper way to detect MiNT, thus a fake
MiNT cookie will return 0.
_FPU - Returns the contents of the _FPU cookie.
_MCH - Returns the contents of the _MCH cookie.
_CF_ - Returns the contents of the _CF_ cookie.
SND? - Returns the contents of the _SND cookie.
Example:
If _MINT !it's really MiNT? (not MagiC faking a mint cookie)
' do this
ENDIF
OS Header+, The Cookie Jar+
COLDBOOT
COLDBOOT (v3.7)
WARMBOOT
These commands will instantly restart the system without warning.
COLDBOOT - Same effect as turning on the system.
WARMBOOT - Same effect as pressing the reset button.
Warning: Any unsaved data will be lost!
IKBD
IKBD state (v3.7)
state: iexp
This function pauses/resumes mouse packet reporting.
state Description
FALSE -> off disable mouse packet reporting
TRUE -> on enable mouse packets
When off the mouse freezes in place. It can still be hidden.
Bconout()+, IKBD command codes+
DEXIST
flag=DEXIST(path$) (v3.7)
flag: ivar
This function determines if a drive exists. Only the first character is
evaluated and case doesn't matter.
Return value: does exist: TRUE (-1)
doesn't exist: FALSE (0)
Examples:
PRINT DEXIST("C:\BACON.INF")
PRINT DEXIST("C:\")
PRINT DEXIST("c")
Note: An invalid drive letter or a null string will return FALSE.
Drvmap()+
XBIOS
G~R
PALGET PALSET
SCREEN
BCONMAP()
BLITMODE() CACHECTRL()
DBMSG() PUNTAES() SSBRK()
DMAREAD() DMAWRITE()
DOSOUND()
ESETBANK() ESETCOLOR() ESETGRAY() EGETPALETTE()
ESETSMEAR() EGETSHIFT() ESETSHIFT() ESETPALETTE()
FLOPRD() FLOPWR() FLOPFMT() FLOPVER() FLOPRATE() PROTOBT()
GETREZ() SETSCREEN() LOGBASE() PHYSBASE()
GETTIME() SETTIME()
GIACCESS() ONGIBIT() OFFGIBIT()
INITMOUS()
IOREC() IKBDWS() MIDIWS()
JDISINT() JENABINT() MFPINT() XBTIMER()
KEYTBL() KBRATE() KBDVBASE() BIOSKEYS()
NVMACCESS()
RANDOM%()
SETCOLOR() SETPALETTE()
SCRDMP() SETPRT() PRTBLK() CURSCONF() RSCONF()
SOUNDCMD() SETBUFFER() DEVCONNECT() SETINTERRUPT() BUFFPTR()
SNDSTATUS() LOCKSND() UNLOCKSND() SETMONTRACKS() SETMODE()
SETTRACKS() BUFFOPER() DSPTRISTATE() GPIO()
SUPEXEC()
VSETMODE() VGETSIZE() VCHECKMODE() VGETMONITOR() VGETRGB() VSETRGB()
VSETSYNC() VSETMASK() VSETSCREEN()
WAKETIME()
VSYNC()
DSP_DOBLOCK() DSP_BLKHANDSHAKE() DSP_BLKUNPACKED()
DSP_INSTREAM() DSP_OUTSTREAM() DSP_IOSTREAM()
DSP_REMOVEINTERRUPTS() DSP_GETWORDSIZE() DSP_LOCK()
DSP_UNLOCK() DSP_AVAILABLE() DSP_RESERVE()
DSP_LOADPROG() DSP_EXECPROG() DSP_EXECBOOT()
DSP_LODTOBINARY() DSP_TRIGGERHC() DSP_REQUESTUNIQUEABILITY()
DSP_GETPROGABILITY() DSP_FLUSHSUBROUTINES() DSP_LOADSUBROUTINE()
DSP_INQSUBRABILITY() DSP_RUNSUBROUTINE() DSP_HF0()
DSP_HF1() DSP_HF2() DSP_HF3()
DSP_BLKWORDS() DSP_BLKBYTES() DSP_HSTAT()
DSP_SETVECTORS() DSP_MULTBLOCKS()
CT60_CACHE() CT60_FLUSH_CACHE() CT60_READ_CORE_TEMPERATURE()
CT60_VMALLOC() CT60_RW_PARAMETER()
RANDOM%
rnd=RANDOM%() (v3.7)
rnd: ivar
This function is equivalent to calling xbios function random(). It returns a
24-bit random integer.
Note: Function name was altered because v3.6 already used the name "RANDOM()".
Random()+
DOSOUND
oldadr=DSOUND(newadr) (v3.7)
Dosound()+
BLITMODE
stat=BLITMODE(mode) (v3.7)
stat=CACHECTRL(opcode,param)
Blitmode()+, CacheCtrl()+
GETREZ
x=G~R (v3.7)
mode=GETREZ()
~SETSCREEN(ladr,padr,rez)
addr=LOGBASE()
addr=PHYSBASE()
G~R - Returns the mode code when the program was started.
Obtained from GETREZ().
Command VSYNC calls Vsync().
Getrez()+, Setscreen()+, Logbase()+, Physbase()+, Vsync()+
WAKETIME
stat=WAKETIME(datime) (v3.7)
Waketime()+
BCONMAP
stat=BCONMAP(dev) (v3.7)
Bconmap()+
GIACCESS
stat=GIACCESS(data,reg) (v3.7)
~ONGIBIT(mask)
~OFFGIBIT(mask)
One possible use, controlling the TT030 internal speaker:
OFFGIBIT(&HBF) !Turn on Speaker
ONGIBIT(&H40) !Turn off Speaker
Giaccess()+, Ongibit()+, Offgibit()+
NVMACCESS
stat=NVMACCESS(op,start,count,addr) (v3.7)
50 bytes of ram, only 0 to 47 can be accessed.
The last 2 bytes are the checksum.
NVMaccess()+
SUPEXEC
stat=SUPEXEC(addr) (v3.7)
Supexec()+
SETPALETTE
orgb=SETCOLOR(ndx,nrgb) (v3.7)
~SETPALETTE(addr)
Setcolor()+, Setpalette()+
GETTIME
time=GETTIME() (v3.7)
~SETTIME(time)
Gettime()+, Settime()+
DMAREAD
stat=DMAREAD(sector,count,addr,dev) (v3.7)
stat=DMAWRITE((sector,count,addr,dev)
DMAread()+, DMAwrite()+
JDISINT
~JDISINT(int) (v3.7)
~JENABINT(int)
~MFPINT(intno,vector)
~XBTIMER(timer,control,data,hand)
Jdisint()+, Jenabint()+, Mfpint()+, Xbtimer()+
SETPRT
~SCRDMP() (v3.7)
stat=SETPRT(conf)
stat=PRTBLK(blk)
stat=RSCONF(speed,flow,usr,rsr,tst,scr)
stat=CURSCONF(func,rate)
Scrdmp()+, Setprt()+, Prtblk()+, Rsconf()+, Cursconf()+
IOREC
addr=IOREC(dev) (v3.7)
~IKBDWS(size,addr)
~MIDIWS(size,addr)
Iorec()+, Ikbdws()+, Midiws()+
KEYTBL
addr=KEYTBL(unshift,shift,capslock) (v3.7)
stat=KBRATE(init,repeat)
addr=KBDVBASE()
~BIOSKEYS()
Keytbl()+, Kbrate()+, Kbdvbase()+, Bioskeys()+
FLOPRD
stat=FLOPRD(addr,res,dev,sector,track,side,count) (v3.7)
stat=FLOPWR(addr,res,dev,sector,track,side,count)
stat=FLOPFMT(addr,skew,dev,spt,track,side,intlv,magic,virgin)
stat=FLOPVER(addr,res,dev,sector,track,side,count)
stat=FLOPRATE(dev,rate)
~PROTOBT(addr,snum,type,eflag)
Floprd()+, Flopwr()+, Flopfmt()+, Flopver()+, Floprate()+, Protobt()+
ESETBANK
obank=ESETBANK(nbank) (v3.7)
ocolor=ESETCOLOR(ndx,ncolor)
gbit=ESETGRAY(mode)
sbit=ESETSMEAR(mode)
mode=EGETSHIFT()
omode=ESETSHIFT(nmode)
~EGETPALETTE(start,count,addr)
~ESETPALETTE(start,count,addr)
EsetBank()+, EsetColor()+, EsetGray()+, EsetSmear()+, EgetShift()+,
EsetShift()+, EgetPalette()+, EsetPalette()+
VSETMODE
old=VSETMODE(mode) (v3.7)
size=VGETSIZE(mode)
mon=VGETMONITOR()
stat=VCHECKMODE(mode)
~VGETRGB(index,count,addr)
~VSETRGB(index,count,addr)
~VSETMASK(ormask,andmask,overlay)
~VSETSYNC(flag)
old=VSETSCREEN(ladr,padr,rez,mode)
VsetMode()+, VgetSize()+, VgetMonitor()+, VcheckMode()+, VgetRGB()+,
VsetRGB()+, VsetMask()+, VsetSync()+, VsetScreen()+
SOUNDCMD
x=SOUNDCMD(mode,data) (v3.7)
x=SETMODE(mode)
x=BUFFOPER(mode)
x=BUFFPTR(ptr)
x=DEVCONNECT(src,dst,clk,pscale,proto)
x=DSPTRISTATE(xmit,rec)
x=GPIO(mode,data)
x=LOCKSND()
x=UNLOCKSND()
x=SETBUFFER(mode,sadr,eadr)
x=SETMONTRACKS(track)
x=SETTRACKS(play,rec)
x=SNDSTATUS(reset)
x=SETINTERRUPT(mode,cause)
Soundcmd()+, Setmode()+, Buffoper()+, Buffptr()+, Devconnect()+,
Dsptristate()+, Gpio()+, Locksnd()+, Unlocksnd()+, Setbuffer()+,
Setmontracks()+, Settracks()+, Sndstatus()+, Setinterrupt()+
CT60_CACHE
stat=CT60_CACHE(mode) (v3.7)
stat=CT60_FLUSH_CACHE()
temp=CT60_READ_CORE_TEMPERATURE(type)
stat=CT60_RW_PARAMETER(mode,type,value)
addr=CT60_VMALLOC(mode,value)
ct60_cache()+, ct60_flush_cache()+, ct60_read_core_temperature()+,
ct60_rw_parameter()+, ct60_vmalloc()+
PALGET
PALGET addr (v3.7)
PALSET addr
addr: iexp (capable of holding 32-bits)
These commands allow easy saving and restoring of color palettes. Unlike
VPALGET and VPALSET these variants use the Xbios palette format and are
compatible with many image file formats, such as Degas. These are only
usable for the original ST/STe video modes. Supports a maximum of 16 colors.
Internally they are based on Xbios function Setcolor.
Regardless of the video mode the buffer should always be 16 words in size.
Example:
' save the current color platte to an array
DIM pal&(16) !16 words
PALGET V:pal&(0)
' set palette of uncompressed degas image
INLINE pic%,32034
SETPAL pic%+2 !skip mode code (word)
Setcolor()+, EgetPalette()+, EsetPalette()+, VgetRGB()+, VsetRGB()+
SCREEN
SCREEN mode (v3.7)
mode: iexp
This command changes the screen mode. See Xbios function Setsceen for a list
of values for parameter mode.
Note: It's up to the coder to use correct values for the hardware. No checks
are made on the value passed to this command. This command only changes
the screen mode and does not reallocate the screen buffer. The new mode
will use the old screen buffer. If the new mode requires a larger screen
buffer this command isn't suitable and SETSCREEN() should be called
directly.
Setscreen()+, VsetScreen()+, VsetMode()+
VSYNC
~VSYNC() (v3.7)
Same as command VSYNC.
DSP_DOBLOCK
~DSP_DOBLOCK(data_in,size_in,data_out,size_out) (v3.7)
~DSP_BLKHANDSHAKE(data_in,size_in,data_out,size_out)
~DSP_BLKUNPACKED(data_in,size_in,data_out,size_out)
~DSP_INSTREAM(data_in,block_size,num_blocks,blocks_done)
~DSP_OUTSTREAM(data_in,block_size,num_blocks,blocks_done)
~DSP_IOSTREAM(data_in,data_out,block_insize,block_outsize,num_blocks,blocks_done)
~DSP_REMOVEINTERRUPTS(mask)
~DSP_GETWORDSIZE()
~DSP_LOCK()
~DSP_UNLOCK()
~DSP_AVAILABLE(xavail,yavail)
~DSP_RESERVE(xreserve,yreserve)
~DSP_LOADPROG(file$,ability,buf)
~DSP_EXECPROG(codeptr,codesize,ability)
~DSP_EXECBOOT(codeptr,codesize,ability)
~DSP_LODTOBINARY(file$,codeptr)
~DSP_TRIGGERHC(vector)
~DSP_REQUESTUNIQUEABILITY()
~DSP_GETPROGABILITY()
~DSP_FLUSHSUBROUTINES()
~DSP_LOADSUBROUTINE(ptr,size,ability)
~DSP_INQSUBRABILITY(ability)
~DSP_RUNSUBROUTINE(handle)
~DSP_HF0(flag)
~DSP_HF1(flag)
~DSP_HF2()
~DSP_HF3()
~DSP_BLKWORDS(data_in,size_in,data_out,size_out)
~DSP_BLKBYTES(data_in,size_in,data_out,size_out)
~DSP_HSTAT()
~DSP_SETVECTORS(receiver,transmitter)
~DSP_MULTBLOCKS(numsend,numreceive,sendblks,receiveblks)
Dsp_DoBlock()+, Dsp_BlkHandShake()+, Dsp_BlkUnpacked()+,
Dsp_InStream()+, Dsp_OutStream()+, Dsp_IOStream()+,
Dsp_RemoveInterrupts()+, Dsp_GetWordSize()+, Dsp_Lock()+,
Dsp_Unlock()+, Dsp_Available()+, Dsp_Reserve()+,
Dsp_LoadProg()+, Dsp_ExecProg()+, Dsp_ExecBoot()+,
Dsp_LodToBinary()+, Dsp_TriggerHC()+, Dsp_RequestUniqueAbility()+,
Dsp_GetProgAbility()+, Dsp_FlushSubroutines()+, Dsp_LoadSubroutine()+,
Dsp_InqSubrAbility()+, Dsp_RunSubroutine()+, Dsp_Hf0()+,
Dsp_Hf1()+, Dsp_Hf2()+, Dsp_Hf3()+,
Dsp_BlkWords()+, Dsp_BlkBytes()+, Dsp_HStat()+,
Dsp_SetVectors()+, Dsp_MultBlocks()+
INITMOUS
~INITMOUS(mode,param,hand) (v3.7)
Initmous()+
DBMSG
~DBMSG(rsrvd,msg_num,msg_arg$) (3.7)
~PUNTAES()
addr=SSBRK(len)
Dbmsg()+, Puntaes()+, Ssbrk()+
GEMDOS
_GEMDOS
ALLOC() CALLOC() REALLOC()
CMDLINE$
CURDIR$
DTA
ENVIRON (cmd) ENVIRON (fnc) ENVIRON$()
F_BGET() F_BPUT()
F_BSAVE() F_BLOAD()
F_CREAD() F_CWRITE() F_PREAD() F_PWRITE()
F_EOF() F_LOC() F_LOF()
F_INP() F_INP&() F_INP%() F_OUT() F_OUT&() F_OUT%()
F_INPUT() F_OUTPUT()
F_LINE_INPUT() F_LINE_OUTPUT()
F_OPEN() F_CLOSE()
F_SEEK() F_RELSEEK() F_ENDSEEK()
FEXIST()
FILELEN() FILECOPY() FILES()
LOADMEM() LOADSTR()
P~I
SET.SOCKADDR_IN
SUPER (cmd) SUPER?
TIMESTAMP$() DATE$() TIME$() DATE() TIME()
YEAR() MONTH() DAY() HOUR24() MINUTE() SECOND()
WEEKDAY() WEEK() DAYNO() LEAP() HOUR12() MERIDIEM()
CCONIN() CCONOUT() CAUXIN() CAUXOUT() CPRNOUT()
CCONIS() CCONOS() CAUXIS() CAUXOS() CPRNOS()
CCONRS() CCONWS() CRAWIO() CRAWCIN() CNECIN()
DFREE%()
DCREATE() DDELETE()
DGETDRV() DSETDRV()
DGETPATH() DSETPATH() DGETCWD()
DLOCK() FLOCK()
DOPENDIR() DREADDIR() DREWINDDIR() DCLOSEDIR() DXREADDIR()
DPATHCONF() DCNTL() DCHROOT()
DWRITELABEL() DREADLABEL()
FATTRIB() FDATIME() FXATTR() FSTAT64() FFSTAT64()
FCHDIR() FFDOPENDIR() FDIRFD()
FCHMOD() FCHOWN() FFCHMOD() FFCHOWN() FCHOWN16()
FDELETE() FRENAME()
FDUP() FFORCE()
FGETCHAR() FPUTCHAR()
FINSTAT() FOUTSTAT() FCNTL() FSELECT() FPOLL()
FOPEN() FCLOSE() FREAD() FWRITE() FCREATE()
FPIPE() FMIDIPIPE() PMSG() PSEMAPHORE()
FREADLINK() FLINK() FSYMLINK()
FREADV() FWRITEV()
FSEEK()
FSOCKET() FSOCKETPAIR() FACCEPT() FCONNECT() FBIND()
FSHUTDOWN() FGETSOCKOPT() FGETPEERNAME() FGETSOCKNAME() FLISTEN()
FRECVMSG() FSENDMSG() FRECVFROM() FSENDTO() FSETSOCKOPT()
MXALLOC() MACCESS() MVALIDATE() SREALLOC() MADDALT()
PDOMAIN()
PEXEC() PFORK() PVFORK()
PGETAUID() PSETAUID() PSETREUID() PSETREGID()
PGETEUID() PSETEUID() PGETEGID() PSETEGID()
PGETGID() PSETGID() PGETUID() PSETUID()
PGETPGRP() PSETPGRP() PGETGROUPS() PSETGROUPS()
PGETPID() PGETPPID()
PNICE() PRENICE() PGETPRIORITY() PSETPRIORITY()
PRUSAGE() SUPTIME() PSETLIMIT() PUSRVAL()
PSIGNAL() PKILL() PAUSE() PTRACE() TSETITIMER()
PSIGBLOCK() PSIGSETMASK() PSIGPENDING() PSIGPAUSE() PSIGACTION()
PSYSCTL()
PUMASK()
PTERM() PTERM0() PTERMRES()
PWAIT() PWAIT3() PWAITPID()
SALERT()
SHUTDOWN() FSYNC() SYNC()
SLBOPEN() SLBCLOSE()
SVERSION()
SUPER()
SYIELD()
SYSCONF() SSYSTEM()
TADJTIME() TGETTIMEOFDAY() TSETTIMEOFDAY()
TALARM() TMALARM()
TGETDATE() TGETTIME() TSETDATE() TSETTIME()
One thing you notice in most medium to large projects is many gemdos() I\O
bindings to avoid the built in error handler. To address this issue a complete
set of alternate F_xxx I/O functions are available. These should cover most
needs and eliminate the extra bindings.
These commands are meant to be familiar and more intuitive than the OS
equivalent.
All F_xxx functions can be freely intermixed with the OS Fxxx calls.
They are built entirely on gemdos() calls.
Mimic GFA or Typical GEMDOS()
fhan&=F_OPEN("o",path$) or fhan&=FOPEN(path$,mode&)
stat&=F_BPUT(fhan&,addr%,count%) or stat&=FWRITE(fhan&,count%,addr%)
stat&=F_OUT%(fhan&,test%) or stat&=FWRITE(fhan&,4,V:test%)
stat&=F_SEEK(fhan&,offset%) or stat&=FSEEK(fhand&,offset%,mode&)
~F_CLOSE(fhan&) or ~FCLOSE(fhand&)
None of the F_xxx functions will invoke the built in error handler. It's
entirely up to the coder to manage potential error codes.
An explanation of gemdos return values as they relate to fread() and fwrite().
These functions should return the count that was passed in if successful.
This scheme also applies to all F_xxx commands that are built upon fread()
and fwrite().
Examples for fwrite(), count is 1024:
...returns 1024, write was successful
...returns 0 to 1023 indicates a disk full condition
...returns < 0 are standard gemdos error codes
Examples for fread(), count is 1024:
...returns 1024, read was successful
...returns 0 to 1023 indicates file being read might be abnormally short
...returns < 0 are standard gemdos error codes
Thus:
F_OUT() F_INP() should return 1 as only 1 byte is written/read
F_OUT&() F_INP&() should return 2 ...
F_OUT%() F_INP%() should return 4 ...
F_OPEN
fhan=F_OPEN(mode$,path$) (v3.7)
stat=F_CLOSE(handle)
stat: ivar
handle: iexp
mode$, path$: sexp
F_OPEN()/F_CLOSE() are a replacements for the built in OPEN/CLOSE, but they
work with standard gemdos handles.
mode$ works just like you would expect. (case doesn't matter)
"I" input
"O" output
"U" update
"A" append
Invalid modes will return -21. Mode "R" is not supported. All other errors
will be standard gemdos error codes.
These commands will not invoke the built in error handler, its up to the coder
to manage all potential errors based on the return value.
Example:
t$="GFABASIC"
fhan&=F_OPEN("o","u:\ram\test.dat")
IF fhan&<0
PRINT "something went wrong, error code: ";fhan&
EDIT
ENDIF
~F_BPUT(fhan&,V:t$,LEN(t$))
~F_CLOSE(fhan&)
Fopen()+, Fclose()+
F_SEEK
stat=F_SEEK(fhan,offset) (v3.7)
stat=F_RELSEEK(fhan,offset)
stat: ivar
fhan, offset: iexp
These are GEMDOS replacements for SEEK and RELSEEK. They are provided for those
that prefer the built in I/O commands.
These commands will not invoke the built in error handler, its up to the coder
to manage all potential errors based on the return value.
Fseek()+
DFREE%
stat=DFREE%(addr,drv) (v3.7)
stat: ivar
addr, drv: iexp
Equivalent to calling gemdos function Dfree(). Returns a diskinfo structure.
addr - pointer to a buffer at least 12 bytes in size
drv - drive to inquire about
0 = current gemdos drive, 1 = A, 2 = B, ...
Note: Function name was altered because v3.6 already used the name "DFREE()".
Dfree()+
F_BGET
stat=F_BGET(fhan,addr,count) (v3.7)
stat=F_BPUT(fhan,addr,count)
stat: ivar
fhan, addr, count: iexp
These are GEMDOS replacements for BGET and BPUT. They are provided for those
that prefer the built in I/O commands. They directly call fread() and fwrite().
fhan - gemdos file handle
addr - buffer address
count - size in bytes
stat - returns the same value as 'count' if successful
=>0 success (ok)
<0 standard gemdos error code (failed)
These commands will not invoke the built in error handler, its up to the coder
to manage all potential errors based on the return value.
Fread()+, Fwrite()+
F_BSAVE
stat=F_BSAVE(path$,addr,count) (v3.7)
stat=F_BLOAD(path$,addr)
path$: sexp
addr, count: iexp
These are GEMDOS replacements for BSAVE and BLOAD. They are provided for those
that prefer the built in I/O commands.
The return value should be the same as count going in, if successful or a
standard gemdos error code.
These functions will not invoke the built in error handler, its up to the coder
to manage all potential errors based on the return value.
path$ - path to file
addr - buffer address
count - size in bytes
stat - returns number of bytes read or written if successful
=>0 success (ok)
<0 standard gemdos error code (failed)
Example:
INLINE addr%,256
stat=F_BSAVE("u:\ram\test.dat",addr%,256)
IF stat<0
PRINT "error code: ";stat
ELSE
PRINT "saved ok"
ENDIF
In the above example it could return a positive number from 0 to 255 as well.
This would indicate a disk full condition.
Fopen()+, Fclose()+, Fread()+, Fwrite()+
F_EOF
stat=F_EOF(fhan) (v3.7)
pos=F_LOC(fhan)
len=F_LOF(fhan)
stat, pos, len: ivar
fhan: iexp
These are GEMDOS based replacements for EOF(), LOC(), and LOF().
F_EOF() returns true and false just like the built EOF() but works with gemdos
handles.
These commands will not invoke the built in error handler, its up to the coder
to manage all potential errors based on the return value.
Fseek()+
stat=F_OUTPUT(fhan,sin$) (v3.7)
stat=F_INPUT(fhan,count,sout$)
fhan, count: iexp
sin$: sexp
sout$: svar
These functions are for reading and writing raw data via gemdos handles. They
are limited to the maximum string length of 32767 bytes.
F_OUTPUT() - return value should be LEN(sin$), otherwise it failed
F_INPUT() - return value should be 'count', otherwise it failed
error code #-1 indicates count>32767
These functions will not invoke the built in error handler, its up to the coder
to manage potential errors based on the return value.
Examples:
Assuming t$="test"...
stat=F_OUTPUT(fhan,t$) -> PRINT #1;t$;
Assuming we read t$ back in...
stat=F_INPUT(fhan,4,t$) -> t$=INPUT$(4,#1)
Fopen()+, Fclose()+, Fread()+, Fwrite()+
stat=F_LINE_OUTPUT(fhan,sin$) (v3.7)
stat=F_LINE_INPUT(fhan,sout$)
fhan: iexp
sin$: sexp
sout$: svar
These functions are for reading and writing ASCII files via gemdos handles.
They are limited to 256 characters maximum including the line endings.
F_LINE_OUTPUT() - writing DOS style ASCII files
return value should be LEN(sin$)+2, otherwise it failed
the +2 accounts for the added cr/lf
error code #-1 signals string len>256
F_LINE_INPUT() - reading DOS or Unix style ASCII files
positive return values should be:
UNIX: LEN(sout$)+1, else it failed
DOS: LEN(sout$)+2, else it failed
negative return values (error codes):
#-11 signals eof, missing cr/lf on the last line of file
sout$ still returns the line
#-1 signals string len>256
sout$ is unchanged as the resulting string won't fit
DOS style: lines ending with cr/lf (ASCII 13/10)
Unix style: lines ending with lf (ASCII 10)
These functions will not invoke the built in error handler, its up to the coder
to manage potential errors based on the return value.
Examples:
Assuming t$="test"...
stat=F_LINE_OUTPUT(fhan,t$) -> PRINT #1;t$
Assuming we read t$ back in...
stat=F_LINE_INPUT(fhan,t$) -> LINE INPUT #1;t$
Fread()+, Fwrite()+
PREAD
PWRITE #channel,sout$ (v3.7)
PREAD #channel,sin$
stat=F_PWRITE(fhan,sout$)
stat=F_PREAD(fhan,sint$)
channel, fhan: iexp
sin$: svar
sout$: sexp
These functions read and write Pascal style strings.
Via channel numbers:
PWRITE - this command could invoke the built in error handler
PREAD - this command could invoke the built in error handler
Via Gemdos handles:
F_PWRITE() - return value should be LEN(sin$)+2, otherwise it failed
the +2 accounts for the size word stored with the string
F_PREAD() - return value should be positive, otherwise it failed, LEN(sout$)+2
the +2 accounts for the size word stored with the string
error code #-1 signals string too long (maximum 32767 characters)
triggers GFA error handler if string request exceeds string ram
These functions won't invoke the built in error handler, it's up
to the coder to manage any errors based on the return value.
The format of a Pascal string:
MKI$(length)+"text"
In situations where human readable data isn't required, this storage method is
faster than 'string+cr/lf'. Use the same space as the normal cr/lf format.
Examples:
Assuming t$="test"...
stat=F_PWRITE(fhan,t$) -> OUT& #1,LEN(t$)
PRINT #1;t$;
Assuming we read t$ back in...
stat=F_PREAD(fhan,t$) -> b&=INP&(#1)
t$=INPUT$(b&,#1)
Fread()+, Fwrite()+
F_INP
stat=F_INP(fhan,bout) (v3.7)
stat=F_INP&(fhan,wout)
stat=F_INP%(fhan,lout)
stat=F_OUT(fhan,b)
stat=F_OUT&(fhan,w)
stat=F_OUT%(fhan,l)
stat, bout, wout, lout: ivar
fhan, b, w, l: iexp
These function mimic INP() and OUT, but use gemdos handles.
The return value is the result of fread() or fwrite(), expect 1, 2, or 4 or a
gemdos error code.
These functions will not invoke the built in error handler, its up to the coder
to manage all potential errors based on the return value.
Fread()+, Fwrite()+, Fputchar()+, Fgetchar()+
ALLOC
addr=ALLOC(size,type,mp) (v3.7)
size, type, mp: iexp
This is a special variant of MALLOC() and MXALLOC(), which is designed to be
idiot proof.
size - size in byte to allocate
type - memory type:
0 = only ST ram
1 = only fast ram
2 = either, prefer ST ram
3 = either, prefer fast ram
if type > 3 error #71 is issued
mp - memory protection:
0 = refer to program header flags
1 = private
2 = global
3 = supervisor mode only access
4 = read only access
if mp > 4 error #71 is issued
It does the following:
check gemdos version
if mxalloc() not supported, ignores type/mp and calls malloc()
mxalloc() is supported, it checks for MiNT
if MiNT is found, mp is taken into account and used
if MiNT isn't found, mp is ignored and only type is used
It auto falls back to malloc() if mxalloc() is not available. Most importantly
the memory protection parameter is ignored if the OS isn't MiNT.
Those extra bits seem to cause problems on non MiNT setups. Simply code your
application as if its for MiNT and let the library handle dropping the
protection bits for you. A lot less work for you. ;o)
Malloc()+, Mxalloc()+
_GEMDOS
x=_GEMDOS (v3.7)
x=_PID
x=DTA
x=SVERSION()
x: ivar
SVERSION() - Returns the GEMDOS version.
The major and minor values are swapped!
FreeMiNT example: SVERSION() -> $4000
_GEMDOS - Returns the GEMDOS version auto corrected.
FreeMiNT example: _GEMDOS -> $0040 (0.40)
P~I - Returns callers current Process ID. (same as PGETPID())
Returns -32 if not running under MiNT.
DTA - Returns the Disk Transfer Address. The startup code has already
allocated this buffer and this built in variable always points to it.
It has a dedicated 44 byte buffer.
Example:
PRINT DTA,FGETDTA() -> prints the same address
~FSETDTA(new_addr%)
' some code, then later to restore it
~FSETDTA(DTA)
' or
~FSFIRST("u:\ram\*.*",&X0)
name$=CHAR{DTA+30} !file name
Sversion()+, Pgetpid()+, DTA+
MXALLOC
addr=MXALLOC(size,type) (v3.7)
stat=MACCESS(start,size,mode)
stat=MVALIDATE(pid,start,size,flags_out)
addr=SREALLOC(size)
stat=MADDALT(start,size)
Note: SREALLOC() should never be used in user applications.
For use by the operating system or auto folder programs only.
Mxalloc()+, Malloc()+, Maccess()+, Mvalidate()+, Srealloc()+, Maddalt()+
FSEEK
stat=FSEEK(offset,hand,mode) (v3.7)
Fseek()+
FOPEN
hand=FOPEN(file$,mode) (v3.7)
stat=FCLOSE(hand)
stat=FREAD(hand,size,addr)
stat=FWRITE(hand,size,addr)
hand=FCREATE(file$,attr)
Fopen()+, Fclose()+, Fread()+, Fwrite()+, Fcreate()+
PDOMAIN
stat=PDOMAIN(dom) (v3.7)
Pdomain()+
DPATHCONF
stat=DPATHCONF(name$,mode) (v3.7)
stat=DCNTL(cmd,name$,arg)
stat=DCHROOT(path$)
Dpathconf()+, Dcntl()+, Dchroot()+
FLOCK
stat=FLOCK(fhan,mode,start,length) (v3.7)
stat=DLOCK(mode,drv)
old=PUMASK(new)
Flock()+, Dlock()+, Pumask()+
SUPER
ostack=SUPER(stack) (v3.7)
status=SUPER?
SUPER mode
ostack: ivar (must be 32-bits)
status: ivar
mode: iexp
SUPER() function - Standard Gemdos call
SUPER? function - Inquire current processor state
Returns: FALSE (0) -> User mode
TRUE (-1) -> Supervisor mode
SUPER command - Set processor state
mode: TRUE (-1) -> Supervisor mode
FALSE (0) -> User mode
Note: Internally saves and restores the stack.
Silently ignored if called out of order or accidently called twice.
Do not mix the SUPER command with the standard Gemdos call. Use one or
the other, but never both.
Example: PRINT SUPER? !-> 0
SUPER TRUE
PRINT SUPER? !-> -1
SUPER FALSE
PRINT SUPER? !-> 0
Super()+
PEXEC
stat=PEXEC(mode,name,cmd,env) (v3.7)
pid=PFORK()
pid=PVFORK()
Pexec()+, Pfork()+, Pvfork()+
SYIELD
stat=SYIELD() (v3.7)
Always returns 0.
Syield()+
SHUTDOWN
~SHUTDOWN(mode) (v3.7)
stat=SYNC()
stat=FSYNC()
Note: SYNC() always returns 0.
Shutdown()+, Sync()+, Fsync()+
PSYSCTL
stat=PSYSCTL(p1,p2,p3,p4,p5,p6) (v3.7)
Good luck finding docs on this one!
Psysctl()+
SYSCONF
stat=SYSCONF(n) (v3.7)
stat=SSYSTEM(mode,arg1,arg2)
Sysconf()+, Ssystem()+
FDELETE
stat=FDELETE(path$) (v3.7)
stat=FRENAME(res,old$,new$)
Fdelete()+, Frename()+
FGETCHAR
chr=FGETCHAR(fhan,mode) (v3.7)
stat=FPUTCHAR(fhan,chr,mode)
Fgetchar()+, Fputchar()+
FDUP
fhand=FDUP(shand) (v3.7)
stat=FFORCE(shand,nhand)
Fdup()+, Fforce()+
DGETDRV
stat=DGETDRV() (v3.7)
stat=DSETDRV(drive)
Dgetdrv()+, Dsetdrv()+
DCREATE
stat=DCREATE(path$) (v3.7)
stat=DDELETE(path$)
Dcreate()+. Ddelete()+
DGETPATH
stat=DGETPATH(pout$,drv) (v3.7)
stat=DSETPATH(path$)
stat=DGETCWD(drv,pout$)
DGETCWD() uses a larger internal buffer than DGETPATH().
Dgetpath()+, Dsetpath()+, Dgetcwd()+
FATTRIB
stat=FATTRIB(file$,flag,attr) (v3.7)
stat=FDATIME(addr,fhan,flag)
stat=FXATTR(flag,file$,xattr)
stat=FSTAT64(flag,name$,stat)
stat=FFSTAT64(fd,stat)
Note: FATTRIB() gives mixed results for the root of a drive. Only seems
reliable under MiNT. Use DRVMAP() to test if a drive exists.
Fattrib()+, Fdatime()+, Fxattr()+, Fstat64()+, Ffstat64()+
FINSTAT
stat=FINSTAT(fhand) (v3.7)
stat=FOUTSTAT(fhan)
stat=FCNTL(fhand,arg,cmd)
stat=FSELECT(tout,rfds,wfds,res)
stat=FPOLL(fds,nfds,timeout)
FPOLL(): See sys\poll.h for a list of valid bits.
Finstat()+, Foutstat()+, Fcntl()+, Fselect()+, Fpoll()+
TGETDATE
date=TGETDATE() (v3.7)
time=TGETTIME()
stat=TSETDATE(date)
stat=TSETTIME(time)
Tgetdate()+, Tgettime()+, Tsetdate()+, Tsettime()+
SALERT
stat=SALERT(msg$) (v3.7)
Note: Always returns 0 (E_OK).
Salert()+
FCHMOD
stat=FCHMOD(path$,mode) (v3.7)
stat=FCHOWN(path$,uid,gid)
stat=FFCHMOD(fd,mode)
stat=FFCHOWN(fd,uid,gid)
stat=FCHOWN16(name$,uid,gid,flag)
Fchmod()+, Fchown()+, Ffchmod()+, Ffchown()+, Fchown16()+
PTERM
~PTERM(retcode) (v3.7)
~PTERM0()
~PTERMRES(keep,retcode)
PTERM() - Equivalent to command: SYSTEM retcode
PTERM0() - Equivalent to command: EDIT
PTERMRES() - This call is usable from GFA, however if you write a TSR the core
of the TSR or routine to be called from an external application
must be written in assembler.
Note: This call also works in the interpreter, however the
interpreter itself becomes the TSR.
Pterm()+, Pterm0()+, Ptermres()+
DATE$
out$=DATE$(in) (v3.7)
out$=TIME$(in)
in: iexp
out$: svar
These commands convert Gemdos date and times to human readable text.
The output format is based on the current MODE setting.
DATE$() converts Gemdos dates
If 'in' = '-1' the current Gemdos date is used.
TIME$() converts Gemdos time
If 'in' = '-1' the current Gemdos time is used.
Example:
MODE 1 !US format
date&=INP&(#1) !load date from a file
PRINT DATE$(date&) !outputs something line 04/25/2018
PRINT DATE$(-1) !output current date
Tgetdate()+, Tgettime()+, Gettime()+
TIMESTAMP$
out$=TIMESTAMP$(in,format$) (v3.7)
format$: sexp
in: iexp (at least 32-bits)
out$: svar
This function converts timestamps to human readable form with a custom layout.
It work independently from other date/time related functions. The current MODE
setting has no effect on the conversion.
in - XBIOS(23) compatible date/time format (a long)
If 'in' = -1 the current date/time is used
format$ - If 'format$' is an empty string ("") the default format is used
(default: "Y-m-dTH:i:s")
See table below for token character list
A maximum of 28 characters is allowed, or it's cropped (no error)
out$ - Returns the result of the conversion
'in' is identical to the return value of Xbios(23). Gemdos() timestamps can
easily be converted by arranging the data as a long: <date.w><time.w>
Example: ts%=MAKE%(date%,time%)
'format$' works by replacing token characters with individual components of
the date and time. Characters that are not considered token characters are
output as is.
Token Output
d day, 2 digits (01 to 31)
D day of the week, 3 char textual representation (Sun to Sat)
j day, no leading zero (1 to 31)
l day of the week, full textual representation (Sunday to Saturday)
F month, full textual representation (January to December)
m month, 2 digits (01 to 12)
M month, 3 char textual representation (Jan to Dec)
n month, no leading zero (1 to 12)
Y year, 4 digits (ie: 2021)
y year, 2 digits (ie: 21)
g hour, 12 hour format, no leading zero (1 to 12)
G hour, 24 hour format, no leading zero (0 to 23)
h hour, 12 hour format, 2 digits (01 to 12)
H hour, 24 hour format, 2 digits (00 to 23)
i minutes, 2 digits (00 t0 59)
s seconds, 2 digits (00 to 59)
a am or pm, lowercase
A AM or PM, uppercase
W week number, ISO-8601 format, no leading zero (1-53)
X week number, US format, no leading zero (1-53)
# toggle digital characters on/off (0 to 9)
$+chr used to output tokens (output next character as is)
Note: By default digital characters are off.
Digital characters are not PRINTable, however they can be displayed
with TEXT or via ReSourCe objects.
If month < 1 or day < 1 error #71 occurs.
Example:
PRINT TIMESTAMP$(-1,"") -> outputs something like: 2018-05-12T20:33:20
'
ts%=INP%(#1) !simulate timestamp loaded from a file
ts$=TIMESTAMP$(ts%,"D M j g:i A")
PRINT ts$ -> outputs something like: Sat Mar 27 1:22 PM
Tgetdate()+, Tgettime()+, Gettime()+
DATE
date=DATE(year,month,day) (v3.7)
time=TIME(hour,minute,second)
date, time: ivar (should be long)
year, month, day, hour, minute, second: iexp
These functions are for creating date or time values in Gemdos format.
DATE() - Builds a date
year - 1980 to 2107
month - 1 to 12
day - 1 to 31
date - Returns result in TGETDATE() format
TIME() - Builds a time
hour - 0 to 23 (24 hour notation)
minute - 0 to 59
second - 0 to 59
time - Returns result in TGETTIME() format
If any paramters are out of range error #71 occurs.
'Not a word' error can occur when using word size return variables. This
is because GFA does not support unsigned words.
Note: No error checking when compiled.
Example:
MODE 1
date%=DATE(1984,11,9)
PRINT DATE$(date%) -> "11/09/1984"
Tgetdate()+, Tgettime()+, Gettime()+
LOADMEM
stat=LOADMEM(path$) (v3.7)
stat: ivar
path$: sexp
Simple way to load data. Uses the default memory allocation settings of the
program header. If you need to know the file size, this function isn't very
handy.
Possible return values for 'stat':
>0 = address of malloc'd block (data that was loaded)
<0 = standard gemdos error code
It's up to the coder to MFREE() the memory block.
This function replaces this code:
OPEN "i",#1,file$
size%=LOF(#1)
adr%=MALLOC(size%)
IF adr%>0 !ok?
BGET #1,adr%,size%
ENDIF
CLOSE #1
Note: This function does not invoke GFA's built in error handler.
Internally it's 100% gemdos calls.
Setting bit 2 (PF_TTRAMMEM) of the program header will cause this call to
allocate fast-ram if available.
Fopen()+, Fread()+, Fclose()+, Malloc()+
FSOCKET
stat=FSOCKET(domain,type,protocol) (v3.7)
stat=FSOCKETPAIR(domain,type,protocol,fds)
stat=FACCEPT(fd,addr,addrlen)
stat=FCONNECT(fd,addr,addrlen)
stat=FBIND(fd,addr,addrlen)
stat=FLISTEN(fd,backlog)
stat=FRECVMSG(fd,msg,flags)
stat=FSENDMSG(fd,msg,flags)
stat=FRECVFROM(fd,buf,buflen,flags,addr,addrlen)
stat=FSENDTO(fd,buf,buflen,flags,addr,addrlen)
stat=FSETSOCKOPT(fd,level,optname,optval,optlen)
stat=FGETSOCKOPT(fd,level,optname,optval,optlen)
stat=FGETPEERNAME(fd,addr,addrlen)
stat=FGETSOCKNAME(fd,addr,addrlen)
stat=FSHUTDOWN(fd,how)
SET.SOCKADDR_IN addr,family,port,ip
stat: ivar
domain, type, protocol, fds: iexp
fd, addr, addrlen, buf, buflen: iexp
backlog, msg, flags, how: iexp
level, optname, optval, optlen: iexp
family, port, ip: iexp
These functions are the basis for MiNT-Net socket calls. FRESOLVE() is missing
because it's actually part of MiNTLib and cannot be incorporated into
GFABASIC.
SET.SOCKADDR_IN is a helper command used to create the sockaddr_in structure.
This structure must be at least 16 bytes.
Check MiNT version before use, as not all versions of MiNT contain these
calls. See the FreeMiNT repository for further information.
Note: As of this writing MiNT-Net does not support IPv6.
CMDLINE$
c$=CMDLINE$ (v3.7)
c$: svar
This built in string variable returns the command line passed to the program.
IF LEN(CMDLINE$)=0 !no command line was passed
IF LEN(CMDLINE$)=1 to 125 !decode standard command line
IF LEN(CMDLINE$)=127 !decode an extended command line
CMDLINE$ does not decode the Gemdos Extended Argument (ARGV) Specification.
It's up to the coder to handle this situation if they wish to support it.
If for some reason the length of the command line is >127 error #60 occurs.
GEMDOS Processes+
ENVIRON
adr=ENVIRON (v3.7)
ENVIRON index,out$
adr: ivar (capable of holding 32-bits)
index: iexp
out$: svar
These commands and functions help manage environment variables.
ENVIRON as a function:
This built-in variable returns the address of the programs environment.
If ENVIRON returns 0 (NULL) then the program was not passed an environment.
ENVIRON as a command:
This command returns all environment strings as an indexed list.
index -> 0 to ?
out$ -> returns result
An empty string signals the end of the environment list.
Examples:
IF ENVIRON
PRINT "environment address: ";ENVIRON
ELSE
PRINT "no environment found"
ENDIF
The format of the environment area is as follows:
<VAR=blah><null><VAR=blah><null> ... <var=blah><null><null>
Note: The last entry is marked with a double null.
CLR i&
DO
ENVIRON i&,t$
EXIT IF LEN(t$)=0
PRINT t$
INC i&
LOOP
PRINT i&
GEMDOS Processes+
ENVIRON$
value$=ENVIRON$(name$) (v3.7)
value$: svar
name$: sexp
This function will search the programs environment area for 'name$' and return
it's value. If 'value$' is an empty string, then 'name$' wasn't found.
If no environment was passed to the program an empty string is returned.
If 'name$' is an empty string and empty string is returned.
Examples:
PRINT ">";ENVIRON$("");"<" !outputs ><
PRINT ">";ENVIRON$("AVSERVER");"<" !outputs >THING<
PRINT ">";ENVIRON$("AVSERVER=");"<" !outputs >THING<
Note: The '=' (equals) sign is optional.
'name$' is limited to 255 characters or error #60 is issued.
GEMDOS Processes+
SLBOPEN
ver=SLBOPEN(lib$,path$,minver,dout,fout) (v3.7)
stat=SLBCLOSE(desc)
ver, stat: ivar
lib$, path$: sexp
minver, desc: iexp
dout, fout: ivar (able to hold at least 32-bits)
These functions allow the use of Shared Libraries. These are supported by MiNT
and MagiC.
Please see further documents for the use of these calls.
Slbopen()+, Slbclose()+, Shared libraries+
ENDSEEK
ENDSEEK #chan,offset (v3.7)
stat=F_ENDSEEK(fhan,offset)
chan, offset, fhan: iexp
stat: ivar
These commands move the file pointer relative to the end of the file.
'offset' should be 0 or a negative value.
If 'offset' is positive it's transformed into a negative value internally.
ENDSEEK - Any error will invoke the built in error handler.
F_ENDSEEK() - The caller should handle the error code returned.
Examples:
OPEN #1,"i","u:\ram\test.dat" !file is 300 bytes
'
ENDSEEK #1,0
PRINT LOC(#1) !displays 300
'
ENDSEEK #1,-1
PRINT LOC(#1) !displays 299
'
CLOSE #1
Fseek()+
FILELEN
size%=FILELEN(path$) (v3.7)
size: ivar
path$: sexp
This function returns the length of a file in bytes or a negative gemdos error
code. It does not invoke GFA's built in error handler.
Internally it's 100% gemdos calls and should not be used on files that are
already open. For open files use LOF() or F_LOF().
Replaces code segment such as:
OPEN "i",#1,path$
size%=LOF(#1)
CLOSE #1
Example:
size%=FILELEN(path$)
IF size%<0
PRINT "error code: ";size%
EDIT
ENDIF
Fopen()+, Fseek()+, Fclose()+
PGETPID
x=PGETPID() (v3.7)
x=PGETPPID()
Pgetpid()+, Pgetppid()+
FPIPE
stat=FPIPE(addr) (v3.7)
stat=FMIDIPIPE(pid,in,out)
stat=PMSG(mode,mboxid,msgptr)
stat=PSEMAPHORE(mode,id,timeout)
Fpipe()+, Fmidipipe()+, Pmsg()+, Psemaphore()+
PRUSAGE
stat=PRUSAGE(adr) (v3.7)
stat=SUPTIME(adr_uptime,adr_load)
stat=PSETLIMIT(option,val)
stat=PUSRVAL(val)
Note: Functions PRUSAGE() and SUPTIME() always return E_OK (0).
Examples:
DIM d%(8)
~PRUSAGE(V:d%(0)) !structure = 8 longs
FOR i&=0 TO 7
PRINT i&,d%(i&)
NEXT i&
EDIT
CLR t%
DIM u%(3)
~SUPTIME(V:t%,V:u%(0)) !1 long, structure = 3 longs
"Uptime: ";t%
FOR i&=0 TO 2
PRINT i&,u%(i&)
NEXT i&
EDIT
Prusage()+, Suptime()+, Psetlimit()+, Pusrval()+
CURDIR$
path$=CURDIR$ (v3.7)
path$: svar
This string function returns the complete default path.
If an error occurs a null ("") string is returned.
Example:
PRINT CURDIR$ -> F:\GBE.DEV\
Note: If you need to know the boot drive: bootdrv$=CHR$(65+DPEEK(1094))+":\"
See also: _BOOTDEV
Some versions of XaAES cause CURDIR$ to retrun the path of the
interpreter. This a bug in XaAES.
Dgetdrv()+, Dgetpath()+
PNICE
stat=PNICE(delta) (v3.7)
stat=PRENICE(pid,delta)
stat=PGETPRIORITY(which,who)
stat=PSETPRIORITY(which,who,pri)
Note: MiNT source code shows return values for PNICE() and PRENICE() as longs.
To get correct return values:
stat&=WORD(PNICE(delta&))
Pnice()+, Prenice()+, Pgetpriority()+, Psetpriority()+
FILECOPY
stat=FILECOPY(src$,dst$) (v3.7)
src$,dst$: sexp
stat: ivar (able to hold a 32-bit value)
This function will copy a file. The source file is only read and the
destination file will be created. If the destination file already exists,
it will be clobbered. See important note below.
The return value is as follows:
=>0 = Ok (file length)
<0 = standard gemdos error code
A zero (0) size file is valid and will be copied.
If there's enough free memory the file will be copied in one read/write pass.
If not, it's copied in smaller chunks until complete.
Note: Extreme care must be taken with this command. The source file
will be destroyed if the source and destination paths are the same!
This function is based 100% on Gemdos calls and does not invoke
GFA's built in error handler.
Fopen()+, Fcreate()+, Fseek()+, Fread()+, Fwrite()+, Fclose()+, Malloc()+,
Mfree()+
DWRITELABEL
stat=DWRITELABEL(path$,label$) (v3.7)
stat=DREADLABEL(path$,lout$)
stat: ivar
path$,label$: sexp
lout$: svar
Dwritelabel()+, Dreadlabel()+
DOPENDIR
stat=DOPENDIR(path$,flag) (v3.7)
stat=DREADDIR(size,dhandle,addr)
stat=DREWINDDIR(dhandle)
stat=DCLOSEDIR(dhandle)
stat=DXREADDIR(size,dhandle,addr,xattr,xret)
stat: ivar
path$: sexp
flag,size,dhandle,addr,xattr: iexp
xret: ivar (able to hold at least 32-bits)
Dopendir()+, Dreaddir()+, Drewinddir()+, Dclosedir()+, Dxreaddir()+
FEXIST
stat=FEXIST(path$) (v3.7)
stat: ivar
path$: sexp
This function determines if a file or folder exists.
Returns: -1 (TRUE) -> file
0 (FALSE) -> path doesn't exist
1 -> folder
Note: FEXIST() gives mixed results for the root of a drive. Only seems
reliable under MiNT. Use DRVMAP() to test if a drive exists.
Fattrib()+
PSIGNAL
stat=PSIGNAL(sig,handler) (v3.7)
stat=PSIGBLOCK(mask)
stat=PSIGSETMASK(mask)
stat=PSIGPENDING()
stat=PSIGPAUSE(mask)
stat=PSIGACTION(sig,act,oact)
stat=PKILL(pid,sig)
stat=PAUSE()
stat=PTRACE(request,pid,addr,data)
stat=TALARM(time)
stat=TMALARM(time)
stat=TSETITIMER(which,interval,value,ointerval,ovalue)
PKILL(pid,9) - Can be used to force kill a program.
PSIGNAL() - A custom signal handler can only be used if written in assembler.
PAUSE() - Always returns E_OK.
PSIGINTR() - Not supported since MiNT v1.16 release.
Psignal()+, Pkill()+, Pause()+, Ptrace()+, Talarm()+, Tmalarm()+,
Psigblock()+, Psigsetmask()+, Psigpending()+, Psigpause()+, Psigaction()+,
Tsetitimer()+,
Signals+, Signal Table+
LOADSTR
stat=LOADSTR(path$,sout) (v3.7)
This function loads a file directly to a string. The file size must be within
string limits (0-32767). Useful for loading GET/PUT images.
Allows the coder to catch errors and avoid the built in error handler.
path$: sexp
sout$: svar
path$ - path to file
sout$ - returns the contents of the file
stat - =>0 = files size (ok)
<0 = standard gemdos error codes
-1 = file exceeds string limit
Typical code:
OPEN "i",#1,path$
size%=LOF(#1)
sout$=SPACE$(size%)
BGET #1,V:sout$,size%
CLOSE #1
New code:
IF LOADSTR(path$,img$)<0
' failed to load image
ENDIF
Setting bit 2 (PF_TTRAMMEM) of the program header will cause this call to
allocate fast-ram if available.
Fopen()+, Fread()+, Fclose()+
FILES
count=FILES(path$,attr,dout$()) (v3.7)
count: ivar
path$: sexp
attr: iexp
dout$(): string array (must have one dimension)
This function reads a disk directory. It is not recursive.
It's similar to command FILES, but the data is stored in an array as opposed
to being sent to the screen or a device. The results are returned in a string
array where each entry represents a directory entry.
Each entry contains all the data packed into 22 bytes.
path$ - Path with mask: "c:\*.*" (if mask not supplied, *.* is assumed)
attr& - attribute (see FSFIRST())
dout$() - returns file data (one dimensional string array)
total >=0 - the total number of files found matching the input criteria
total <0 - gemdos error code
Other possible errors: array not dimensioned - #15 (used as a feature)
array must have one dimension - #28
array index to large (result exceeds DIM'd size) - #16
Special feature:
Internally FILES() determines if the array has been dimensioned or not.
If FILES() is called and the array isn't dimensioned, it only scans the
directory. The array is completely ignored and the function returns the total
number of files found. This takes the guess work out of determining the number
of elements required to hold all the file names.
If FILES() is called and the array has been dimensioned, it attempts to fill
the array with results.
Packed string data layout:
Name Null Size
| | |
FILENAME.EXTNADDTTSSSS (always 22 bytes)
|| |
|| Time
|Date
Attributes
Offset Size Description
1 13 chars Name (padded with nulls)
14 1 byte Attributes (see FSFIRST())
15 1 word Date in gemdos() format
17 1 word Time in gemdos() format
19 1 long Size in bytes
Examples:
fn$=ZTRIM$(dout$(i&)) !only want the name
attr&=ASC(MID$(dout$(i&),14,1))
date%=CVI(MID$(dout$(i&),15,2)) !must be long, else 'not a word' error
time%=CVI(MID$(dout$(i&),17,2)) ! ... long also
size%=CVL(MID$(dout$(i&),19,4))
'
' alternate way to extract the time/date
ts%=CVL(MID$(dout$(i&),15,4)) !pass right into TIMESTAMP$()
' to calc array size:
path$="o:\*.gfa" !be sure to use the same parameters
total&=FILES(path$,0,dout$()) !array not dim'd, scan dir only
DIM dout$(total&) !now we know how many elemets we need
~FILES(path$,0,dout$()) !fill the array
' alternate way, using arbitrary array size, only need one call
path$="o:\*.gfa"
DIM dout$(128)
total&=FILES(path$,0,dout$()) !if it exceeds 128 files, error #16 occurs
Note: For OPTION BASE 1 users, an empty directory returns 0.
Thus, DIM dout$(0) is an error condition.
To avoid extra code to catch this error one can simply use
DIM dout$(total+1)
Waste one string entry, but reduces the overall code complexity.
CALLOC
addr=CALLOC(items,size) (v3.7)
addr: ivar (able to hold 32-bits)
items, size: iexp
This function allocates ram and clears it to zero.
Useful for porting 'C' code.
It's equivalent to:
FUNCTION calloc(items%,size%)
$F%
LOCAL adr%
adr%=MALLOC(items%*size%)
IF adr%
BZERO adr%,items%*size%
ENDIF
RETURN adr%
ENDFUNC
Setting bit 2 (PF_TTRAMMEM) of the program header will cause this call to
allocate fast-ram if available.
Malloc()+
YEAR
y=YEAR(date) (v3.7)
m=MONTH(date)
d=DAY(date)
h=HOUR24(time)
m=MINUTE(time)
s=SECOND(time)
y, m, d, h, s: ivar
date, time: iexp
These functions return individual date/time components.
date/time should be a gemdos compatible date or time value.
The format is identical to TGETDATE() and TGETTIME().
Current RTC values are use if date or time is -1 (TRUE).
YEAR() -> 1984 to 2107
MONYH() -> 1 to 12
DAY() -> 1 to 31
HOUR24() -> 0 to 23 (24 hour format)
MINUTE() -> 0 to 59
SECOND() -> 0 to 59 (2 second resolution)
Tgetdate()+, Tgettime()+, Gettime()+
HOUR12
h=HOUR12(hour) (v3.7)
h: iexp
This function converts 24 hour time to 12 hour time.
hour: 0 to 23 (24 hour)
If hour is out of range error #71 occurs.
Return: 1 to 12 (12 hour)
Example:
PRINT HOUR12(HOUR24(-1)) !current time
MERIDIEM
flag=MERIDIEM(hour) (v3.7)
hour: iexp
This function determines if hour expressed in 24 hour format is AM or PM.
If hour is out of range (0 to 23) error #71 occurs.
Return: FALSE -> AM (ante meridiem, before midday)
TRUE -> PM (post meridiem, after midday)
Example:
PRINT MERIDIEM(HOUR24(-1)) !current time
WEEKDAY
ret=WEEKDAY(date,format) (v3.7)
ret=WEEKDAY(year,month,day,format)
ret: ivar
date, format, year, month, day: iexp
This function can be used to determine the day of the week of any given date.
WEEKDAY(date,format) accepts a standard Gemdos date as input
Input: if date = -1 the current Gemdos date is used
Note: Only works for dates within the limits of the Gemdos date format.
The year can be 1980 to 2107.
WEEKDAY(year,month,day,format) year, month, and day as individual parameters
Input: year (>1752)
month (1-12)
day (1-31)
Both variants return the following:
ISO-8601 format = 0 US format = 1
1 -> Monday 0 -> Sunday
2 -> Tuesday 1 -> Monday
3 -> Wednesday 2 -> Tuesday
4 -> Thursday 3 -> Wednesday
5 -> Friday 4 -> Thursday
6 -> Saturday 5 -> Friday
7 -> Sunday 6 -> Saturday
Examples:
PRINT WEEKDAY(-1,1) !current Gemdos date
PRINT WEEKDAY(date&,1) !simulate a Gemdos date loaded from a file
PRINT WEEKDAY(2018,12,25,1) !outputs 2
Note: WEEKDAY() is based on Tomohiko Sakamoto's Algorithm for finding the day
of the week. Given any date according to the Gregorian Calendar, the
task is to return the day (Monday, Tuesday, etc) on that particular day.
It was hand translated from 'C' to assembler by Lonny Pursell
Tgetdate()+
DAYNO
ret=DAYNO(date) (v3.7)
ret=DAYNO(year,month,day)
ret: ivar
date, year, month, day: iexp
This function returns the day of the year of a given date.
Returns a number from 1 to 365.
Returns a number from 1 to 366 for a leap year.
DAYNO(date) accepts a standard Gemdos date as input.
Input: if date = -1 the current Gemdos date is used
Note: Only works for dates within the limits of the Gemdos date format.
The year can be 1980 to 2107.
DAYNO(year,month,day) accepts year, month, and day as individual parameters.
Input: year (>1752)
month (1-12)
day (1-31)
Examples:
PRINT DAYNO(-1) !current Gemdos date
PRINT DAYNO(date&) !simulate a Gemdos date loaded from a file
Note: Based on the Gregorian Calendar.
Tgetdate()+
LEAP
flag=LEAP(year) (v3.7)
flag: ivar
year: iexp
This function determines if a given year is a leap year.
flag returns: TRUE -> Is a leap year (366 days)
FALSE -> Not a leap year (365 days)
Note: Based on the Gregorian Calendar.
If years <= 1752 it returns FALSE.
Examples:
PRINT LEAP(1992) !true
PRINT LEAP(2000) !true
PRINT LEAP(1900) !false
PRINT LEAP(YEAR(-1)) !current year
WEEK
ret=WEEK(date,format) (v3.7)
ret=WEEK(year,month,day,format)
ret: ivar
date, format, year, month, day: iexp
This function returns the week number of a given date.
Returns a number from 1 to 53.
WEEK(date,format) accepts a standard Gemdos date as input
Input: if date = -1 the current Gemdos date is used
Note: Only works for dates within the limits of the Gemdos date format.
The year can be 1980 to 2107.
WEEK(year,month,day,format) year, month, and day as individual parameters
Input: year (>1752)
month (1-12)
day (1-31)
Format parameter:
0 -> ISO-8601 format
1 -> US format
Examples:
PRINT WEEK(-1,1) !current Gemdos date
PRINT WEEK(date&,1) !simulate a Gemdos date loaded from a file
Tgetdate()+
FREADLINK
status=FREADLINK(symlink$,out_refers_to$) (v3.7)
status=FLINK(oldname$,newname$)
status=FSYMLINK(oldname$,newname$)
FREADLINK() parameter scheme doesn't match official documentaion.
Freadlink()+, Flink()+, Fsymlink()+
CREAD
CWRITE #channel,sout$ (v3.7)
CREAD #channel,sin$
stat=F_CWRITE(fhan,sout$)
stat=F_CREAD(fhan,sin$)
channel, fhan: iexp
sin$: svar
sout$: sexp
These functions read and write 'C' style strings.
Via channel numbers:
CWRITE - This command can invoke the buit in error handler.
CREAD - This command can invoke the buit in error handler.
Limited to 256 characters.
Via Gemdos handles:
F_CWRITE() - return value should be LEN(sin$)+1, otherwise it failed
the +1 accounts for the null stored with the string
do not append a null, it does it for you
F_CREAD() - return value will be positive, otherwise it failed, LEN(sout$)+1
the +1 accounts for the null stored with the string
error code #-1 signals string too long (maximum 32767 characters)
triggers GFA error handler if string request exceeds string ram
the null is not returned on the end of the string
These functions won't invoke the built in error handler, it's up
to the coder to manage any errors based on the return value.
The format of a 'C' string:
"text"+CHR$(0)
Fread()+, Fwrite()+
PGETUID
uid=PGETUID() (v3.7)
stat=PSETUID(uid)
gid=PGETGID()
stat=PSETGID(gid)
gid=PGETPGRP()
stat=PSETPGRP(pid,newgrp)
stat=PGETGROUPS(len,gidset)
stat=PSETGROUPS(len,gidset)
auid=PGETAUID()
stat=PSETAUID(auid)
euid=PGETEUID()
stat=PSETEUID(euid)
egid=PGETEGID()
stat=PSETEGID(egid)
stat=PSETREUID(ruid,euid)
stat=PSETREGID(rgid,egid)
Pgetuid()+, Psetuid()+, Pgetgid()+, Psetgid()+,
Pgeteuid()+, Pseteuid()+, Pgetegid()+, Psetegid()+,
Pgetpgrp()+, Psetpgrp()+ ,Pgetgroups()+, Psetgroups()+,
Pgetauid()+, Psetauid()+, Psetreuid()+, Psetregid()+
PWAIT
stat=PWAIT() (v3.7)
stat=PWAIT3(flag,rusage)
stat=PWAITPID(pid,flag,rusage)
Pwait()+, Pwait3()+, Pwaitpid()+
CCONIN
ch=CCONIN() (v3.7)
~CCONOUT(ch)
ch=CAUXIN()
~CAUXOUT(ch)
stat=CPRNOUT(ch)
ch=CRAWIO(ch)
ch=CRAWCIN()
ch=CNECIN()
stat=CCONIS()
stat=CCONOS()
stat=CAUXIS()
stat=CAUXOS()
stat=CPRNOS()
~CCONRS(sin$)
stat=CCONWS(text$)
Note: CCONWS() is faster than PRINT.
Cconin()+, Cconout()+, Cauxin()+, Cauxout()+, Cprnout()+,
Crawio()+, Crawcin()+, Cnecin()+, Cconrs()+, Cconws()+,
Cconis()+, Cconos()+, Cauxis()+, Cauxos()+, Cprnos()+
TADJTIME
stat=TADJTIME(delta,olddelta) (v3.7)
stat=TGETTIMEOFDAY(tv,tzp)
stat=TSETTIMEOFDAY(tv,tzp)
Tadjtime()+, Tgettimeofday()+, Tsettimeofday()+
FREADV
stat=FREADV(handle,iov,niov) (v3.7)
stat=FWRITEV(handle,iov,niov)
Freadv()+, Fwritev()+
FCHDIR
stat=FCHDIR(fd) (v3.7)
stat=FFDOPENDIR(fd)
fd=FDIRFD(handle)
These are not documented anywhere.
Google might help.
Fchdir()+, Ffopendir()+, Fdirfd()+
REALLOC
newadr%=REALLOC(oldadr,oldsize,newsize) (v3.7)
newadr: ivar (at least 32-bits)
oldadr, oldsize, newsize: iexp
This function will reallocate a memory block and copy it's contents and the
old memory block will be freed.
Return values: 0 = malloc failed
<0 = mfree failed (oldadr likely incorrect)
>0 = address of new memory block
If it fails the old block is left intact.
Notes:
For this call to work, there must be enough ram to hold both blocks at the
same time.
How it works:
A new block is allocated
If larger than the old block, the entire contents of the old block is copied
The unused portion of the new block is cleared
If smaller than the old block, the contents is copied, but truncated
No clearing need be done
Finally the old block is freed
If freeing the old block fails, nothing is allocated
Setting bit 2 (PF_TTRAMMEM) of the program header will cause this call to
allocate fast-ram if available.
Malloc()+, Mfree()+
LINE-A
CRASTER
SFILL
TMOUSE
TPUT
TMOUSE
TMOUSE addr (v3.7)
addr: iexp
Line-A transform mouse. Similar to DEFMOUSE, but works at the Line-A level.
addr - address of mouse shape structure
Line-A Transform Mouse+
TPUT
TPUT x,y,mask$,data$ (v3.7)
x,y: iexp
mask$,data$: sexp
Line-A blit with transparency.
The command will ignore incorrectly formatted strings (LEN()<6).
See also TBITBLT.
Example:
' paint a transparent sprite
'
' generate sprite
' paint mask
GRAPHMODE 1
DEFFILL 1,1
PBOX 0,0,40,40
DEFFILL 0,1
PCIRCLE 20,20,15
DEFFILL 1,1
PCIRCLE 8,20,15
' get mask
GET 0,0,40,40,mask$
' paint sprite
GRAPHMODE 2
DEFFILL 0,1
PBOX 0,0,40,40
DEFFILL 2,1
PCIRCLE 20,20,15
DEFFILL 3,3
PCIRCLE 20,20,15
DEFFILL 0,1
PCIRCLE 8,20,15
' get sprite
GET 0,0,40,40,sprite$
'
' paint a background
DEFFILL 4,1
PBOX 45,45,275,155
DEFFILL 6,4
PBOX 50,50,270,150
'
' paint sprite with transparency
REPEAT
IF MOUSEK=1
drawx&=MOUSEX-20
drawy&=MOUSEY-20
HIDEM
'
' PUT drawx&,drawy&,mask$,1
' PUT drawx&,drawy&,sprite$,7
'
TPUT drawx&,drawy&,mask$,sprite$
'
SHOWM
PAUSE 10
ENDIF
UNTIL MOUSEK=2
EDIT
Line-A BitBlt+
SFILL
SFILL x,y,type,f,m,addr,num_pattern (v3.7)
x, y, type, f, m, num_pattern: iexp
addr: iexp (must be at least 32-bits)
Line-A seed fill command. Must call ACLIP prior to this command.
Colors are specified in Xbios hardware order.
Internally MFILL is always 0 (mono).
x - start x position
y - start y position
type - -1 = fill until some other color than the inital one is detected
=>0 = outline mode, stop at this color
f - fill color
m - write mode 0-3 (see ALINE)
addr - pattern buffer (see HLINE)
num_pattern - pattern word count - 1
Example:
INLINE pattern%,4
WORD{pattern%+0}=&HAAAA
WORD{pattern%+2}=&H5555
'
ACLIP 1,0,0,319,199 !required!
'
SFILL 100,100,-1,C_XBIOS(#2,16),0,pattern%,1
'
~INP(2)
EDIT
Line-A Seed Fill+
CRASTER
CRASTER type,mfill,smfdb,dmfdb,addr,num_pattern (v3.7)
type, mfill, num_pattern: iexp
smfdb, dmfdb, addr: iexp (must be at least 32-bits)
Line-A copy raster command. Should call ACLIP prior to this command.
Use PTSIN() or SET.PXYXY to set the source and destination rectangles.
Use INTIN() to set the remaining parameters.
type - 0=opague 1=transparent
mfill - 0=mono 1=multi-plane
smfdb - source MFDB
dmfdb - destination MFDB
addr - pattern buffer (null=off)
num_pattern - pattern word count - 1
PSTIN(0-3) - source rectangle
PTSIN(4-7) - destination rectangle
INTIN(0) - write mode (same as GRAPHMODE) or logic operation (0-15)
INTIN(1) - foreground color
INTIN()2 - background color
Line-A Copy Raster+
Compiler commands
Compiler commands (v3.7)
$Ax
set MiNT memory protection: x=0 to 3 (default=0)
0 -> private
1 -> global
2 -> super
3 -> readable
changes the header of the output binary
$D+
symbol control
$D+ -> append symbol table (default=off)
same as linker command line option '-s'
$H1 H+ H-
stack control (programs only)
$H1 -> insert a single stack check
if the stack goes too deep and exceeds the allocated space
error #93 'stack error' will be trigger
also checks the top to insure the stack stays in bounds
its possible an asm routine has not restored the stack
low overhead, can be left in apps if used in specific places
$H+ -> start inserting stack checks before each line
$H- -> stop inserting stack checks
note: stack size is always 8kb
$Kx
keep free: x=>16384 (default=16384)
subtracted off the largest block before $Mx is executed
handy for apps that need all available ram, but want to leave the OS some
$L-
suppress user symbol output (all routines and labels)
object file created by the compiler will have no user symbols
this is useful if linking with a 3rd party linker
note: Do not use this option if you are trying to use a debugger
$Ox
set program flags: x=0 to 7 -> bit field (default=all off)
bit #0 -> fast load
bit #1 -> load alt
bit #2 -> malloc alt
changes the header of the output binary
$T1 T+ T- T# T? T~ T< Zx
trace control (default=all off)
$T1 -> insert a single trace call
$T+ -> start inserting trace calls before every line
note line numbers in normal error messages
if on, an extra line is added to the error messages -> 'Line 00000'
break key alert also reports the line stopped at ($Ux)
if not used, error messages appear as they used to
$T- -> stop inserting trace calls
$T# -> enable crash reporting
write current line number to the crash report area
degrades performance, but can help locate really nasty bugs
$T? -> show line number on screen
prints current line number at position 0,0 via cconws()
cursor is saved/restored, but still might cause problems?
if the toswin2 console is open, its printed there instead
close the toswin2 window, it can't keep up, its too slow
$T~ -> line step (waits for a key press after each line)
caps-lock=toggle on/off
right-shift=advance to next line
if $T? is on, the line number shown is the next line to be executed
when the advance key is pressed
$T< -> slow motion
caps-lock=toggle on/off
right-shift=hold program, release to continue
$T~ and $T< can't be used at the same time, one or the other
last one the compiler finds it the one that will be used
$Zx -> x=0 to ? (default=2)
set $T< delay (with a resolution of 50th of a second)
each call adds 4 to 8 bytes per line to the output binary
plus the trace code itself
recommended for debug use only
$U*
insert $U checks before each gfa command
where as $U+ inserts checks after code generating commands
increases break key checks more often
increases the accuracy of EVERY and AFTER
$Whhhh
insert assembler as hex codes (warning: advanced command!)
case is not important, spaces and dollar signs '$' are ignored
each entry must be a 4 character hex value, no checks are made!!!!!!!!!!!!!!
insertion stops when the line ends or a comment is found
examples: (the space after the command itself is optional)
$w hhhh !with comment
$w hhhhhhhh !exactly 8 chars 2*4=8
$w hhhh hhhh
$w $hhhh
$w $hhhh$hhhh
$w hhhh $hhhh !mixed
$w 4E73 !rte
this command must be on a line by itself and not mixed with other commands
parameters must be legal assembler code, not data!
avoid branching, short branching might work, untested!
avoid registers a3 to a6
if used, restore them before a GFA command is encountered
always restore the stack as well if you use it
$B+
installs an exception handler (bombs)
fixed, no longer freezes MiNT (use only as a last resort!)
recommended for debug use only
$I+
interrupts on (not really interrupt driven anymore)
fixed, no longer interrupt driven (required by $B+)
enables the break key at all $Ux checks
The original docs still apply, the behavior of the old options are unchanged,
only the method used internally has changed so they run interrupt free. EVERY
and AFTER might not be as accurate, but they are usable. The break key is
only checked between commands, so if some command does not return, the break
key won't be detected.
Examples:
$A1 !memory protection set to global
$D+ !turn on debug symbols
$K32768 !leave the system 32kb
$H+ !enable stack checking...
' bunch of code (only testing the stack for this code section
$H- !stop checking the stack
$O2 !set 'load alt' flag
$T+ !if an error occurs, I want to know the line number
$T+,I+,B+ !report bomb errors with line numbers, extreme debugging
$T+,T# !report line numbers, write line number to crash report area
$T+,T#,I+,B+ !all the above
$U* !insert checks before every single line of code
Introduction
Yet another GFA-BASIC Library.
You might be wondering why release yet another library. Let me explain. First,
let us examine the current libraries available.
Original GFA library:
Lots of bugs, especially the famous string handling bug, yet it can be solid
with some _extremely_ careful programming. Contains Line-A calls all over the
place though. You end up using a lot of bindings to avoid many of the built
in commands. You really need to know exactly how to code around all of these
problems. Does not correctly support the 040/060 CPUs.
GFA Patch
Lots of bugs remain. All the Line-A stuff is removed. Otherwise its mostly
the same as the original library. Can be very stable, if you know how to
avoid the string handling bug. This is the library I myself have used for a
very long time.
LicomLIB
Still has lots of bugs (plus new ones added). All Line-A stuff removed. Some
parts are completely removed, rather than fixing them. It is also crash prone
(just leave out $Mx and see for yourself). An (incorrect) attempt at fixing
the string handling bug was made. After some study in the dis-assembler, I
can only recommend never using this library. I have to say its pretty much a
hacked up mess.
RUN!Lib/RUN!Only
Still has some old bugs, a couple minor new ones added. Most of the bad
Line-A stuff removed. Some new features too. However the patching goes too
far in my opinion. Making the library ultra clean, breaks functionality for
demo and game coders. Appears to be loosely based on LicomLIB.
The goal with this library is to fix all the known bugs, yet maintain a balance
such that it doesn't target any specific coding style. It should suit the GEM
coder as well as the demo and game coders. A single library that can be used by
all GFA coders regardless of their project. The only thing really needed to
write a clean GEM application is proper documentation.
A good example is HIDEM/SHOWM and the MOUSEx commands which have always, since
day one, been Line-A calls internally. However, GFA has several ways to
accomplish the same task. If a GEM coder wants to hide or show the mouse, he
should call GRAF_MOUSE() since GFA provides nearly all the AES functions built
in. Likewise if a GEM coder wants to sample the mouse location, he should call
GRAF_MKSTATE(). HIDEM/SHOWM and the MOUSEx commands need to remain as they were
for the demo and game coders. Patching them actually takes away some Line-A
functionality for non GEM coders and that is exactly what this library attempts
to correct.
Redirecting RC_COPY and GET/PUT to the VDI also break demos and games. They
cannot simply be recompiled in order to benefit from the many bug fixes this
library has to offer without a speed penalty. The same applies the CPU and FPU
enhancements, you gain one thing, break something else. Yet another reason
these old commands should really stay as they were.
Sure it is easier and quicker to type HIDEM than the other methods, but there
are solutions like:
PROCEDURE hidem
~GRAF_MOUSE(blah...)
RETURN
Is it really that much more work to type '@hidem' versus 'hidem'? It is only
one extra key stroke.
It should also be noted that its too much work to maintain two full libraries.
That is also my motivation for rethinking the whole library update scheme.
Really this is the simplest solution, the coder does not have to recode his
application, and the old GFA documentation for the most part holds true. Other
methods involve hacks to the compiler and such, and/or the user recode or add
strange new commands to the source code. I wish to avoid all that.
Due to the serious nature of some of these bugs, simply patching them just
wasn't possible anymore. They have been fully dis-assembled and
repaired/recoded and re-assembled from the ground up. Some of these corrections
are based on some older patches, namely the Deep Sleep patch (aka GFA-Patch
v1.07). Deep Sleep was contacted, promised me the source code to their patches,
but what seems to be typical when it comes to GFA matters, they did NOT deliver
the goods. That is when more extensive research was put into the problems, and
the repairs have mutated into something I feel is far more than just a clone of
the old GFA-Patch. By not supplying the source code, all Deep Sleep did was
tarnish their name. They only slowed me down a week or so at which point I had
all their patches dis-assembled and commented anyway.
As of this writing approximately 182 modules have been updated. This is the
largest most extensive GFA Library update to date. Hopefully it becomes the
most widely used.
License agreement
This package carries with it the same license agreement as the original
GFA-BASIC package. Any program created with GFA-BASIC must contain the name
of the package somewhere in the program and/or the documention. That means
the words 'GFA-BASIC' must be visible to the end user somewhere in the
release.
It would also be nice if GBE was mentioned and/or my name, but that's not
required. :o)
New features
Important library changes:
Start-up code
New commands and fuctions: (Sorted A-Z -> index)
Misc
API/Protocols
AES
VDI
BIOS()
XBIOS()
GEMDOS()
LINE-A
Compiler commands
These commands have been changed or enhanced:
ALERT
CLEARW
CLOSEW
CONTRL()
DEFFN
DEFLIST
DEFMOUSE num
DIM
DMASOUND
ERASE
ERR
ERROR
EXIST()
FATAL
FILESELECT
FLOATs
GEMSYS n
GETSIZE()
HIMEM
INTIN()
KEYDEF
KEYPAD
MENU m$()
MENU_REGISTER()
MENU_TEXT()
PI
STE?
TEXT
TT?
VDIBASE
VQT_NAME()
W_INDEX()
_X, _Y
Versions of System Components+, TOS list+
Start-up code
CLS is not called at the start of the program like the editor does. This is
unacceptable in desk accessories or multi-tasking environments. If you need
the screen cleared at startup, simply add CLS at the top of your program.
ERR will be set to 8 if $Mx fails or the program eats all ram.
See ERR for more information.
FATAL will be set to TRUE if the program is running on the wrong CPU type.
See FATAL for more information.
There is no need to allocate a DTA for your application. The library sets up a
DTA for you. The original library would clobber the command line by leaving
the DTA pointing at BASEPAGE+128. This is no longer the case.
Note: If the program is running as a desk accessory the DTA is left at
BASEPAGE+128. There is no command line to be clobbered.
All the information gathered about the machine is stored in the
System Table.
See SYSTAB() for more information about the System Table.
Note: The mouse is not automatically hidden/shown when writing to the screen.
The coder must manage the mouse.
ALERT
ALERT now allows 5 lines of text, with 10 character buttons, and the newer AES
icons 4 and up.
Icons 1 to 3 work every where (standard)
Icons 4 to 6 depend on the AES version
Note: No checks are made to insure the parameters are valid for the version
of TOS it might be running on. That's left up to the coder.
CLEARW
CLEARW variant added. Standard window commands.
CLEARW n -> tops the window, then clears entire window with a blit
CLEARW #n -> walks the rectangle list and clears each rectangle with a blit
DEFFN
DEFFN cannot be placed inside a PROCEDURE or FUNCTION.
DEFLIST
The DEFLIST command isn't fully compatible with GFA-Basic v3.6.
Captitolization of variable names is no longer tied to the command style.
Bit #1 controls the command name style only.
Bit #4 controls the variable name style:
off (0) = name
on (1) = Name
Note: This isn't an issue since the DEFLIST command cannot be compiled.
DIM
DIM/ERASE cannot be placed inside a FUNCTION.
CLOSEW
CLOSEW #n variant added. Standard window commands.
CLOSEW n -> wind_close(n) -> wind_delete(n) -> WF_TOP, VS_CLIP()
CLOSEW #n -> wind_close(n) -> wind_delete(n)
CONTRL()
CONTRL() limit bumped to 13 elements per NVDI v5 limits.
Related to CONTRL(x)=n and n=CONTRL(x) -> x can be 0 to 12
DEFMOUSE num
Parameter range expanded to accept a full 16-bit word (Geneva support).
M_FORCE can also be used: DEFMOUSE OR(2,&H8000)
DEFMOUSE 255 (USER_DEF) issues error #64 (pointer error)
DEFMOUSE >65535 -> address of a valid mouse shape structure (user_def)
Examples:
' create a mouse shape structure, see GRAF_MOUSE() documentation for more info
m$=MKI$(0)+MKI$(0) !x/y action point
m$=m$+MKI$(1) !bit-planes (always 1)
m$=m$+MKI$(0)+MKI$(1) !mask/pointer colors
m$=m$+STRING$(16,CHR$(255)+CHR$(255)) !mask
m$=m$+STRING$(16,CHR$(0)+CHR$(1)) !pointer
DEFMOUSE V:m$ !the parameter is greater than 65535, an address is assumed
' or...
adr%=V:m$
DEFMOUSE adr%
DMASOUND
DMASOUND command enhanced to allow 16-bit playback on the Atari Falcon030.
DMASOUND start%,end%,rate&[,ctl&]
If bit 6 of the rate& parameter is set 'on', then 16-bit playback is enabled.
rate&=2 !25 kHz
rate&=BSET(rate&,6)
Note: No hardware test is performed, so its up to the coder to make sure
the application is actually running on the correct hardware.
ERR
ERR will be initialized to 8 if the requested $Mx ram is not available.
$M32768
IF ERR=8 !not enough ram? (check at startup)
' handle error condition (see FATAL for example code)
ENDIF
$Mx Situation ERR= Comments
------------- ---- --------------------------------------------------------
Option used 0 Success - allocate to the size you specified
Option used 8 Failed - not enough ram, allocated smaller than expected
Option unused 8 Failed - allocate all ram, do not bother to test ERR
Not using $Mx is treated as an error condition, ERR=8. Typically its bad
programming practice to eat all available ram. There are situations where this
is acceptable, if that is your intention, simply do not test ERR at start-up.
Note: This should be checked near the top of your program before trying to
dimension any arrays or create commonly used strings. This works in the
interpreter as well as compiled. If the interpreter cannot meet the ram
requirements requested it will also report error code 8.
How does $Mx actually work?
First the start-up module inquires the largest free block. It then subtracts
off the keep-free amount that is left for the system. Normally 16kb is left
free for the system. It then compares this result to the amount you requested.
If the result is larger than your request, your application gets exactly what
it requested. If the result is smaller than your requested, your application
is given what is available. If this happens your application is suddenly
running with less ram than it expected and eventually will run into problems.
ERROR
Error code 0 (division by zero) has been moved to error code 7. This is a
strange oversight by the original author. The library can pass error codes out
via pterm(), thus it becomes impossible to detect this specific error. Zero is
suppose to indicate no error at pterm(). I have used GFA to write child
processes and actually ran into this situation.
Error code 0 -> undefined (means ok)
Error code 7 -> division by zero
New error codes:
#101 -> additional copyright information (lib & interpreter)
#94 -> token error, likely a corrupt file (interpreter only)
EXIST()
Exist has been updated to work with long file names. It no longer clobbers
the DTA buffer.
FATAL
FATAL will be initialized to TRUE if the program is running on the wrong
processor type. This allows the coder to decide how the program exits.
IF FATAL !running on the wrong CPU type?
' handle error condition...
ENDIF
Built for Started on FATAL=
--------- ---------- ------
680xxx 680xxx FALSE
V4E V4E FALSE
680xxx V4E TRUE
V4E 680xxx TRUE
This should be checked right away at the top of your program, literally the
the very first line of code.
Programs (APP, PRG, TOS, TTP, GTP):
Display an error message.
Immediately exit cleanly with pterm() (EDIT, END, QUIT, or SYSTEM).
Accessories (ACC):
Do not call menu_register() and enter an event loop and ignore all events.
It's probably not wise to interrupt the boot process with an alert.
Setup a dummy event loop that does nothing but report the error.
Note: When this condition occurs the Line-A interface has not been initialized
because it would instantly crash. L~A will return 0. The application
needs to exit as soon as possible before it encounters and illegal
op-code or sit idle in an event loop.
In the editor, FATAL will always be initialized to FALSE.
Example code:
' at the very top of your application
IF ERR=8 OR FATAL !$Mx failed or wrong cpu detected?
@fatal_err
ENDIF
'
' the rest of your program here
'
PROCEDURE fatal_err
IF BTST(STE?,10) !acc?
~MENU_REGISTER(APPL_INIT()," <app name here>")
DO
~EVNT_MESAG(0) !idle until event
IF MENU(1)=40 !acc called?
@fatal_err_message !show messages
ENDIF
LOOP !an acc must not exit!
ELSE !prg?
IF BTST(STE?,11)=FALSE !no mint?
DEFMOUSE 0 !force pointer, older tos shows busy bee
ENDIF
@fatal_err_message !show messages
EDIT !edit -> pterm0() when compiled
ENDIF
RETURN
PROCEDURE fatal_err_message
LOCAL dv&
IF ERR=8
ALERT 1,"<low ram message here>",1," Abort ",dv&
ENDIF
IF FATAL
ALERT 1,"<wrong cpu message here>",1," Abort ",dv&
ENDIF
RETURN
Why is this not handled inside the library start-up code?
If the start-up code calls any AES functions, then the linker is always going
to link and initialize the AES. It would not be possible to write a small TOS
or TTP style application anymore. The GFA compiler has always had this ability
to only link the AES/VDI modules as needed. Calling EVNT_MESAG() inside the
main start-up module would break this ability.
This is 100% optional as well. If you want to rely on the end user reading
your documentation and installing the correct binary, you are free to do that
as well. But, we all know, most users do not read docs. ;o)
FILESELECT
FILESELECT no longer buffers the screen image. If you want the screen saved
and restored you need to do it yourself. Note that SGET/SPUT only work on 32kb
screens. FILESELECT by default sends the application a standard AES redraw
message, if one wants to handle it that way.
The string parameters will only be forced to upper case if single-tasking
is detected.
Also the string limits have been increased to support long file names.
paths -> 256 characters
files -> 64 characters
FLOATs
Float range corrected: 2.225073858507E-308 to 3.595386269725E+999
An exponent of 1000 will correctly generate a syntax error.
It used to accept +1000 which displayed as garbage.
GEMSYS n
The internal table GEMSYS (with a parameter) uses to auto-fill the GCONTRL()
array has been updated to more current AES specifications.
GEMSYS 'n' supports the following additional calls:
APPL_YIELD()
APPL_SEARCH()
APPL_CONTROL()
APPL_GETINFO()
MENU_POPUP()
MENU_ATTACH()
MENU_ISTART()
MENU_SETTINGS()
OBJC_SYSVAR()
OBJC_XFIND()
GRAF_MULTIRUBBER()
WIND_DRAW()
WIND_NEW()
RSRC_RCFIX()
SHEL_RDEF()
SHEL_WDEF()
SHEL_HELP()
FORM_POPUP()
The opcode range is 10 to 135. For a complete list see the GEMSYS Table.
This brings the GEMSYS table up to N.Aes v2.0 standards.
Anything outside this range needs to be written in long form, meaning you will
need to set the GCONTRL() entries yourself.
Note: If you are writing bindings for Geneva, MagiC, WDialog, or XaAes you will
need to use the long form as well.
HIMEM
HIMEM is a useless pointer and should never be used.
INTIN
INTIN() array expanded to 512 elements.
This means other commands that use this array internally are improved:
DEFFILL high/true color support
TEXT longer string output
VQT_EXTENT() longer string input
KEYDEF
This command is ignored.
It was interrupt driven and thus removed because it was unsafe.
KEYPAD
This command is ignored.
It was interrupt driven and thus removed because it was unsafe.
Limit of 10 characters for menu titles removed.
Added support for reg_newname(-1).
See additional AES documentation for proper use.
Note: The menu title is limited to 32 characters maximum.
Same as NAES.
MENU_TEXT() never worked correctly as it left the AES pointing at a GFA
string. Eventually it would become corrupted, do to garbage collection, which
moved the string in memory.
This now overwrites the old string.
The string length must be <= the old one or it will be clipped.
PI
PI will return a slightly adjusted value if the FPU is enabled.
This improves the accuracy, but it's still not perfect.
See TT? for details.
STE?
Returns information about STE compatible hardware support.
Bit Description (if On)
--- ------------------------------------------------------------
0 machine has enhanced joystick ports (STE/Falcon030)
1 machine supports stereo 8-bit playback (STE/Falcon030/TT030)
Examples:
ejoy!=BTST(STE?,0)
stereo_dma!=BTST(STE?,11)
Bits 2-31 are not used (always 0).
TEXT
TEXT x,y,l,t$ -> Character limit of 119 increased to 510. Calls v_justified()
TEXT x,y,t$ -> Character limit of 119 increased to 512. Calls v_gtext()
Note: The variant without the length was completely rewritten for speed.
TT?
Returns information about the CPU/FPU type and invokes CPU/FPU enhancements:
Bit Meaning (if On)
--- --------------------
0 CPU => 68020
1 FPU detected
Invoked CPU enhancements if the CPU is => 68020.
'float to integer' -> BFFFO
long multiply using muls.l (signed) -> LMUL
long division using divs.l (signed) -> LDIV
long modulo using divsl.l (signed) -> LMOD
Invoked FPU enhancements if an FPU is detected:
(A)SIN, (A)COS, (A)TAN, LOG(10), EXP(), SQR() (interpreter/library)
PI (interpreter/library)
Example: ~TT? !turn on the enhancements
In the case of PI, a slightly adjusted value is used to improve the accuracy.
However, GFA does not really have enough decimal places for the FPU when
working with PI. Do not expect perfect results.
Note: This can be used by any application. If the required CPU or FPU is not
found the enhancements are simply not invoked and the old slower methods
are used.
Bits 2-31 are unused and always off.
The FPU emulation in some emulators is not very good. If you use this
option in your program, perhaps consider a switch so the end user can
turn it on/off.
VDIBASE
VDIBASE now points to GFA's internal VDI parameter block.
This was previously undocumented and can be used to snoop on the results of
any built in VDI command.
VDIBASE + 0 contrl 12 words
VDIBASE + 4 intin 256 words
VDIBASE + 8 ptsin 256 words
VDIBASE +12 intout 256 words
VDIBASE +16 ptsout 30 words
Example:
DEFLINE ,4
PRINT WORD{LONG{VDIBASE+16}+0} !width actually set, ptsout(0)
VQT_NAME
Array element INTOUT(33) can contain extra font info, see additional VDI docs.
face&=VQT_NAME(1,name$)
IF CONTRL(4)=>33
type&=INTOUT(33)
IF type&=0
PRINT "pixel/bitmap font"
ELSE !else if type&=1
PRINT "outline/vector font"
ENDIF
ELSE
PRINT "no extra font information"
ENDIF
See additional VDI documentation for correct use.
W_INDEX
This function converts an AES handle to a GFA window number, if a GFA window
is open.
Example:
gfa_window_number&=W_INDEX(#aes_window_handle&)
If the AES window handle in question cannot be found in the WINDTAB structure,
it will return -1.
_X
Initialized with VDI values insead of Line-A values.
Writing a clean GEM application
This section will not explain how to code a clean GEM application. Instead it
will list most of the commands and the OS layer they call. If you want your
application to run correctly on various machines with gfx cards and/or MiNT,
pay careful attention to this list.
This list is only valid for the GBE Library.
On the other hand if you are writing a demo or a game for a specific machine,
the following list can be ignored.
Each OS layer has its own section:
OS Layer - GFA command
Ok - Ok -> Ok to use
Calls - Internal call GFA makes
Alternate - Some other GFA command or layer that is more GEM/MiNT compatible
AES Ok Calls
ALERT ok FORM_ALERT()
APPL_xxx() ok APPL_xxx()
DEFMOUSE num ok GRAF_MOUSE()
DEFMOUSE str ok GRAF_MOUSE() (aes option)
DELAY ok EVNT_TIMER()
EVNT_xxx() ok EVNT_xxx()
FILESELECT ok FSEL_INPUT()
FILESELECT # ok FSEL_EXINPUT()
FORM_xxx() ok FORM_xxx()
FSEL_xxx() ok FSEL_xxx()
GRAF_xxx() ok GRAF_xxx()
MENU_xxx() ok MENU_xxx()
OBJC_xxx() ok OBJC_xxx()
RSRC_xxx() ok RSRC_xxx()
SCRP_xxx() ok SCRP_xxx()
SHEL_xxx() ok SHEL_xxx()
WIND_xxx() ok WIND_xxx()
MENU a$() ok MENU_BAR()
MENU x,num ok MENU_ICHECK()/MENU_IENABLE()
MENU OFF ok MENU_TNORMAL()
MENU KILL ok MENU_BAR()
CLEARW - single tasking only
CLIP # (window) - single tasking only
CLOSEW - single tasking only
FULLW - single tasking only
INFOW - single tasking only
OPENW - single tasking only
TITLEW - single tasking only
TOPW - single tasking only
WINDTAB/WINTAB() - single tasking only
W_HAND()/W_INDEX() - single tasking only
VDI Ok Calls
BITBLT s%(),d%(),p%() ok VRO_CPYFM()
BOUNDARY ok VSF_PERIMETER()
BOX ok V_PLINE()
CIRCLE ok V_ARC()
CIRCLE (pie) ok V_ARC()
CLIP ok VS_CLIP()
COLOR ok VSL_COLOR()
CURVE ok V_PLINE()
DEFFILL (2 parameters) ok VSF_COLOR()/VSF_UDPAT()
DEFFILL (3 parameters) ok VSF_COLOR()/VSF_STYLE()/VSF_INTERIOR()
DEFMARK ok VSM_COLOR()/VSM_TYPE()/VSM_HEIGHT()
DEFLINE ok VSL_TYPE()/VSL_WIDTH()/VSL_ENDS()/VSL_UDSTY()
DEFMOUSE str ok VSC_FORM()
DEFTEXT ok VST_COLOR()/VST_EFFECTS()/VST_ROTATION()/
VST_HEIGHT()/VST_FONT()
DRAW/DRAW TO ok V_PLINE()
ELLIPSE ok V_ELLARC()
ELLIPSE (pie) ok V_ELLARC()
FILL ok V_CONTOURFILL()
GDOS? ok VQ_GDOS()
GRAPHMODE ok VSWR_MODE()
LINE ok V_PLINE()
PBOX ok V_BAR()
PELLIPSE ok V_ELLIPSE()
PELLIPSE (pie) ok V_ELLPIE()
PCIRCLE ok V_CIRCLE()
PCIRCLE (pie) ok V_PIESLICE()
PLOT ok V_PLINE()
POLYFILL/LINE/MARK ok V_FILLAREA()/V_PLINE()/V_PMARKER()
POINT() ok V_GET_PIXEL()
PRBOX ok V_RFBOX()
RBOX ok V_RBOX()
TEXT ok V_GTEXT()/V_JUSTIFIED()
V_CLRWK() ok V_CLRWK()
V_CLSVWK() ok V_CLSVWK()
V_CLSWK() ok V_CLSWK()
V_OPNVWK() ok V_OPNVWK()
V_OPNWK() ok V_OPENWK()
V_UPDWK() ok V_UPDWK()
VDIBASE ok WORK_OUT()
VSETCOLOR ok VS_COLOR()
VQT_EXTENT() ok VQT_EXTENT()
VQT_NAME() ok VQT_NAME()
VST_LOAD_FONTS() ok VST_LOAD_FONTS()
VST_UNLOAD_FONTS() ok VST_UNLOAD_FONTS()
_X/_Y/_C ok WORK_OUT(0/1/13)
Line-A Ok Calls Alternate
ACHAR - textblt TEXT
ACLIP - line-a variables CLIP
ALINE - arbitrary_line LINE
APOLY - filled_polygon POLYFILL
ARECT - filled_rectangle PBOX
ATEXT - textblt TEXT
BITBLT x%() - bitblt BITBLT s%(),d%(),p%()
BITBLT addr% - bitblt BITBLT s%(),d%(),p%()
CRSCOL/CRSLIN - line-a variables vq_curaddress()
GET/PUT ok vro_cpyfm() (vdi option) -
GETSIZE() ok WORK_OUT() (vdi option) -
HIDEM/SHOWM ok graf_mouse() (aes option) -
HLINE - horizonal_line LINE
HTAB/VTAB - line-a variables vs_curaddress()
L~A - - Don't use it
MOUSE x&,y&,k& ok graf_mouse() (aes option) -
MOUSEX/MOUSEY/MOUSEK ok graf_mouse() (aes option) -
RC_COPY ok vro_cpyfm() (vdi option) -
SETMOUSE - line-a variables APPL_TPLAY()
PSET - plot_pixel PLOT
PTST - get_pixel POINT()
SPRITE - draw_sprite/undraw_sprite BITBLT s%(),d%(),p%()
BIOS Ok Calls Alternate
CLS - BCONOUT(VT52) PBOX
INPAUX$/INPMID$ ok BCONIN() -
LOCATE - BCONOUT(VT52) vs_curaddress()
PRINT - BCONOUT() CCONWS() or V_CURTEXT()
PRINT AT() - BCONOUT(VT52) vs_curaddress()
XBIOS Ok Calls Alternate
SETCOLOR - SETCOLOR() VSETCOLOR
SOUND/WAVE ok DOSOUND() -
PEEK/DPEEK/LPEEK ok SUPEXEC() if address $420-$FFFF use SSYSTEM()
POKE/DPOKE/LPOKE ok SUPEXEC() if possible use BYTE{}/WORD{}/LONG{}
SPOKE/SDPOKE/SLPOKE ok SUPEXEC() if address $420-$FFFF use SSYSTEM()
SGET/SPUT ok LOGBASE() BITBLT s%(),d%(),p%() not limited to 32kb
VSYNC ok VSYNC() -
GEMDOS Ok Calls Alternate
DATE$= ok TSETDATE() -
FGETDTA() ok FGETDTA() -
FSETDTA() ok FSETDTA() -
FSFIRST() ok FSNEXT() -
FSNEXT() ok FSFIRST() -
EXEC ok PEXEC() -
MALLOC() ok MXALLOC() -
MFREE() ok MFREE() -
MSHRINK() ok MSHRINK() -
RESERVE - - $Mx and/or MALLOC()
SETTIME ok TSETDATE()/TSETTIME() -
TIME$= ok TSETTIME() -
=DATE$ ok TSETDATE() -
=TIME$ ok TGETTIME() -
System Ok Calls Alternate
AFTER ok Timer B EVNT_TIMER()
EVERY ok Timer B EVNT_TIMER()
PAUSE - Timer B DELAY/EVNT_TIMER()
TIMER - Timer B DELAY/EVNT_TIMER()
GFA internal Ok Calls Alternate
CLIP OFFSET ok - -
DATE$/TIME$ ok - -
DEFNUM ok - -
HIMEM ok - Useless pointer, do not use
KEYDEF - - Ignored, does nothing
KEYPAD - - Ignored, does nothing
MENU x,str ok - Overwrites old string
MODE ok - -
OPTION BASE ok - -
STE?/TT? ok - -
If you notice some command missing and you are curious about it, contact me.
I'll gladly add it to the list.
A similar list could be made for all the I/O commands as well, but for the most
part they are all standard BIOS() or GEMDOS() calls. If such a need becomes
important I can expand this list to include the I/O commands.
The only downside to the file I/O commands is the error handling. Errors during
file I/O trigger GFA's error handler. If you use direct GEMDOS() calls you can
better manage the error handling yourself.
Also, any use of supervisor mode in MiNT degrades the performance. One should
try to avoid this. If you want to find cookies or write to system variables,
have a look at function call SSYSTEM(). For proper vector management, see
function SETEXC(). See also STE? and TT?.
For proper MiNT, VDI, and GEM coding techniques, please seek other sources of
information. For example:
The MiNT CVS Repository (if you can read 'C')
The Atari Compendium (book or CD)
TOS.HYP (very good, and updated once in a while yet too)
Atari Profibuch (huge German book)
The Atari Developers Kit (bit old)
Misc Web sites
Usenet and forums (if someone named charles replies, ignored it!)
Credits
Version 3.70 released Dec 9th, 2020 in honor of Frank Ostrowski's birthday.
You will notice that there are no extra copyrights or other messages displayed.
I do not claim to have written this software, only that I have spent the time
to recode portions of it. The idea is to make minimal changes, that is, only
what is required to solve the problems.
I've lost track of some people I should thank, some stand out though, they
are in no particular order:
Joakim Högberg (aka GokMasE)
For listening to my endless babbling about GFA and its internal workings.
Also for AtarICQ, which shows just what someone can do with GFA and some
motivation. Also a huge thanks for testing.
Peter Persson (aka PeP)
For letting me bend his ear and some tips here and there.
George Nakos (aka ggn)
For the text version of the Devpac 3 manual which I use quite a lot when my
memory fails me. If PDF has one advantage, it's the search feature!
Henk Robbers (author of TT-Digger)
TT-Digger was _heavily_ used during the development phase.
Frank Owstroski
For keeping me so busy for so long.
Misc others:
Ingo Schmidt (aka Curly)
Holger Herzog (aka Schaaf)
Peter Backes (aka rtc)
Lourens Blok
Damir Vuk
Mikko Larjava (originally solved the string handling bug)
Pavel Puchala (reporting typos across multiple documents)
Thomas Ilg (ideas and wonderful games)
Pierre Ton-That (pushing the limits of GFA)
Anders Lindström (bug reports)
All the other versions of BASIC that suck.
In a strange way, that also motivates me.
Helped with translations:
English: lp (me)
German: Curly and rtc
French: kellis and MystikShadows
Swedish: PeP and GokMasE
Slovenian: SWE, Vido, and Curly
Norwegian: ozk
Support
Please report any typos, mistakes, errors, bugs, dust spots, half lit pixels,
you get the point? I can't fix what I don't know about it.
Please don't hesitate to contact me. It's my goal to maintain this library and
if you think you have found a problem let me know. However, please be prepared
to supply a test case (GFA source) that demonstrates the problem. If you don't
want to supply the entire source, try to at least isolate the problem into
something smaller you are willing to send me.
Also, if you are using an emulator, please test your code on a real machine or
find someone with a real machine to test it, before you contact me. Many times
the problem is the emulator. I don't respond well to bogus bug reports.
Disclaimer
Disclaimer
Use entirely at your own risk. I (the author) take no responsibility for any
damage resulting from the use (or misuse) of this software package.
Terms of Use
This package can be placed on ftp sites or Public Domain CD-ROMs.
This package must remain unaltered and CANNOT be repackaged.
This package CANNOT be redistributed on hard disk images or floppy images
or other forms of virtual media used specifically with emulators.
Features
Mostly bug fixes and enhancements.
No radical changes to the library for maximum backward compatibility.
Enhanced CPU/FPU support for machines with an 020 CPU or better (optional).
Unused code removed.
Improved MiNT compatibility.
Some small optimizations were done as well.
Line-A use only where it should be used.
Improved error handler with advanced debugging options.
Break key can now be cleanly used in compiled applications.
EVERY/AFTER are now cleanly implemented.
Improved hardware detection for STE only commands.
All vector hooks removed (except $B+ which is optional).
Completely rebuilt and recompiled from the ground up, every single program and
module.
Development
Assembler: Devpac v3.10
Make: custom (written in GFA)
Dis-assembler: TT-Digger v8.1
Text editor: qed 5.0.5
Source testing: GBE v1.72
Initial development was done on my Hades060 with FreeMiNT. When the Hades060
passed away, may it rest in peace, ARAnyM was used to continue my work.
Known problems
INSTR()/RINSTR()
The 2 parameter variants work fine. Stick to only 2 parameter if you can.
The 3 parameter variants are still broken. This is a tough one to fix.
If you must use all 3 parameters, use these wrappers:
FUNCTION instr(a$,b$,i)
LOCAL v
v=INSTR(a$,b$,i)
IF v<i ! occurs when a$=b$ for i>1
v=0
ENDIF
RETURN v
ENDFUNC
FUNCTION rinstr(a$,b$,i)
LOCAL v
v=RINSTR(a$,b$,i)
IF i=LEN(b$) ! special fix
v=-(LEFT$(a$,i)=b$)
ELSE IF i<LEN(b$) ! general problem when a$=b$
v=0
ENDIF
RETURN v
ENDFUNC
DIM inside a FUNCTION
Don't do it, or weird stuff will happen.
CRSCOL, CRSLIN
These do not work within a TosWin2 window. They only work on real full screens.
LOAD, SAVE, PSAVE, LIST, and LLIST
These are ignored by the interpreter, since there is no direct mode.
Strange compiler bugs that still remain:
EXIT IF FALSE !does not work compiled
IF FALSE !does not work compiled
ELSE IF FALSE !does not work compiled
ENDIF
EXIT IF 0 !does not work compiled
IF 0 !does not work compiled
ELSE IF 0 !does not work compiled
ENDIF
FOR a|=200 TO 10 STEP -1 !does not work compiled
NEXT a|
IF 1=2 !random crashes
ELSE IF 1=2 !random crashes
EXIT IF 1=2 !random crashes
POINT() doesn't work for HC/TC modes. It returns the VDI pen color. Remember
to GHIDEM/GSHOWM the mouse when using this function. If you don't it returns
the pen color at the hotspot of the mouse pointer.
LPENX and LPENY probably only work in the original ST modes. Internally they
use the old shifter mode value to calculate LPENX. I have no way to test
these, so unless someone reports a problem they will remain as is.
INPx()/OUTx do not support peripheral devices 6 to 9. See equivalent BIOS
functions.
RESERVE is still very broken under MiNT.
The Compiler and Linker do not play well with ARGV (extended command lines).
Emulation notes
If you notice strange behavior and you are using the host file system, don't
send me a bug report. Instead, stop using the host file system and use disk
images. Host file systems tend to be less than 100% compatible and/or buggy.
Such problems often stem from EOF() not working on the host file system. Best
option is to use disk images to avoid such problems.
Important notes
There is one important difference between the editor and the compiler. The
editor always initializes the AES and the VDI, however it is possible a
compiled application will not do this. If no AES or VDI calls are made the
linker will not link the code needed for this step. This can cause some
commands and functions to appear broken. All that is needed is a single AES or
VDI call to force the compiled program to operate like the editor. Use some
call that does not change anything, but rather does an inquire, like
~POINT(0,0). This is enough to force the linker to work it's magic.
If one uses $Mx and the exact amount cannot be allocated, the library simply
gives the user all the ram that is available. That's not a perfect situation
and can cause some problems if one assumes since the application appears to run
all is working as expected. If this condition happens ERR will be set to 8 at
startup so this can now be detected properly. The reason the library doesn't
issue an error or dump some message is simple. Since it allows desk accessory
creation, that makes dumping messages and termination a lot more complex if
some startup problem happens.
The mouse is not auto hidden when writing anything to the screen. This must be
handled by the coder. This makes it possible to hide the mouse and issue many
graphics commands and then turn it back on. This reduces flicker and speeds up
the program. If the mouse is not hidden before writing to the screen, mouse
droppings will appear if the mouse is moved.
This library will only work with the included compiler, likewise the compiler
will only work with this library. This is because not all of the bugs are in
the library, some are actually related to the compiler. The compiler also
requires the linker in this archive. Basically do not mix and match any
components of this archive with another. If so, expect unpredictable results.
Functions listed as VOID (~) return no meaningful result. Such functions
basically return garbage and should never be used. Relying on such results
will lead to problems.
A word about the debugging options. These options bloat the binary and slow it
down and should never be left in a final release if you plan to distribute the
application. If you want to send individuals debug versions that is acceptable.
Also, stack checking will only detect if the stack goes to deep under normal
use (sub-routine nesting) and recursion. It won't help much at all if you are
inside a C:() call when the stack goes to deep. The best you can do is set the
stack size of the application to meet the requirements of all the external
(non-GFA) calls it makes. Stack checks have very low overhead and can be left
in if used sparingly.
Note: The old compiler/linker automatically appended extenders. This caused
nothing but problems under MiNT and so this behavior has been removed. The path
that is passed will be used 'as is'. Thus it may not work correctly with old
shells or GUI frontends that worked around these issues. I still think this is
a bug in MiNT, but nobody wanted to fix it. MiNT does not correctly simulate
the old TOS file system correctly in this regard.
Memo: This package is only available in English. Due to lack of feedback I have
dropped all the other translations. The only real feedback I got was from the
ones that did the translations, which on average is one person per language.
There isn't that much text in these binaries anyway and it makes building the
tools much easier.
Interpreter notes
The runonly interpreter can be used stand alone from the Desktop. Either
drop files on the binary, or install it as an application on the Desktop with
extension *.gbs (GFA-Basic Source).
By default the editor will allocate about half the available ram. This can be
changed via a patchable area in the header of the binary.
The following long can be found (minus the quotes):
'GBE3'
Directly after this string is two longs:
ram to allocate (default is 0)
0 = allocate all the ram
1 = allocate half the ram
? = allocate exact amount specified
ram to keep free for the system (default is 16384)
? = exact amount specified (only applied if previous long = -1)
The full layout of the header in bytes is like so (minus the quotes):
"GBE3rrrrkkkk"
rrrr = long (ram to allocate)
kkkk = long (ram to keep free)
If rrrr is larger than the largest free block, then the interpreter will give
you what is available and set ERR to 8 to signal the setting has failed.
Notes
This section is just my personal thoughts about GFA-BASIC.
I've always been impressed with it, especially the subroutine folding. The
speed was always pretty good also. The ease of use is also quite good compared
to some other versions of BASIC. I also like that the library is built on
standards (DRI format). The auto indentation and instant syntax checking set
it apart from most other versions of BASIC.
After spending so much time working on it, I feel the compiler package was
rushed out the door. I highly suspect the Atari project was terminated before
Frank really had a chance to finish it. The compiler, linker, and the library
seem to contain debug code that was never removed or converted to error
messages. I'm referring to the ILLEGAL instructions found at various places.
These are often used to invoke a debugger. Unfortunately, since they were left
in, if the user manages to trigger one, it just dies unexpectedly with an
illegal instruction error (4 bombs). The end user is then left wondering what
the heck caused that and where in the code was it?!
There are a few other versions of BASIC, but you might not like or agree with
my comments, suffice it to say I think they suck. I'll leave it at that.
LDW Compiler (ST-BASIC)
The only other BASIC I am remotely impressed with isn't really a BASIC, but a
stand alone compiler. Also has a standard DRI library. This actually made
ST-BASIC usable. Quite a feat of programming if you ask me. I'm not
recommending anyone use this, just impressed at the effort put in to it.
Advanced debugging
Firstly one should read the original compiler manual, especially the $Ux
section. $Ux is the key to making the normal error trapping work. $U in its
simplest form inserts a single check. The so called 'check' does several
things. These are inserted between your GFA commands.
$U checks do the following:
prepare RESUME in case an error occurs (error handling)
check if the break key is pressed (with $I+)
check EVERY/AFTER timers (with $I+)
$Ux comes in 4 forms:
$U !insert a single check
$U+ !insert checks after every line that generates code
$U* !insert checks before every line
$U- !stop inserting checks
Debug levels. The compiler doesn't really have debug levels per say, but
depending on the nature of the bug hunt, it does have different ways to seek
them out. Some bloat the binary and/or degrade the performance more than
others.
The debugging begins with $T+. All this does is insert a call to a special
routine designed specifically to aid in debugging. It also makes line numbers
visible in normal error messages. You can activate more specific types of
checks you wish to have monitored.
The trace options are as follows:
Line number monitoring (default if on)
Line number saving to low memory (for really serious problems)
Line number is displayed on the screen
Single stepping the application (key press needed to continue)
Slowing the application down (slow motion)
Stack bounds checking
Here's a run down, based on the situation you might be trying to catch:
A line of code generates a normal GFA error and you want to know the line number.
Use: $T+ (best performance)
A line of code generates a bomb and you wish to know the line number.
Use: $T+,I+,B+
You suspect a stack overflow somewhere in the application.
Use: $T+,H+
A line of code freezes the machine and you are forced to hit the reset button.
Use: $T+,T# (worst performance)
If you want to see the line number in real time as the program runs...
Add: $T?
You want to single step the application.
Use: $T+,T~,T?
You want to slow the application down.
Use: $T+,T<,T?
If you want to alter the slow motion speed...
Add: $Tx (x=50th of a second delay)
If the machine froze, restart GBE after the reset and reload the source code.
Then use the new menu option in GBE: File -> Crash Report
This option will recover the last line executed and place the cursor on the
offending line. It also writes a crash report to the clipboard for those
that use assembler.
If you are not using GBE the line number can be found in the crash report
area of memory at address $3EC (word). Value of zero equals no crash noted.
If the value is <>0 then this is the line number it crashed at. This can also
be found in the crash report written to the clipboard.
Example using these new debugging commands:
REM #LIB new lib !set the library
'
$U* !insert error checks (needed by the break keys)
$T+ !add line numbers (error handler will then show line numbers)
$T# !save the line number to the crash report area (slower performance)
$H+ !we also want to check the stack bounds
$I+ !enable break keys (also needed by $B+)
$B+ !lets get crazy and trap bomb errors
$E$ !error messages as human readable text
'
ON ERROR GOSUB error_handler !install a custom error handler
CLS
trap_error: !jump here to continue after an error
DO
PRINT
PRINT "Press '1' for normal error"
PRINT "Press '2' for bomb error"
PRINT "Press 'ESC' to exit"
k&=INP(2)
IF k&=ASC("1")
@crash_normal
ELSE IF k&=ASC("2")
@crash_bomb
ENDIF
LOOP UNTIL k&=27
EDIT
'
PROCEDURE crash_normal
f=f/0 !division by zero!
RETURN
PROCEDURE crash_bomb
LONG{&HFFFFFFFF}=22 !bus error!
RETURN
PROCEDURE error_handler !my error handler, dump some info, then resume
PRINT "-- An error has been trapped --"
PRINT "ERR: ";ERR
PRINT "FATAL: ";FATAL !if = TRUE only 'resume label' is allowed
PRINT ERR$(ERR) !dump the alert string, so we can see the line number
RESUME trap_error !recover from the error, back to the main loop...
RETURN
Library versions
There are two versions of this library aimed at supporting different CPUs.
1) All 680x0 CPUs, designated '68K' version:
This means all Atari made machines, plus the Hades, and Milan.
Basically any 680x0 based Atari compatible or emulator.
2) Coldfire V4E, designated 'V4E' version:
Currently only the FireBee clone.
The two libraries are identical except for the following differences, which
are related to the FireBee. The V4E library is coded to be FireBee compatible.
1) move.b to/from the stack (sp) causes an odd stack address
2) 68020 mul/div instructions report incorrect results
3) Line-A opcodes cause an instruction conflict
4) tas instruction causes cache issues and thus random problems
Other than the above differences the libraries are identical. If you are a
program author and wish to support all Atari's and all clones, you will need
to release your program as two separate binaries. All that is required is a
simple recompile. I suggest using *.PRG for 68K binaries and *.APP for V4E
binaries this way they can have the same base name and still reside in the
same folder.
Example: GBE.PRG -> 68K version
GBE.APP -> V4E version
Why two libraries? Good question.
The main problem is the Line-A calls. On the FireBee the Line-A calls are
remapped to a totally different opcode range. This is because the normal ST
Line-A opcode range on the FireBee are now actual Coldfire instructions.
This causes a serious conflict. GFA offers access to the Line-A functions
even if you never use them. Removing all Line-A access would of been one
option, however it would of created a host of other problems.
The other issue is the patches themselves. Its possible to patch most of the
problematic instructions such that it will run on both CPUs, however in doing
so the patches cause the application to run slower on the 680x0 CPUs. It would
not be fair to impact the speed of the older machines in order to support the
FireBee.
In summary the benefits of two libraries are:
1) The FireBee gets GFA support
2) GFA on the 68K machines is unchanged, its fast and efficient
3) The Line-A calls are still supported in both libraries (both CPUs)
4) Applications can run on both CPUs simply be recompiling them
Additional notes:
The V4E version of the library produces binaries that will not run correctly
on an 68K machine. This is because the opcode to initialize the Line-A is
completely different.
The V4E library also requires the CF68KLib provided by FireTOS. Applications
made with GFA do not run at full speed because of this requirement.
The FireBee reports no FPU (cookie _FPU=0) thus the FPU enhancements do
nothing.
The FireBee reports its machine type (cookie _CPU=60) as a 68060, thus the CPU
enhancements should work as expected.
FireBee library code changes:
CLOSE [#x]
EXIST()
INSERT array|()
KILL\MKDIR\RMDIR\CHDIR
MAT RANG
RENAME\NAME
TT? -> div/mul/mod
DRAW
SCRP_WRITE()/APPL_FIND()/RSRC_LOAD()/FORM_ALERT()
SHEL_ENVRN()
SPACE$()/STRING$(x,x&)
CHR$()
str$=str$+"x"
VAL()/VAL?()
Note: The interpreter has some of the above issues plus a bunch more, far to
many to list here.
FireBee technical notes:
Current status:
Library - fixed, ~37 fixes applied (tested ok)
Compiler - fixed, ~34 fixes applied (tested ok)
Linker - fixed, ~2 fixes applied (tested ok)
GBE - fixed, ~7 fixes applied (tested ok)
Interpreter - fixed, ~160 fixes applied (untested)
It was ~8 hours of work spread across 50 assembler source files!
Memo:
GFA itself and anything built with it requires FireTOS (CFLib) and will not
run at full speed. GFA has not been rewritten for the Coldfire CPU, only the
CFLib incompatibilities have been solved.
It is possible to use a 68K dev system and build binaries for the FireBee. Its
also possible to use a FireBee dev system and build binaries for 68K machines.
All that is required is installing the correct version of GBE/compiler/linker
and both libraries (68K/V4E). The library used during the build process
determines the target machine.
You will need to release two versions of your software to satisfy all users.
This is related to the the Line-A incompatibly on the FireBee.
Its a case of... well... its better than nothing!
Problem #1:
Its a bit technical, but I'll try to explain it. As you know the Coldfire is
not 100% 68k compatible. Certain opcodes are not supported or handled
differently. The CFLib manages to solve quite a lot of these issues, but there
are a couple of instructions it cannot fix. One of them happens to be move.b
to or from the stack (a7). My guess is it cannot be trapped. Anyway, the 680x0
chips keep the stack even. If you push a byte, it pads it with a 0. Push '2'
as a byte for example and you end up with $0200 on the stack as a word. The
ColdFire on the other hand pushes just a byte and you end up with a stack on
an odd address.
There's two common occurrences in GFA where this instruction is used. One is
to temporarily null terminate a string (prep for some OS call), so the result
is the stack is odd at the moment an OS function is called. I don't really
know if that is good or bad. Something tells me its a bad idea, because at the
time the OS was written, the stack was assumed to be even. Maybe some one else
knows?
It can cause suboptimal execution times. Its able to read and write 2 and 4
byte values at odd addresses, but it takes more CPU cycles.
Something like this:
lea 0(a1,d1.w),a0 ;locate end of string
move.b (a0),-(a7) ;save end char addr (stack goes odd at this point)
pea (a0) ;save char addr
clr.b (a0) ;null terminated string
pea (a1) ;string addr
move.w d7,-(a7) ;op code
trap #@gemdos
addq.l #6,a7 ;fix stack
movea.l (a7)+,a0 ;restore end char addr
move.b (a7)+,(a0) ;restore end char
The other occurrence is used to decode words on an odd address (within the
token stream). This is where GFA buggers. To make matters worse the original
author of GFA exploited this instruction. He expects the processor to pad the
byte to a word, which has the side effect of shifting it left 8 bits if he
reads it back with move.w (sp)+. This goes completely wrong on the ColdFire
and GFA crashes. There's 158 occurrence of move.b to the stack in the original
editor alone.
Something like this:
decode_index: moveq #0,d0 ;clr
cmpi.b #$f0,(a5)+ ;check index size
bcs.s .1_byte_index ; byte? yes...
move.b (a5)+,-(sp) ;upper byte (a5=token stream, might be odd)
move.w (sp)+,d0 ;now its shifted left 8 bits
.1_byte_index: move.b (a5)+,d0 ;move lower byte into place (index decoded)
Here is an alternate explanation I found:
Picking up an unaligned word. The straightforward approach is to load 1 byte,
shift it into position, and load the second byte. The faster way (28 cycles
instead of 38) is to exploit the stack pointer's odd behavior when byte
quantities are pushed on the stack:
MOVE.B (A0)+,-(SP) ;First byte to high half of new word on stack.
MOVE.W (SP)+,D0 ;Pop that new word to D0. First byte in place.
MOVE.B (A0),D0 ;Second byte in place.
The majority of these are what I just described. The entire GFA package
contains 231 occurrences.
Problem #2:
Since the Coldfire supports tst.b on the stack, the CF68kLib cannot trap and
correct it when it's used on the stack. The Coldfire never rounds the stack up
to and even address.
move.w buf,d1
sne -(sp) ;put a flag on the stack (CF68kLib handles this one)
;misc...
; code...
; here...
tst.b (sp)+ ;test flag and removed it from stack (stack goes odd!)
beq.s blah...
Problem #3:
Line-A opcodes A000-A00F as used by the Atari ST for lower level gfx functions
conflict with Coldfire instructions. This opcode range is used by the Coldfire
for actual instructions and thus any program that uses Line-A opcodes fails.
The Line-A opcodes on the FireBee are mapped to the range A920-A92F. This is a
huge incompatibility issue and basically forced me to spin-off a new library.
I could of simply removed all Line-A calls from the library which would of
solved the problem. However, my goal has always been to keep the library as
close to the original as possible. It's still possible to write a demo, a game,
or a clean GEM app with GFA. The choice is still up to the coder.
As far as I know the FireBee only catches Line-A Init. A lot of packages make
this call in the start-up code. So long as no other calls are made these apps
should work on the FireBee.
Problem #4:
The 68020 instructions mul.l and div.l return incorrect results. These must be
recoded.
Problem #5:
This one is not really documented anywhere. I don't know if its a bug in the
Coldfire CPU or the FireBee, or a combination of the two, but the TAS
instruction does not work correctly. It causes random cache issues that
manifests itself as all sorts of weirdness. A program might run once, then
fail several times doing the same exact task. Just like move.b to the
stack it must be recoded and removed.
See CF68KLib.PDF (68K Emulation Library for Coldfire) for more detailed
information.
See also FireBee.HYP -> Crashes with the Coldfire
Moving from older libs to GBE Lib
GFA Library
Things that will need fixed:
Screen is auto cleared
FILESELECT screen saving/restoring
Auto mouse hiding/showing
GFA Patch
This library is nearly identical to the original library except all the
Line-A access has been removed.
LicomLib
This library has all the Line-A functions removed and many of the unclean
commands recoded to be clean. This library replaces all Line-A calls with AES
calls. These will need to be fixed by hand.
RUN!Lib
This library is based on LicomLib as far as I can tell.
Things that will need fixed:
(Re)DIM is not supported (ERROR #99)
Setting library options via INP() is not supported
Same issues as LicomLib.
Tutorials
CPU Error Detection
CPU and FPU Support
Detecting $M Failure
Optimizing with GBE
Compiler - change log
GFA-BASIC Compiler change log:
------------------------------------------------------------------------------
v3.7:
Extended function table support added
Removed option $D~ to suppress call to vqt_attributes() inside DEFTEXT
Many new commands and functions: AES, VDI, BIOS, XBIOS, GEMDOS, and LINEA
New feature added to GEMSYS
New feature added to GETSIZE()
$Zx range check enforced (3000)
$H renamed to $H1
$T renamed to $T1
bugs:
OPEN mode$ string length bug fixed
DEFFN inside a PROCEDURE/FUNCTION cause a structure error
DIM/ERASE inside a FUNCTION cause a structure error
RANDOMIZE/RANDOM() bug fixed
------------------------------------------------------------------------------
r29:
changes:
Added option $D~ to suppress call to vqt_attributes() inside DEFTEXT
------------------------------------------------------------------------------
r28:
bugs:
DEFFN/FORM INPUT could fail on the FireBee, 'tst.b (sp)+' fixed
------------------------------------------------------------------------------
r27:
changes:
Wrong CPU type returns error code -65
------------------------------------------------------------------------------
r26:
bugs:
DEFMOUSE parameter treated as a word, should of been a long
upper word was garbage, parameter was interpreted as an invald address
VSETCOLOR with combined rgb treated as a word, should of been a long
upper word was garbage, caused incorrect colors
APPL_TPLAY() address parameter treated as a word, should of been a long
------------------------------------------------------------------------------
r25:
Resync'd version number with linker
------------------------------------------------------------------------------
r24:
bugs:
Reverted start-up code change that was done at r16, broke desk accessories
Caused an invalid stack pointer
------------------------------------------------------------------------------
r23:
changes:
Added compiler command $L- to suppress user symbol output (routines/labels)
The object file created by the compiler will have no user symbols
Useful if linking with a 3rd party linker (avoid duplicate symbol error)
------------------------------------------------------------------------------
r22:
bugs:
END, EDIT, STOP generated no code if 1st line of PROCEDURE or FUNCTION
------------------------------------------------------------------------------
r21:
Dropped 'US' from the title
------------------------------------------------------------------------------
r20:
changes:
Structure test: reverted 'missing Case' test (issue with faceVALUE code)
------------------------------------------------------------------------------
r19:
bugs:
Structure test failed to save/restore a register (SELECT/CASE)
Fixed DEFFN bug (missing BRAanch instruction)
Failed if DEFFN followed a subroutine definition with no parameters
changes:
$L- command removed, Line-A will always be initialized (reverted)
$Hx command removed, stack size will always be 4kb (reverted)
$Tx command moved to $Zx (makes checking the compiler options easier)
Coldfire V4E support (FireTOS+CFLib)
Added '68K' or 'V4E' to the copyright depending on the compiler build
32 changes (move.b instructions to/from stack recoded)
68K version ran on a coldofre CPU will print an error message and exit
V4E version ran on a 680x0 CPU will print an error message and exit
------------------------------------------------------------------------------
r18:
Added compiler option $Whhhh
------------------------------------------------------------------------------
r17:
Recoded OUT, OUT&, and OUT% to support device numbers 6 to 9
------------------------------------------------------------------------------
r16:
Added a way to detect the revision
Optimized a few lines
CLEARW n and CLEARW #n now call different routines
CLEARW n was in the library but never used
CLOSEW n and CLOSEW #n now call different routines
CLOSEW #n will now generate an linker error if used with an old library
Start up code in the compiler output binary tweaked
Structure test will now detect missing CASE statements
Compiler option $Ux no longer locks up the compiler from the command line
Added command $Ax (program header -> memory protection)
private, global, super, readable
Added command $Ox (program header -> memory flags)
fastload, load alt, malloc alt
Added command $D+ (symbol table)
Added command $U* (insert checks before every command)
Added command $L- (skip Line-A initialization)
Added command $Kx (keep free)
Added commands $H, $H+, $H-, and $Hx (stack control)
Added commands $T, $T+, $T-, $T#, $T~, $T<, $T?, and $Tx (line tracing)
------------------------------------------------------------------------------
r15:
Reverted the '$F%' and '$X' modification, fixed the code which skips spaces
The command '$ F%' is now valid per the manual (extra white spaces)
------------------------------------------------------------------------------
r14:
Missing procedures and labels are now detected
RESTORE missing_label !fixed
Program would still run, but the wrong DATA line was restored
GOTO/RESUME missing_label !fixed
ON ERROR/ON BREAK GOSUB missing_proc !fixed
EVERY/AFTER x GOSUB missing_proc !fixed
ON MENU GOSUB missing_proc !fixed
ON MENU KEY/IBOX/OBOX/BUTTON/MESSAGE GOSUB missing_proc !fixed
ON x GOSUB missing_proc1,missing_proc2 !fixed
These were all fatal! -> JSR 0.L or JMP 0.L
Code removed which was suppose to skip spaces in '$F%' and '$X'
Code always failed anyway, thus this never worked '$ F%'
Added error code -3 (Procedure or label undefined)
If this error ever occurs, please contact me!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
------------------------------------------------------------------------------
r13:
Optimized GRAF_MKSTATE() fix
Unused code identified and removed
Unreleased
------------------------------------------------------------------------------
r12:
Program exit code is now a standard MiNT error code
Disk full error code (-1) changed to -91
Not enough memory error code (-8) changed to -39
File type/format error code (-100) changed to -26
------------------------------------------------------------------------------
r11:
$X with FUNCTIONs (with no parameters) sometimes added a stack correction
Incorrectly tested a filler byte (one token to far) at the end of the line
If the routine was called enough, it would eventually crash
------------------------------------------------------------------------------
r10:
$X with VAR parameters calculated the wrong amount of stack correction
If VAR was used the calculation was always too small
Caused the stack space to be slowly eaten away
If the routine was called enough, it would eventually crash
$X with FUNCTIONs (with parameters) produced no stack correction at all
Caused the stack space to be eaten away even faster
Norwegian/NO translation added
------------------------------------------------------------------------------
r9:
GRAF_MKSTATE() bug fixed
GRAF_MKSTATE() with no parameters whatsoever was fatal
DIM bug fixed
A line such as DIM (1,2,3,4,5,6,7,8) was fatal
This will now generate a logical error message
MAT INPUT bug fixed
A line such as MAT INPUT x() was fatal
This will cause input to be accepted on the console as expected
MAT DET/QDET/RANG bug fixed
A line such as MAT DET a(1,1),float was fatal
Crashes related to undefined functions within structure commands fixed
A line such as IF @my_func(params)=0 could be fatal, but not always
It will now halt at the first undefined function
MSHRINK() always failed (returned error code -40)
This command now works as it should
Slightly cleaner start up code in the compiled application (NOP replaced)
The NOP caused a weird problem with MagicPC + JIT compiler enabled (Ingo)
ILLEGAL instructions in various parts of the code replaced
Should any of these errors occur it will report the error and exit cleanly
Header flags are preset to use fastram if you have it
This actually speeds up the compile process
Recompiled with Devpac's optimizations enabled
------------------------------------------------------------------------------
r8:
Added a new real time line counter option
The old interrupt method is still in place, but should be avoided
Would crash sometimes on my 060 with MiNT, as it was rather unstable
The new counter is only available via GBE (v1.4 and up)
------------------------------------------------------------------------------
r7:
Pdomain() call added for better long file name support
------------------------------------------------------------------------------
r6:
Swedish/SE an Slovenian/SI translations added
------------------------------------------------------------------------------
r5:
French/FR translation added
------------------------------------------------------------------------------
r4:
German/DE translation added
------------------------------------------------------------------------------
r3:
Typos and incorrect wording in text strings corrected
It would appear nobody at GFA did any proof reading ;o)
------------------------------------------------------------------------------
r2:
Crash under MagiC (and MagiC-PC/Magic-Mac) fixed
MCB was destroyed, thew out the DeepSleep fix, reworked the statup code
------------------------------------------------------------------------------
r1:
Double extender bug fixed (*.gfa.gfa)
This occured on certain file systems, mostly those that support long names
File names default to lower case
All the default file names stored in the binary are now lower case
------------------------------------------------------------------------------
r0:
Disassembly started with the English/US version
A binary match was established
Linker - change log
GFA-BASIC Linker change log:
------------------------------------------------------------------------------
v3.7:
Resync'd version number with compiler
------------------------------------------------------------------------------
r29:
Fixed default library name based on build type (lib_68k/lib_v4e)
Fixed very obscure bug, liraries with a certain module count broke the linker
Fixed test on maximum command line length (was 96, changed it to 126)
Clobbered the command line length byte, forgot to skip command line length
If one drag&drop'd test.o from desktop, tried to link test.o twice
------------------------------------------------------------------------------
r28:
Resync'd version number with compiler
------------------------------------------------------------------------------
r27:
Improved Coldfire V4E support (FireTOS+CFLib)
68K version ran on a coldfire CPU will print an error message and exit
V4E version ran on a 680x0 CPU will print an error message and exit
Wrong CPU type returns error code -65
------------------------------------------------------------------------------
r26:
Resync'd version number with compiler
------------------------------------------------------------------------------
r25:
First coldfire release. TAS instruction fails on the FireBee.
Added '68K' or 'V4E' to the copyright depending on the compiler build
------------------------------------------------------------------------------
r24:
Resync'd version number with compiler
------------------------------------------------------------------------------
r23:
Resync'd version number with compiler
------------------------------------------------------------------------------
r22:
Resync'd version number with compiler
------------------------------------------------------------------------------
r21:
Index file magic is now tested, new error message 'Index format invalid'
Library file magic is now tested, new error message 'Library format invalid'
Dropped 'US' from the title
------------------------------------------------------------------------------
r20:
Resync'd version number with compiler.
------------------------------------------------------------------------------
r19:
Resync'd version number with compiler.
Small code change, saved a few bytes.
Coldfire V4E support (FireTOS+CFLib)
added '68K' to the copyright notice, works on both CPUs as is
0 changes (no move.b instructions to/from stack)
------------------------------------------------------------------------------
r18:
Resync'd version number with compiler
------------------------------------------------------------------------------
r17:
Resync'd version number with compiler
------------------------------------------------------------------------------
r16:
Version numbers sync'd (easier to keep track of changes)
Added a way to detect the revision
Optimized a few lines, removed some unused code
Obscure bug fixed (failed to report offset errors)
Missing error messages added (Relocation error)
Added MiNT fxattr() -> fchmod() calls for non-TOS file systems
Added special support for new compiler commands (program header and symbols)
------------------------------------------------------------------------------
r9 to r15:
skipped (see r16 notes)
------------------------------------------------------------------------------
r8:
Program exit code is now a standard MiNT error code
Disk full error code (-1) changed to -91
Fatal error code (-2) changed to -12
------------------------------------------------------------------------------
r7:
Norwegian/NO translation added
------------------------------------------------------------------------------
r6:
ILLEGAL instructions in various parts of the code replaced
See compiler notes, same changes made
Header flags are preset to use fastram if you have it
See compiler notes, same changes made
Recompiled with Devpac's optimizations enabled
------------------------------------------------------------------------------
r5:
Libraries with extenders didn't work (*.lib)
It will now properly handle libraries such as 'custom.lib'
------------------------------------------------------------------------------
r4:
Failure under MagiC corrected (gemdos error)
This was related to how the linker determines file sizes
Swedish/SE an Slovenian/SI translations added
------------------------------------------------------------------------------
r3:
French/FR translation added
------------------------------------------------------------------------------
r2:
German/DE translation added
------------------------------------------------------------------------------
r1:
Double extender bug fixed (*.o.o)
This only occured if linking additional object files into a project
See compiler notes, same exact problem
File names default to lower case
See compiler notes, same changes made
------------------------------------------------------------------------------
r0:
Disassembly started with the English/US version
A binary match was established
Library - change log
GFA-BASIC Library change log:
------------------------------------------------------------------------------
v3.7:
changes:
Many new commands and functions: AES, VDI, BIOS, XBIOS, GEMDOS, and LINEA
New feature added to GEMSYS
HIMEM reverted back to a useless pointer
Remove switches from:
MOUSE x,y,k
DEFMOUSE shape$
GET x1,y1,x2,y2,t$
HIDEM, SHOWM, MOUSEX, MOUSEY, MOUSEK, CURVE, RC_COPY, GETSIZE(), VSETCOLOR
STE? function removed bits 2-18
GDOS? extra feature removed
bugs:
OPEN mode string length must be 1 or error code #21 is issued
OPEN memory leak related to error code #22 fixed
------------------------------------------------------------------------------
r18:
changes:
POINT() reverted TC fix, use this instead: pixel%=LONG{LONG{GB+80}}
DEFTEXT height was setting ptsin(0), not required per NVDI
DEFMARK height was setting ptsin(0), not required per NVDI
HIMEM option will speed-up DEFTEXT (internal GFA window call skipped)
VDIBASE now points to GFA's internal VDI parameter block
GEMSYS 16 now supports appl_bvset()
HIMEM option to change padding character used in STR$()
bugs:
VST_LOAD_FONTS() binding fixed, intin() count was wrong
These do not have a return value according to the NVDI docs:
V_CLSWK(), V_CLSVWK(), V_UPDWK(), V_CLRWK(), VQT_EXTENT()
------------------------------------------------------------------------------
r17:
changes:
DEFMOUSE num optimized (smaller)
DEFMOUSE str recoded for readability
BLOAD error handling improved
STICK x recoded to be MiNT friendly
STICK(0/1)/STRIG(0/1) recoded to be MiNT friendly (standard st ports)
V_OPNWK()/V_OPNVWK() previous fix optimized (smaller)
POINT() reverted back to using gfa's internal vdi arrays (smaller)
some coldfire code optimized (smaller)
RC_COPY coldfire changes removed, was never needed
SHEL_WRITE() coldfire changes removed, was never needed
bugs:
MODE build date conversion tweaked
DRAW could fail on the FireBee, odd stack address
------------------------------------------------------------------------------
r16:
bugs:
Multi-dimensional array limit of 65535 was not properly enforced
------------------------------------------------------------------------------
r15:
changes:
TT? tweaked such that it only enables the enhancements exactly once
MODE tweaked such that it only converts the app build date exactly once
HIMEM entry for bitmap size is now unused
GETSIZE() is Line-A function again, with an added VDI option (see HIMEM)
some ERROR messages reworded
ERROR #72 added -> 'Invalid _DATA pointer'
ERROR #35 removed, no reference
OPEN had a line of unused code removed
Stack size bumped to 8192 bytes (was 4000 bytes)
all extra asm modules removed from the library (lack of interest)
bugs:
GETSIZE() bitmap size calculation corrected for 15-bit modes
GET (gfx) string size calculation corrected for 15-bit modes
_DATA= now does bounds checking and issues error code #72 if out of range
_DATA fixed to return 0 if the next READ will result in 'out of data'
fixed routine that outputs error messages as text if AES not linked
FOR-NEXT loops with floats issued wrong error code, #8 should of been #91
INPUT # issued wrong error code, #35 should of been #25
------------------------------------------------------------------------------
r14:
changes:
SOUND fix improved that was introduced at r11
PI will be tweaked slightly for better results only if the FPU is enabled
bugs:
ERROR handler didn't pass out all error codes correctly via pterm()
negative error codes were ok, but positive ones ended up negative
------------------------------------------------------------------------------
r13:
changes:
break key error code changed to #-68 (user aborted process)
GEMSYS 'n' updated to N.AES v2.0 specifications (range 10 to 135)
reverted table entry appl_yield(17), original entry was correct
added table entry appl_search(18)
fixed table entry menu_popup(36)
added table entry menu_attach(37)
added table entry menu_istart(38)
added table entry menu_settings(39)
added table entry objc_sysvars(48)
added table entry objc_xfind(49)
added table entry graf_multirubber(69)
added table entry wind_draw(99)
added table entry wind_new(109)
added table entry rsrc_rcfix(115)
reverted table entry shel_rdef(126), original entry was correct
fixed table entry shel_wdef(127)
added table entry shel_help(128)
added table entry appl_control(129)
fixed table entry appl_getinfo(130)
added table entry form_popup(135)
PCIRCLE binding improved, unused ptsin entries removed
PCIRCLE (extra parameters) binding improved, unused ptsin entries removed
CIRCLE binding improved, unused ptsin entries removed
DEFLINE binding improved, unused ptsin entries removed
DEFMOUSE str option moved to HIMEM
VSETCOLOR range option moved to HIMEM
GET has option to use VDI function vro_cpyfm() (see HIMEM)
CURVE has option to use VDI function v_bez() (see HIMEM)
RC_COPY has option to use VDI function vro_cpyfm() (see HIMEM)
MOUSEx has option to use AES function graf_mkstate() (see HIMEM)
HIDEM/SHOWM has option to use AES function graf_mouse() (see HIMEM)
bugs:
EVERY/AFTER not working in SingleTOS (register clobbered)
------------------------------------------------------------------------------
r12:
changes:
FUNCTIONs date$() and time$() added
unused buffer removed from the BSS section (uses less ram)
bugs:
TAS instruction not working on the FireBee (PRINTing in GFA windows)
------------------------------------------------------------------------------
r11:
changes:
SOUND command had an unused word table wasting space (removed table)
DMASOUND command now supports 16-bit palyback on the Atari Falcon030
reverted changes to CRSCOL and CRSLIN (back to being Line-A calls)
reverted changes to PRINT (back to being a bios() call)
DEFMOUSE str enhanced to call the graf_mouse()
PROCEDURE print/printe/printx added (cconws())
KEYDEF code size further reduced
KEYPAD does nothing (new features reverted)
ERROR #22, #23, #48, #92 reworded
bugs:
PADT() contained a bug, incorrect bit test
------------------------------------------------------------------------------
r10:
changes:
DEFMOUSE >65535 -> address of a valid mouse shape structure (user_def)
saved 32 bytes in the bss segment, uneeded buffer removed
ERROR code #60 reworded to be more generic 'String length wrong'
added error #101 as human readable text
SPRITE command sped up, unneeded register saves removed
duplicate line of code removed
VQT_EXTENT() no longer clips the string off
TEXT command sped up, no longer clips the string off
null strings will not be passed to the VDI, command is ignored
INTIN() array expanded to 512 elements
POLYxxx commands no longer clip the PTSIN() array off
TITLEW/INFOW no longer clips the string off
W_INDEX() will return -1 if the AES window handle is not found
VDIBASE patch reverted, VDIBASE points to the WORK_OUT() array
CLOSEW reworked previous patch for better top window detection
CLOSEW # only closes and deletes the window, does no topping or clipping
STE? function extended with more bit flags
MENU m$() removed limit of 10 characters on menu titles
UPPER$() minor optimization
FUNCTION lower$() added
FUNCTION mirror$() added
FUNCTION crypto$() added
FUNCTION ltrim$()/rtrim$()/ztrim$() added
PROCEDURE memset and memzero added
FUNCTION memfind() added
FUNCTION crc16()/crc32() added
FUNCTION imgsize() added
PROCEDURE sget/sput added
PROCEDURE get/put added
FUNCTION lcase$()/ucase$() added
FUNCTION xlate$() added
FUNCTION strpeek$() added
PROCEDURE strpoke added
FUNCTION pack()/unpack() added
Added GFA-Vector calls
FUNCTION countchr() added
DTA is only set if running as PRG
there is no command line to clobber if running as ACC
if $Mxxx is not set ERR=8 at start-up
FATAL=TRUE at start-up if the program is running on the wrong CPU type
reverted r7 CPU type error message
its now up to the coder to test FATAL at start-up and react accordingly
bugs:
APOLY failed to set line-a offset mfill
the docs state APOLY uses the same parameters as HLINE which sets mfill
APPL_TPLAY(num,speed,mem) patch reverted to match editor parameter order
STORE/RECALL no longer generates error #28
OPENW # (6 parameters) fixed a bug related to index 0 (desktop)
CLEARW n failed to check if the window was open before clearing it
FDIV/FMOD fixed (see function TT?)
MENU_TEXT() crashed on non-menu object strings
removed routine to clear the BSS, caused a crash under magic (unneeded)
incorrectly calculated the end of the BSS segment
------------------------------------------------------------------------------
r9:
changes:
dropped 'US' from the title
RECALL string limit of 8000 characters fixed (now supports strings up to 32k)
------------------------------------------------------------------------------
r8:
changes:
removed an unneeded line of code from function x=L~A
binding for GDOS? improved to match offical documentation
------------------------------------------------------------------------------
r7:
new features:
TEXT x,y,t$ -> calls v_gtext() for more speed (without the length parameter)
allows 128 character output
CHDRIVE now reports errors (-46 invalid drive specification)
SEEK change reverted (same code as editor)
error code #-1 changed to #-37 (device detection)
DEFMOUSE x& will default to the arrow (0) shape if user_def (255) is passed
fixed binding per AES docs
PRINT tweaked for more speed
VDIBASE now points to the results of vq_extnd() (57 words) see VDI docs
example: planes&=WORD{VDIBASE+8}
minor code improvements in buffer.s
minor code improvement in fpow.s
minor code improvement in windows.s
EOF()/LOC()/LOF() error code changed to #-37
minor code improvement in loc.s
EXIST() code size reduced, optimized to avoid the stack
DIR$() code size reduced
HIMEM now means 'hidden memory' and points the library structure
VQT_NAME() fix improved
bss segment aligned to a 4 byte boundary (030 and up optimization)
bss segment internal variables cleared to match the editor
unused symbol removed related to the KEYPAD command
TOUCH error code #-1 changed to #-37 (device detection)
RECALL error code #-1 changed to #-37 (device detection)
KILL/MKDIR/RMDIR/CHDIR optimised to avoid the stack
NAME optimized to avoid the stack
RC_COPY optimized to avoid the stack
added a Coldfire CPU flag to the library structure
added maximum string length for TEXT to the library structure
Library structure -> flush cache entry removed
Coldfire V4E support (FireTOS+CFLib)
added '68K' or 'V4E' to the copyright depending on the library build
34 changes across 14 modules (move.b instructions to/from stack removed)
TT? mul/div/mod changed
68K apps ran on a coldfire CPU will print an error message and exit
V4E apps ran on a 680x0 CPU will print an error message and exit
KEYPAD command expanded
KEYDEF command expanded
STE? function expanded
changes:
Line-A always initialized (reverted previous Line-A change)
stack size always 4kb (reverted previous stack change)
bugs:
uninitialized pointer in cookie jar code caused a crash under SingleTOS
wrong parameter going into vsm_height()
POLYxxx point limit lowered to 128 (was 512 which caused a buffer overrun)
limit now matches what the error message (too many points) has always said
TIMER saves critical registers (used internally)
MENU KILL failed to clear the event flags, clobbered MENU(0) instead
thix fix was incorrectly applied (broke ON MENU xxx GOSUB commands)
PRINT "" crashed (or any expression resulting in a null string)
BLOAD previous fix partially broke error handling (device detection)
error code #-1 changed to #-37 (device detection)
INPUT(#x) error code #-1 changed to #-37 (device detection)
INPUT #x error code #-1 changed to #-37 (device detection)
LINE INPUT #x error code #-1 changed to #-37 (device detection)
RECALL string length bug fixed
------------------------------------------------------------------------------
r6:
bug fixes:
start up code changed, if appl_init() fails, abort any further AES calls
this makes the code more /auto folder friendly
PRINT recoded, only the console is redirected through gemdos
previous change broke all device output, effected several commands
incorrectly evaluated the _MCH cookie, failed to check the minor revision
enhanced joysticks are not actually present on the megaste and the stbook
reverted VDIBASE, this now points to the base of the WORK_OUT() array
thus xrez&=WORD{VDIBASE}, yrez&=WORD{VDIBASE+2}, etc...
reverted CURVE, turns out v_bez() requires gdos, thus fails without gdos
TOUCH never worked, incorrect parameters were passed to the gemdos() call
FILESELECT now handles long file names (max characters: path=256/file=64)
FSEL_INPUT() now handles long file names (max characters: path=256/file=64)
-negative error codes didn't display correctly in ASCII (such as ERROR -64)
fixed workstation defaults, invalid parameter passed to vsl_style()
parameter passed in the wrong register as well (clobbered)
MENU m$() did not honor the width returned from graf_handle()
MENU KILL failed to clear the event flags, clobbered MENU(0) instead
the library structure is now hidden behind the DTA (see BASEPAGE)
removed some more unused code
removed an unused symbol
INP(), INP?(), OUT?() will now report bios errors
INP&(), INP%() now support device numbers 6 to 9
OUT, OUT&, OUT% now support device numbers 6 to 9
new features:
VSETCOLOR now supports RGB values 0-1000 if bit #8 of the index is on
POINT() reverted for compatibility, 32-bit return value found in INTOUT(0/1)
added interpreter/compiler flag to the library structure
------------------------------------------------------------------------------
r5:
module changes:
reverted rinstr() back to the original code
accidently left dev code in the lib which broke rinstr()
needs more study before it can be safely fixed
reverted instr() back to the original code
just in case (for compatibility reasons)
needs more study before it can be safely fixed
------------------------------------------------------------------------------
r4:
program start up:
cleaned up (pretty much a complete rewrite)
temporary stack change removed
added support for adjustable stack sizes (programs only)
desk accessories will be given the old 4000 byte stack as before
bios() CLS removed
if you want the screen cleared, use the CLS command
initialization as desk ACC improved, mshrink() avoided (not needed)
proper detection of the CPU, FPU, SND, and MCH cookies
CLIP OFF no longer required, clip initialization corrected
incorrectly used Line-A variables (corrected with VDI values)
DTA is now preset, the command line won't get clobbered as before
user need not worry about such things anymore (it's only 44 extra bytes)
MiNT calls used if present, to avoid the use of super() calls
misc stuff:
all internal references to Hidem and Showm removed, smaller/faster library
it's up to the coder to hide and show the mouse at all times
unused code found and removed
internal I/O buffering
bogus error code corrected, should of been error #24
incorrect error code #13 corrected, should of been error code #-36
removed break key checks from all modules (was interrupt driven)
if the temp string pool ever fills up, wrong error code was issued
was #14, changed to #43 to match the editor 'expression too complex'
$B+ fixed for debugging use under MiNT, but should be avoided otherwise
$Ux self modifying code fixed (only happened in very short programs)
conterm system variable fiddling removed
$I+
all interrupts and system vector hooks removed
keyboard interrupt removed (keypad)
KEYPAD and KEYDEF left as is, but have no effect if used
timer interrupt removed (EVERY/AFTER)
EVERY/AFTER still work, but no longer interrupt based
possibly less accurate?
only checked after each GFA command which generates code
Line-A seed fill vector hook removed
etv_critic GEMDOS() vector hook removed
break key works as it used to (ON BREAK xxx)
only checked after each GFA command which generates code
ALERT
allows 5 lines, with 10 char buttons, allows newer AES icons 4 and up
was limited to 4 lines with 8 char buttons
icon was limited to 0-3
default button parameter is now limited to 0-3 (crashed some AES versions)
APPL_EXIT()
now returns the correct value based on if APPL_INIT() failed
APPL_INIT()
should force the linker to link the AES init code
really isn't that the point in calling it?
on 2nd thought no, this will now return -1 per the AES specs if init failed
APPL_TPLAY()
corrected parameter bug (now works as documented)
ARRAYFILL
an undimensioned array will now report error #15 as it should
BITBLT s(),d(),p()
it never did set the MFDBs reserved fields even if passed
dose it matter? left as is (technically fast this way)
BLOAD
no longer clobbers channel #89 (now uses an unused channel)
no longer uses an fread() trick with a file size of $00FFFFFF
MagiC choked on this (this is a bug in MagiC, works fine in TOS)
fseek() is used instead to obtain the exact file size
BSAVE
no longer clobbers channel #89 (now uses an unused channel)
CLEARW
this command now works (failed on gfx cards)
CLEARW n and CLEARW #n now call different library routines
Line-A blit replaced with a VDI blit
CLOSE
lack of error reporting corrected, reports error #23 and #24
CLOSEW #n
added to the compiler (was an unused token)
will cause a linker error if used with old libs
however both tokens call the same lib routine
top window detection fixed (clipping was incorrectly set on non-gfa windows)
the library was developed during SingleTOS days, CLIP #n might be needed
to reset the clip, before outputing to an old GFA window
CLS
only outputs ESC+E (dropped the extra CR)
CRSCOL/CRSLIN
removed Line-A variables, calls VDI vq_curaddress() instead
DIM
error code #14 'array dimensioned twice' now works
error code #17 'dim index too large' now works
DEFMOUSE
parameter range expanded to except a full 16-bit word (Geneva support)
user_def(255) is ignored if passed
use GRAF_MOUSE() to set a user defined mouse form
DFREE()
handles larger hard drives (up to 2gb)
incorrectly used words to compute the drive space
didn't pass out an error code correctly
drives over 2gb are still a problem, limit imposed by GFA's long% variables
DIR/FILES
(with TO) clobbered channel #87 (a free channel will be used instead)
no longer resets the DTA address back to BASEPAGE+128
the current DTA address is used (setup at startup)
DIR$()
invalid drive identifiers will now be reported
typically error -46 if the drive does not exist
EOF(), LOC(), and LOF()
lack of error reporting corrected, reports error #23 and #24
ERR
should contain 0 (no error at start)
if the amount of ram in $Mx can't be met, will be set to 8 (out of memory)
ERROR/ERR$()
typos in error messages corrected
error code #0 'division by zero' moved to #7 (#7 was undefined)
0 passed out via pterm() means ok, thus it could not be detected
library revision inserted into ERROR #100 (copyright notice)
bios() and gemdos() error messages updated to more current OS wording
missing error messages added: #2, #11, #16, #43
error messages that are impossible to receive in compiled apps removed
#0, #25, #55, #63, #91
generic error message (numbers only) now has 'GFA-BASIC' added to it
this way it's more clear where the error came from
error messages sent to the console now have the alert box format removed
error trapping corrected, no more crashes at
LOF(), ADD(), ASIN(), MOD(), and ^(power)
EXIST()
recoded to work correctly with long file names
FIELD, GET #, PUT #, RECORD
all related errors corrected
error #54 was reported as error #8
errors #23, #24, #50, #52, and #54 were reported as error #111
FILESELECT, FILESELECT#
AES version number check corrected
no longer forces uppercase if multi-tasking is detected
screen buffering removed (only worked in ST modes)
if you really want screen buffering in 32k modes, use SGET/SPUT
FORM_CENTER()
jumped to wrong label, but worked anyway, now corrected
FRE()
garbage collection bug fixed (related to string handling)
caused random unexpected crashes that could not easily be explained
FSETDTA, FGETDTA
removed from the library (compiler inlines them anyway)
the lib no longer changes the DTA address
the lib now uses the current DTA address (setup at startup)
FSFIRST
duplicate code removed (library slightly smaller)
GDOS?
extended to return the GDOS type in INTOUT(0/1)
type%=LONG{INTOUT}
GET, PUT
undocumented feature, if bit #4 of mode is set, VDI blit is used
vro_cpyfm() is used instead of Line-A blit
several bugs fixed, was mostly non-functional
GETSIZE()
Line-A variables removed (uses VDI values instead)
simply subtract 6 for standard bitmaps (+6 is the string header for GET/PUT)
INP(#c), INP&(#c), INP%(#c)
lack of error reporting corrected, reports error #24
INPUT$(#c,n)
lack of error reporting corrected, reports error #24
INSTR()
with 3rd parameter fixed INSTR(a$,b$,i) or INSTR(i,a$,b$)
if i=0 -> i=1 (test continues)
if i<0 -> returns 0
if a$="" -> returns 0
if b$="" -> returns 0
if len(a$)<len(b$) -> returns 0
if i>len(a$) -> returns 0
KEYPAD, KEYDEF
ignored if used (were interrupt based)
LINE-A
graphics commands are untouched, these are usable but discouraged
all internal calls to hidem removed
LPRINT
never worked correctly on the Falcon030 (corrected device handle)
MENU m$()
did not work correctly with N.Aes (hidemenu=true) option
MENU_REGISTER()
corrected, buffer decreased to normal size
strange buffer scheme removed
added support for reg_newname(-1)
MENU_TEXT()
left the AES pointing to a GFA string (eventually GFA moves the string!)
copies new string over top old string
will be padded with spaces if too short
if string passed is too long, it will be clipped
OPENW
works now, and text scrolling is handled via vdi vro_cpyfm()
line-a calls removed (failed on gfx cards)
fixed the strange bold attribute inside windows with printing (vdi bug)
OPTION BASE 1
now works with numeric and string arrays (compiled)
strange crashes were reported
PADx, LPENx, STICK(2-5), STRIG(2-5)
theser are now detected correctly
these used to be enabled based on the '_SND' coookie
they should only be enabled on STE and Falcon030 machines
POINT()
didn't work correctly on gfx cards with more than 256 colors
fixed bindings (worked anyway, but now its correct)
returns a full 32-bit long in INTOUT(0/1) (high color/true color support)
up to the coder to decode the pixel format
PRINT
uses gemdos cconws(), printing can now be properly redirected
printing is faster, was calling bios bconout() per character
PRINT USING
no longer uses the base of the stack as a temporary buffer
QSORT, SSORT
contains self modifying code
problem resolved, should work on any setup
RESERVE
under multi-tasking will be ignored
cannot be used reliably because ram is managed differently in SingleTOS
RETURN
2 illegal instructions, replaced with error code #93 'stack error'
if it ever happens (doubt it) it will attempt to recover via the error handler
RC_COPY
undocumented feature, if mode>255 its treated as an op_tab
see Line-A documention for more information
SEEK/RELSEEK
duplicate code removed (library slightly smaller)
crash with bad channel number corrected (stack error)
lack of error reporting corrected, reports error #24
SOUND, WAVE
recoded all MOVEP instructions
minor bug related to #period, 0 is now properly detected and bumped to 1
STE?
returns information about STE hardware support
bit 0 = if set the machine has enhanced joystick ports (STE/Falcon030)
bit 1 = if set machine has stereo 8-bit playback
STOP
German break key alert message translated to English
added 'GFA-BASIC' to alert message
STORE, RECALL
error code corrected, was #23, should of been #24
added check for undimensioned arrays, error #15
added check for 1 dimensional arrays, error #28
could issue bogus error messages, error #-36 is now issued
strings over 9100 characters caused a crash, added limit of 8000 characters
if this limit is exceeded it will issue error #10 'string too long'
no longer uses the temporary string pool/stack as a temporary buffer
STRING$(cnt,s$)
fixed incorrect error code, was #15, should of been #10 'string too long'
STRING$(cnt,asc), SPACE$()
didn't fully check string limits
error #10 is now issued as it should be 'string too long'
TEXT
character limit of 119 tweaked to 126 (7 more characters)
fixed bindings (worked anyway, but now its correct)
TIMER
redirected to gemdos ssystem() via MiNT if avaliable
auto fallback to old method, if MiNT is not found
TOUCH
lack of error reporting corrected, reports error #24
gemdos errors will also be reported
TT?
self-modifying code fixed (no more random crashing on an 060)
bit 0 = if set cpu => 68020
bit 1 = if set fpu detected
invoke CPU enhanced code for the following if the CPU is a 68020 or better
'float to integer' -> BFFFO
long multiply using muls.l (signed) -> LMUL
long division using divs.l (signed) -> LDIV
long modulo using divsl.l (signed) -> LMOD
invoke FPU enhanced code for the following if an FPU (68881/68882) is found
(A)SIN, (A)COS, (A)TAN, LOG(10), EXP(), SQR(), FDIV, FMOD
VDIBASE
use to point outside the apps memory space to an undocumented VDI structure
it now points to an internal structure with some useful information
VSETCOLOR i,rgb
no longer swaps the red and blue values
VQT_NAME()
does not clobber INTOUT(33) anymore
INTOUT(33) can contain extra font info, see VDI docs
V_OPNWK(), V_OPNVWK()
with the extra parameters fixed
W_HAND()
did not handle index 0 correctly (desktop)
the editor also has this same bug
_X, _Y
was using Line-A variables
initialized to VDI WORK_OUT(0/1)+1
so long as one avoids the old window commands, these don't change
------------------------------------------------------------------------------
r3:
Famous string handling bug related to FRE() fixed
Thanks to Mikko Larjava and Ingo's tip
Unneeded BSR removed from BMOVE and EXEC (mouse)
Removed unneeded carriage return from CLS
Error message #100 updated to reflect revision
------------------------------------------------------------------------------
r2:
Fixed some badly worded error messages
Started to add several translations:
German/DE, French/FR, Slovenian/SI (completed)
Swedish/SE (incomplete), Norwegian/NO (missing)
r1:
Cleaned up init.o/hidem.o sources (Line-A patches)
------------------------------------------------------------------------------
r0:
Disassembly started with the English/US version + GFA Patch v1.07
A binary match was established
Interpreter - change log
GFA-BASIC Interpreter change log:
------------------------------------------------------------------------------
v3.7:
changes:
Extended function table support added
Many new commands and functions: AES, VDI, BIOS, XBIOS, GEMDOS, and LINEA
New feature added to GEMSYS
New feature added to GETSIZE()
HIMEM reverted back to a useless pointer
Remove switches from:
MOUSE x,y,k
DEFMOUSE shape$
GET x1,y1,x2,y2,t$
HIDEM, SHOWM, MOUSEX, MOUSEY, MOUSEK, CURVE, RC_COPY, GETSIZE(), VSETCOLOR
STE? function removed bits 2-18
GDOS? extra feature removed
BLOAD will issue error code #64 if address = 0
BLOAD "path" used without first doing BSAVE (last used address = 0)
bugs:
OPEN mode string length must be 1 or error code #21 is issued
ON ERROR GOSUB sent GBE the wrong line number in the AES message
WAVE env parameter limit increased from 2 bits to 3 bits
DEFFN inside a PROCEDURE/FUNCTION cause a structure error
DIM/ERASE inside a FUNCTION cause a structure error
Non-fatal bug in start-up code caused CMDLINE$ to report error #60
------------------------------------------------------------------------------
r18:
changes:
POINT() reverted TC fix, use this instead: pixel%=LONG{LONG{GB+80}}
DEFTEXT height was setting PTSIN(0), not required per NVDI
HIMEM option will speed-up DEFTEXT (internal GFA window call skipped)
Moved menu tree object and string buffers to the BSS segment
Moved window title buffers to the BSS segment
HIMEM+80 will return the line number where the last error occurred
ERROR was recoded slightly to export the line number
VDIBASE now points to GFA's internal VDI parameter block
GEMSYS 16 now supports appl_bvset()
HIMEM option to change padding character used in STR$()
bugs:
ON ERROR GUSOB when triggered caused GBE to place cursor at end of program
VST_LOAD_FONTS() binding fixed, intin() count was wrong
These do not have a return value according to the NVDI docs:
V_CLSWK(), V_CLSVWK(), V_UPDWK(), V_CLRWK(), VQT_EXTENT()
------------------------------------------------------------------------------
r17:
changes:
DEFMOUSE num optimized, improved error handling
DEFMOUSE str recode for readability
MENU OFF, MENU x,y, and MENU x,t$
will issue ERROR #62 if there is no active menubar
TOUCH error handling updated to match the library
STICK x recoded to be MiNT friendly
STICK(0/1)/STRIG(0/1) recoded to be MiNT friendly (standard st ports)
POINT() reverted back to using gfa's internal vdi arrays (smaller)
SHEL_WRITE() coldfire changes removed, was never needed
bugs:
MODE build date conversion tweaked
MENU a$() always issued ERROR #62, was completely broken
RC_COPY (VDI variant) with optional mode parameter caused a crash
DRAW/DUMP/FULLW/RESUME/TRON could fail on the FireBee, odd stack address
------------------------------------------------------------------------------
r16:
bugs:
Random crashes when started fixed
Not working from fastram fixed
Structure error not detected if called from GBE (bad include file)
DIM var(1,2,3,4,5,6,7,8) seems to work, compiler has limit of 7 dimensions
ERROR #18 will be issued if more than 7 dimensions are used
Multi-dimensional array limit of 65535 was not properly enforced
------------------------------------------------------------------------------
r15:
changes:
MODE tweaked such that it only converts the app build date exactly once
HIMEM entry for pack/unpack routines are now unused
HIMEM entry for date/time routines are now unused
HIMEM entry for bitmap size is now unused
GETSIZE() is Line-A function again, with an added VDI option (see HIMEM)
TT? tweaked such that it only enables the enhancements exactly once
some ERROR messages reworded
ERROR #20 removed, duplicate of #33 (GOTO tweaked)
Stack size bumped to 8192 bytes (was 4000 bytes)
bugs:
GETSIZE() bitmap size calculation corrected for 15-bit modes
GET (gfx) string size calculation corrected for 15-bit modes
INPUT # issued wrong error code, #35 should of been #25
CLEAR inside For-Next loop or subroutine wasn't detected, fatal
the library will not catch this error
RCALL issued wrong error code, #16 should of been #65
FN undefined functions issued wrong error code, #19 should of been #44
FOR-NEXT loops with floats issued wrong error code, #8 should of been #91
ERROR/ERR$() paramter range adjusted to reject =>127
------------------------------------------------------------------------------
r14:
changes:
SOUND fix improved that was introduced at r11
PI is tweaked slightly for better results only if the FPU is enabled
bugs:
special interpreter ram setting '1' could cause 3 bombs (a1 ended up odd)
DRAW "XX" could crash with invalid 'XX' commands, added strict checks
invalid 'XX' commands will issue error code #9
------------------------------------------------------------------------------
r13:
changes:
aligned several more commands and functions that are often used in loops
removed some more unused buffers from the BSS section
removed an unused string from DUMP
GEMSYS 'n' updated to N.AES v2.0 specifications (range 10 to 135)
reverted table entry appl_yield(17), original entry was correct
added table entry appl_search(18)
fixed table entry menu_popup(36)
added table entry menu_attach(37)
added table entry menu_istart(38)
added table entry menu_settings(39)
added table entry objc_sysvars(48)
added table entry objc_xfind(49)
added table entry graf_multirubber(69)
added table entry wind_draw(99)
added table entry wind_new(109)
added table entry rsrc_rcfix(115)
reverted table entry shel_rdef(126), original entry was correct
fixed table entry shel_wdef(127)
added table entry shel_help(128)
added table entry appl_control(129)
fixed table entry appl_getinfo(130)
added table entry form_popup(135)
PCIRCLE binding improved, unused ptsin entries removed
PCIRCLE (extra parameters) binding improved, unused ptsin entries removed
CIRCLE binding improved, unused ptsin entries removed
DEFLINE binding improved, unused ptsin entries removed
DEFMOUSE str option moved to HIMEM
VSETCOLOR range option moved to HIMEM
GET has option to use VDI function vro_cpyfm() (see HIMEM)
CURVE has option to use VDI function v_bez() (see HIMEM)
RC_COPY has option to use VDI function vro_cpyfm() (see HIMEM)
MOUSEx has option to use AES function graf_mkstate() (see HIMEM)
HIDEM/SHOWM has option to use AES function graf_mouse() (see HIMEM)
bugs:
SETCOLOR used a 15-bit mask that should of been 12-bits (rrrrggggbbbbb)
EVERY/AFTER not working in SingleTOS (register clobbered)
XaAES killing the runonly: Non-AES process issued AES system call 12
Crash just before pterm(), called shel_write() after appl_exit()
------------------------------------------------------------------------------
r12:
changes:
removed several unneeded buffers from the bss section (saved ~4kb)
if started from the Desktop, allocates about half the free ram
first V4E build for the FireBee
HIMEM build type can now return 68K or V4E
added two more entries to HIMEM (date/time function pointers)
ERROR #100 and #101 updated with build type
GBE credit box will now show the build type of the interpreter (68K or V4E)
added CPU check at start-up, terminate with message if wrong CPU detected
memory handling at start-up completely recoded, added new options
only MaxMem and SysMem are used, MinMem is ignored
enabled 030+ optimisations (rounding up to a long word boundary)
BSS segment is now aligned (GFA's internal variables)
some of the most used internal routines and gfa commands aligned
all large long word tables aligned
alignment notes:
TOS does not insure long word alignment when starting programs
a program started in TOS might end up long word aligned simply by chance
MiNT on the other hand seems to insure long word alignment \o/
bugs:
random crashes with extremely low string memory, old string management bug
TAS instruction not working on the FireBee (PRINTing in GFA windows)
------------------------------------------------------------------------------
r11:
changes:
SOUND command had an unused word table wasting space (removed table)
DMASOUND command now supports 16-bit palyback on the Atari Falcon030
reverted changes to CRSCOL and CRSLIN (back to being Line-A calls)
reverted changes to PRINT (back to being a bios() call)
DEFMOUSE str enhanced to call the graf_mouse()
KEYPAD does nothing (new features reverted)
ERROR #11, #22, #23, #27, #48, #92 reworded
bugs:
SOUND command, range checks added, error #71 will be triggered
WAVE command, range checks added, error #71 will be triggered
PADX(), PADY(), PADT(), range check added, error #71 will be triggered
STICK, STICK(), STRIG(), range check added, error #71 will be triggered
DMASOUND defaulted to repeat mode if the optional parameter was not passed
hardware err msg froze non-STE machines if STE cmds were used (missing rts)
STICK(0-1), STRIG(0-1) no longer cause a crash
t$=INPUT$(cnt) crashed and/or returned an empty string (register typo)
------------------------------------------------------------------------------
r10:
changes:
DEFMOUSE 255 (user_def) issues error #64 (pointer error)
DEFMOUSE >65535 -> address of a valid mouse shape structure (user_def)
saved 32 bytes in the bss segment, uneeded buffer removed
correct parameter order APPL_TPLAY(num,speed,mem), GFA manual is incorrect
SPRITE command sped up, unneeded register saves removed
ERROR code #60 reworded to be more generic 'String length wrong'
error code #64 reworded to be more generic 'Pointer error'
error code #71 reworded to be more generic 'Index/Parameter out of range'
error code #72 slightly reworded
added error code #101
DEFFILL ,pattern$ will generate an error #60 if the length is incorrect
DEFMOUSE shape$ will generate an error #60 if the length<>74
VQT_EXTENT() generates error #60 if length exceeds the limits of INTIN()
TEXT generates error #60 if length exceeds the limits of INTIN()
null strings will not be passed to the VDI, command is ignored
INTIN() array expanded to 512 elements
window commands generate error #71 if the window number is out of range
CLIP #, TITLEW, INFOW, FULLW, TOPW, CLEARW, CLOSEW, OPENW, W_HAND()
TITLEW/INFOW generate error #60 if the string limit is exceeded
W_INDEX() will return -1 if the AES window handle is not found
CLEARW n command added (was missing), code copied from the library
this variant of CLEARW tops the window first, then clears it
CLOSEW reworked previous patch for better top window detection
CLOSEW # only closes and deletes the window, does no topping or clipping
VDIBASE patch reverted, VDIBASE points to the WORK_OUT() array
STE? function extended with more bit flags
MENU m$() removed limit of 10 characters on menu titles
added pack/unpack rountines via HIMEM
bugs:
APOLY failed to set line-a offset mfill
the docs state APOLY uses the same parameters as HLINE which sets mfill
WINDTAB() failed to catch negative window numbers: r&=WINDTAB(-1,0)
y=MENU(x) did no checks whatsoever on parameter x (limited to -2 to 15)
y=DRAW(x) did no checks whatsoever on parameter x (limited to 0 to 5)
OPENW # (6 parameters) fixed a bug related to index 0 (desktop)
CLEARW failed to check if the window was open before clearing it
MENU x did no checks whatsoever on parameter x (limited to 0 to 3)
DEFNUM x did no checks whatsoever on parameter x (limited to 3 to 14)
DEFLIST x did no checks whatsoever on parameter x (limited to 0 to 11)
e$=ERR$(x) did no checks whatsoever on parameter x (limited to -128 to 127)
MENU x,y did no checks whatsoever on parameter y (limited to 0 to 3)
ERROR x did no checks whatsoever on parameter y (limited to -128 to 127)
obscure bug in RETURN string$ related to MiNT memory allocation
obscure bug in string$ parameter passing, related to MiNT memory allocation
KEYPAD fixed, d0 clobbered
MENU_TEXT() crashed on non-menu object strings
------------------------------------------------------------------------------
r9:
changes:
dropped 'US' from the title
------------------------------------------------------------------------------
r8:
changes:
binding for GDOS? improved to match offical documentation
structure test: reverted 'missing Case' test (issue with faceVALUE code)
------------------------------------------------------------------------------
r7:
new features:
TEXT x,y,t$ -> calls v_gtext() for more speed (without the length parameter)
allows 128 character output
CLS -> improved code, copied from the library
minor code improvement at MSHRINK()
minor code improvements in buffer.s
minor code improvement in fpow.s
minor code improvement in windows.s
getbuf.s code size reduced
buffer2.s code size reduced
fclose1.s code size reduced
TRON #channel now reports unopen channels (used to ignore such errors)
TOUCH error code #-1 changed to #-37 (device detection)
buffer had possible conflict with PRINT
DIR$() code size reduced
SEEK error code #-1 changed to #-37 (device detection)
EXIST() code size reduced
_C code size reduced, copied from the library
TITLEW removed duplicate code
POINT() optimized for speed, code size reduced
CHDRIVE now reports errors (-46 invalid drive specification)
DEFMOUSE x& will default to the arrow (0) shape if user_def (255) is passed
fixed binding per AES docs
ERROR message #9 slightly reworded
PRINT tweaked for more speed (twice)
DRAW tweaked for more speed
DIR/FILE tweaked to match the library, loop altered for speed
DUMP to file defaults to a lower case extender '.dmp' if left off
backup files now default to a lower case extender '.bak' if left off
VDIBASE now points to the results of vq_extnd() (57 words) see VDI docs
example: planes&=WORD{VDIBASE+8}
68020 and up optimizations added (code/data alignment)
HIMEM now means 'hidden memory'and points to the library structure
VQT_NAME() fix improved, smaller code size
PLOT tweaked for more speed
IRQ handling improved for more speed (code copied from the library)
only saves/restores critical registers
BLOAD fix improved, code copied from library
did not check for device errors like the library does (was ignored)
error code #-1 changed to #-37 (device detection)
EOF()/LOC()/LOF() error code changed to #-37 (device detection)
minor code improvement in loc.s
RECALL error code #-1 changed to #-37 (device detection)
INPUT(#x) error code #-1 changed to #-37 (device detection)
INPUT #x error code #-1 changed to #-37 (device detection)
LINE INPUT #x error code #-1 changed to #-37 (device detection)
ERROR #55 removed, never used
Library structure -> Line-A flag removed (always intialized)
added a Coldfire CPU flag to the library structure
added maximum string length for TEXT to the library structure
Library structure -> flush cache entry removed
KEYPAD command expanded
KEYDEF command expanded
STE? function expanded
gbe:
suppress default path setting if called from GBE
GBE now controls the default path via shel_write() extended mode
improved path handling, test for drive letter and path
bugs:
default path handling under SingleTOS failed
ERR incorrectly initialized to 8 under SingleTOS
OPTION BASE tweaked (cache issues)
error handler calls tweaked (cache issues)
AFTER/EVERY minor bug messed up the first timer tick
MAT MUL error handling tweaked
DEFLIST was fatal if used outside of GBE (missing RTS)
QSORT/SSORT previous cache fix incorrectly implemented (broke a CMP)
MAT READ fixed problem related to the break key
MAT MUL fixed problem related to the break key
MAT DET/QDET fixed problem related to the break key
uninitialized pointer in cookie jar code caused a crash under SingleTOS
wrong buffer address fixed: matnorm.s, matread.s, mat1add.s, and mat2add.s
wrong parameter going into vsm_height()
missing RTS in irqreset.s
POLYxxx point limit lowered to 128 (was 512 which caused a buffer overrun)
limit now matches what the error message (too many points) has always said
PTSIN() limit corrected, was 30, should of been 256
structure test failed to save/restore a register (SELECT/CASE)
MAT MUL typo in error handling caused a crash (wrong register)
BSAVE failed to purge internal disk cache (truncated files)
called wrong output routine (code copied from library, slighty faster)
DIR TO failed to purge internal disk cache (truncated files)
DUMP TO failed to purge internal disk cache (truncated files)
TIMER saves critical registers (used internally)
PRINT "" crashed (or any expression resulting in a null string)
KEYPAD/KEYDEF failed to eat parameters from the token stream
------------------------------------------------------------------------------
r6:
needs fixed:
instr()/rinstr()
not implemented:
fpu -> fdiv, fmod (implemented in the library, compiling boosts the speed)
misc:
removed various sections of dead code
removed cls at startup
removed cursor off at pterm()
removed call to cursconf()
removed conterm fiddling
interpreter setups a dta, no longer alters the dta
removed break key checks
fixed workstation defaults, invalid parameter passed to vsl_style()
fixed ste joystick detection
err=8 at startup if ram allocation fails
error messages updated:
incorrect spelling and misc rewordings
_data= issued undefined error code #72 -> 'invalid data pointer'
removed error message #63, never used
fixed temp string pool search (max was off by 1)
fixed falcon lprint problem
fixed binding to vdi text
fixed clipping at startup
fixed bload problem under magic
fixed call bug
console printing sped up via gemdos cconws()
fixed tos version in the fsel calls
removed screen buffering in fileselect command
fixed forced upper case in fileselect command
fileselect now supports long file names
fsel_input() now supports long file names
fsel_input() return parameter length fixed (was +1 too many)
shel_find() return parameter length fixed (was +1 too many)
shel_read() return parameter length fixed (was +1 too many)
keypress, keylook fixed for non-irq use
keypad, keydef ignored for non-irq use
graphic text limit bumped to 126
setmouse fixed for non-irq use
fixed dfree() to use longs
fixed exist() to use fattrib() internally
extended point() for true color modes
fixed getsize() to use vdi w/h values
fixed hardcopy to use a system call
error handling in touch improved
touch fixed, parameters going into fdatime() were incorrect
fixed desktop index used in w_hand()
defmouse parameter range increased for newer aes
alert icon range increased for newer tos
alert line count increased to 5
alert button width increased to 10
error handling at close improved
fixed arrayfill so it reports undimensioned arrays
fixed strange bold text in gfa windows
fixed bug in rc_copy (op_tab)
fixed error code at getfbuf
fixed mat read bug
added 'missing case' to structure test
fixed random crashes at qsort/ssort
fixed random crashes with the tt? function
error code 0 replaced with error code 7
added cpu lmul, ldiv, lmod
added fpu asin, acos, atan, sqr
fixed menu_text() bug
fixed menu_register() bugs
fixed reserve (ignored if multi-tasking is detected)
fixed minor bug in the sound command, removed all movep instructions
fixed menu command (failed with n.aes option hidemenu)
fixed dir/files to use current dta
fixed dir$() so it detects invalid paths
seek/relseek now report channel errors
fixed v_opnwk()/v_opnvwk() parameter order
gdos? extended to return the gdos type in intout(0/1)
vqt_name() extended to return extra font information
fixed ste? function
fixed mw_out lockup (did not check for ste hardware)
fixed dmacontrol command
fixed dmasound command
cleaned up timer function
better error handling at inpx(#chan), input$(#chan)
bug at closew fixed (top window detection)
bug at clearw fixed (missing mfdb structure)
cls used in gfa windows fixed
text scrolling in gfa windows fixed
vsetcolor with composite rgb (red & blue was swapped)
vsetcolor now supports rgb values 0-1000 if bit #8 of index is on
locate/print at() issues fixed (line-a)
fixed break key
fixed every/after (non-interrupt driven, checked between each line
DUMP command works
tron/troff/trace commands work
MAT PRINT with the 2 extra parameters always outputs 0
CURVE updated to match the library (same number of iterations)
missing procedures:
fixed ON ERROR/BREAK GOSUB, reports missing procedure (#19)
fixed TRON proc, reports missing procedure (#19)
fixed EVERY/AFTER x GOSUB, reports missing procedure (#19)
fixed all ON MENU x GOSUB commands, reports missing procedure (#19)
if these point to procedures with parameters, reports too many parameters (#45)
INP(), INP?(), OUT?() now report bios errors
INP&(), INP%() now support device numbers 6 to 9
OUT, OUT&, OUT% now support device numbers 6 to 9
showm/hidem fixes:
all line-a commands,sprite
all vdi/aes calls
bload,bsave,bget,bmove,defmouse,exec,sput,sget,outx,print,rc_copy,put,get
gbe:
added calls to dsetdrv() and dsetpath() to the source file
added argv support (interpreter option)
added minm, maxm, and sysm support
added version information (about dialog box)
supress file selector if started from gbe
supress quit alert prompt if started from gbe
supress error alert box if started from gbe
supress 'program end' alert box if ran from the desktop
added library structure behind the DTA (see library docs for more info)
added deflist aes message
CLEAR no longer sets the event flags to 0
no longer sets break key flag to 0 either
eof
GEMSYS Table
GEMSYS 'n' supported calls.
Note: Entries with '-' should not be used via short form as it fills the
GCONTRL() entries 1 to 3 with zeros.
Opcode Name Info
------ -------------- ----------
10 appl_init
11 appl_read
12 appl_write
13 appl_find
14 appl_tplay
15 appl_trecord
16 -
17 appl_yield N.AES v2.0
18 appl_search AES v4.0
19 appl_exit
20 evnt_keybd
21 evnt_button
22 evnt_mouse
23 evnt_mesag
24 evnt_timer
25 evnt_multi
26 evnt_dclick
27 -
28 -
29 -
30 menu_bar
31 menu_icheck
32 menu_ienable
33 menu_tnormal
34 menu_text
35 menu_register
36 menu_popup AES v3.30
37 menu_attach AES v3.30
38 menu_istart AES v3.30
39 menu_settings AES v3.30
40 objc_add
41 objc_delete
42 objc_draw
43 objc_find
44 objc_offset
45 objc_order
46 objc_edit
47 objc_change
48 objc_sysvar AES v3.40
49 objc_xfind AES v4.1, N.AES v2.0
50 form_do
51 form_dial
52 form_alert
53 form_error
54 form_center
55 form_keybd
56 form_button
57 -
58 -
59 -
60 -
61 -
62 -
63 -
64 -
65 -
66 -
67 -
68 -
69 graf_multirubber N.AES v2.0 (aka graf_rwind AES v4.1)
70 graf_rubberbox
71 graf_dragbox
72 graf_movebox
73 graf_growbox
74 graf_shrinkbox
75 graf_watchbox
76 graf_slidebox
77 graf_handle
78 graf_mouse
79 graf_mkstate
80 scrp_read
81 scrp_write
82 -
83 -
84 -
85 -
86 -
87 -
88 -
89 -
90 fsel_input
91 fsel_exinput
92 -
93 -
94 -
95 -
96 -
97 -
98 -
99 wind_draw N.AES v2.0
100 wind_create
101 wind_open
102 wind_close
103 wind_delete
104 wind_get
105 wind_set
106 wind_find
107 wind_update
108 wind_calc
109 wind_new AES v1.40
110 rsrc_load
111 rsrc_free
112 rsrc_gaddr
113 rsrc_saddr
114 rsrc_obfix
115 rsrc_rcfix AES v4.0
116 -
117 -
118 -
119 -
120 shel_read
121 shel_write
122 shel_get
123 shel_put
124 shel_find
125 shel_envrn
126 shel_rdef N.AES v2.0
127 shel_wdef N.AES v2.0
128 shel_help N.AES v2.0
129 appl_control N.AES v2.0
130 appl_getinfo AES v4.0
131 -
132 -
133 -
134 -
135 form_popup N.AES v2.0
CPU Error Detection
CPU Error Detection
by Lonny Pursell
Rev 3 3/12/2018
CPU error detection via FATAL (Lib r10 and up)
______________________________________________
FATAL will be initialized to TRUE if the program is running on the wrong
processor type. This allows the coder to decide how the program exits.
IF FATAL !running on the wrong CPU type?
' handle error condition
ENDIF
Built for Started on FATAL=
680xxx 680xxx FALSE
V4E V4E FALSE
680xxx V4E TRUE
V4E 680xxx TRUE
This should be checked right away at the top of your program, literally the
very first line of code.
Programs (APP, PRG, TOS, TTP, GTP):
Immediately exit cleanly with pterm() (EDIT, END, QUIT, or SYSTEM).
Accessories (ACC):
Do not call menu_register() and enter an event loop and ignore all events.
Note: When this condition occurs the Line-A interface has not been initialized
because it would instantly crash. L~A will return 0. The application needs to
exit as soon as possible before it encounters and illegal op-code.
In the editor, FATAL will always be initialized to FALSE.
Example:
IF FATAL !wrong cpu?
' show an alert or print a message to the console
IF BTST(STE?,10) !acc?
' do not call menu_register()!
DO
~EVNT_MESAG(0) !ignore all events
LOOP !an acc must not exit
ELSE
EDIT !edit -> pterm() when compiled
ENDIF
ENDIF
Why is this not handled inside the library start-up code?
If the start-up code calls any AES functions, then the linker is always going
to link and initialize the AES. It would not be possible to write a small TOS
or TTP style application anymore. The GFA compiler has always had this ability
to only link the AES/VDI modules as needed. Calling EVNT_MESAG() inside the
main start-up module would break this ability.
This is 100% optional as well. If you want to rely on the end user reading your
documentation and installing the correct binary, you are free to do that as
well. But, we all know, most users do not read docs. ;o)
_______________________________________________________________________________
I was thinking about this and maybe it isn't a good to idea to halt the boot
process with an alert box if something goes wrong with an installed desk
accessory. It's very unlikely, but what if ERR and FATAL both fail at the same
time? That would be a bad day. Here's an alternate idea that handles both
situations as PRG or ACC. If running as an ACC it appears to install ok, but
gives the user an error message when they try to use it.
This is somewhat untested, but it should work in theory. Example code:
' at the very top of your application
IF ERR=8 OR FATAL !$Mx failed or wrong cpu detected?
@fatal_err
ENDIF
'
' the rest of your program here
'
PROCEDURE fatal_err
IF BTST(STE?,10) !acc?
~MENU_REGISTER(APPL_INIT()," app name here")
DO
~EVNT_MESAG(0) !idle until event
IF MENU(1)=40 !acc called?
@fatal_err_message !show messages
ENDIF
LOOP !an acc must not exit!
ELSE !prg?
IF BTST(STE?,11)=FALSE !no mint?
DEFMOUSE 0 !force pointer, older tos shows busy bee
ENDIF
@fatal_err_message !show messages
EDIT !edit -> pterm0() when compiled
ENDIF
RETURN
PROCEDURE fatal_err_message
LOCAL dv&
IF ERR=8
ALERT 1,"low ram message here",1," Abort ",dv&
ENDIF
IF FATAL
ALERT 1,"wrong cpu message here",1," Abort ",dv&
ENDIF
RETURN
CPU and FPU Support
CPU and FPU Support
by Lonny Pursell
Rev 4 12/2/2022
______________________________
Is it possible to use the FPU? Well, sort of. The last version released (v3.6)
added limited FPU support. It's disabled by default and wasn't documented very
well. Some users perhaps are unaware it even had FPU support. At the time of
its release the TT030 was fairly new and came fitted with an FPU as standard.
If the correct hardware isn't found no harm is done. It only activates the
features on valid hardware. It also does something extra, it activates a faster
float to integer conversion. The float to integer conversion takes place in
quite a few commands and functions. I like to classify these into categories,
CPU enhancements and FPU enhancements.
They are enabled with the TT? function. Likes this:
bits&=TT? !enable FPU
It's also possible to activate the CPU and FPU features separately with some
code. This bit of code will only accelerate the compiled version of your
program and the interpreter will ignore it.
PROCEDURE cpu_on
$X PATIFP
RETURN
PROCEDURE fpu_on
$X PATCHXX
RETURN
The TT? function also returns a value.
Bit State Meaning
0 on 68020 or better detected
1 on FPU detected
2 to 31 off -
The unused bits remain the same in the updated library because every reference
to TT? would trigger the activation routine. See function STE? for extended
library information.
It only takes one call to TT? to activate these enhanced options and they can't
be shut off.
The updated library provides additional CPU enhancements.
Command/Function Instruction Status
Float to integer conversion BFFFO standard
Long multiply MULS.L added
Long divide DIVS.L added
Long modulo DIVSL.L added
The updated library provides additional FPU enhancements.
Function Status
SIN() standard
COS() standard
TAN() standard
EXP() standard
LOG() standard
LOG10() standard
ASIN() added
ACOS() added
ATN() added
SQR() added
For 680x0 machines these enhanced features generally show some amount of
performance improvement. Rarely do programs use floating-point, however most
programs should benefit from the fasterer float to integer conversion. How much
is hard to say, it depends entirely on the commands and functions used in the
program.
The FireBee however is a different animal. It reports itself as an 060, however
the long MUL, DIV, and MOD end up being trapped by the CF68KLib. It also
reports no FPU so the FPU options are not invoked. Its probably not worth using
these on the FireBee. To avoid that one can simply do something like this:
' If a Coldfire CPU is detected (start-up code already checked)
IF _CF_=0 !not the firebee?
~TT? !active the enhancements
ENDIF
One could also have some sort of option in their app and let the user decide if
they want this activated.
Note: Although the name of the function is TT?, it's not really specific to the
TT030, it never was. It was simply a poorly chosen name for the function. ;o)
Detecting $M Failure
Detecting $M Failure
by Lonny Pursell
Rev 3 3/12/2018
Detecting $Mx failure via ERR (Lib r10 and up)
______________________________________________
ERR will be initialized to 8 if the requested $Mx ram is not available.
$M32768
IF ERR=8 !not enough ram? (check at startup)
' handle error condition...
ENDIF
$Mx Situation ERR= Comments
Option used 0 Success - allocate to the size you specified
Option used 8 Failed - not enough ram, smaller than expected
Option unused 8 Failed - allocate all ram minus keep-free
Not using $Mx is treated as an error condition. Typically its bad programming
practice to eat all available ram. There are situations where this is
acceptable. If that is your intention, simply do not test ERR at start-up.
Note: This should be checked near the top of your application before trying to
dimension any arrays or create commonly used strings. This works in the
interpreter as well as compiled. If the interpreter cannot meet the ram
requirements requested it will also report error code 8.
How does $Mx actually work?
First the start-up module inquires the largest free block. It then subtracts
off the keep-free amount that is left for the system. Normally 16kb is left
free for the system. It then compares this result to the amount you requested.
If the result is larger than your request, your application gets exactly what
it requested. If the result is smaller than your request, then your application
is given what is available. If this happens your application is suddenly
running with less ram than it expected and eventually will run into problems.
Optimizing with GBE
Optimizing with GBE
by Lonny Pursell
Rev 4 3/12/2018
______________________________
If you like to code making your programs more human readable, you often pay for
it. It actually makes the program larger and slower. Using a feature of GBE,
you can get the best of both.
This has a lot to do with the way GFA references and fetches variables from
memory. They are stored in the BSS section and referenced via an offset from
register A5.
Warning: Assembler listings are used to analyze the results. ;o)
The listings were created with Digger and then commented by hand.
Example showing what happens when trying to code in a human readable fashion:
REM #LIB new lib
REM #SYM !add symbols, debug use only
'
REM #DC* !turn on constants (remove this line to see the difference)
REM #DC? !optional check for duplicates outside the definition block
'
REM #DC+ !begin constant block
' for test purposes (examples)
cx&=0
cy&=0
cw&=1280
ch&=1024
' system equates
obj_tree&=0 !type
max_depth&=7
pdomain&=281 !opcode
domain_mint&=1
' output from rsc editor
tree0&=0 !first tree
obj0&=0 !first object in tree
title$="program"
REM #DC- !end constant block
'
~GEMDOS(pdomain&,W:domain_mint&)
~RSRC_GADDR(obj_tree&,tree0&,tree_adr%)
~OBJC_DRAW(tree_adr%,obj0&,max_depth&,cx&,cy&,cw&,ch&)
CHAR{adr%}=title$
EDIT
Normal build:
UserCode: clr.w -32730(a5) ;cx&=0
clr.w -32728(a5) ;cy&=0
move.w #1280,-32726(a5) ;cw&=1280
move.w #1024,-32724(a5) ;ch&=1024
clr.w -32738(a5) ;obj_tree&=0
move.w #7,-32732(a5) ;max_depth&=7
move.w #281,-32716(a5) ;pdomain&=281
move.w #1,-32714(a5) ;domain_mint&=1
clr.w -32722(a5) ;tree0&=0
clr.w -32720(a5) ;obj0&=0
lea DATASTAR,a2 ;data section
moveq #7,d0 ;string len()
lea -32768(a5),d0 ;title$
bsr CONSTOS ;construct string
move.w -32714(a5),-(a7) ;push domain_mint&
move.w -32716(a5),-(a7) ;push pdomain&
trap #1 ;call gemdos()
addq.l #4,a7 ;fix the stack
move.w -32722(a5),d0 ;param tree0&
move.w -32738(a5),d1 ;param obj_tree&
bsr RSRC_GAD ;call rsrc_gaddr()
move.l d1,-32764(a5) ;tree_adr% = result
move.w -32724(a5),d0 ;param ch&
move.w -32726(a5),d6 ;param cw&
move.w -32728(a5),d5 ;param cy&
move.w -32730(a5),d4 ;param cx&
move.w -32732(a5),d3 ;param max_depth&
move.w -32720(a5),d2 ;param obj0&
move.l -32764(a5),d1 ;param tree_adr%
bsr OBJC_DRA ;call objc_draw()
lea -32768(a5),a0 ;title$
lea -32754(a5),d1 ;adr%
bsr KCHAR ;call CHAR{}
bsr END ;edit
The results of the DC* meta command:
It might look like this if you hard-coded all the values. This is the actual
code the compiler receives after GBE translates the constants.
~GEMDOS(&H119,W:&H1)
~RSRC_GADDR(&H0,&H0,tree_adr%)
~OBJC_DRAW(tree_adr%,&H0,&H7,&H0,&H0,&H500,&H400)
CHAR{adr%}="program"
EDIT
Build using the DC* meta command:
UserCode: pea $01190001.l ;push pdomain&/domain_mint& (long)
trap #1 ;call gemdos()
addq.l #4,a7 ;fix the stack
moveq #0,d0 ;tree0&
moveq #0,d1 ;obj_tree&
bsr RSRC_GAD ;call rsrc_gaddr()
move.l d1,-32764(a5) ;tree_adr% = result
move.w #1280,d6 ;param cw&
moveq #0,d5 ;param cy&
moveq #0,d4 ;param cx&
moveq #7,d3 ;param max_depth&
move.w #1024,d0 ;param ch&
moveq #0,d2 ;obj0&
move.l -32764(a5),d1 ;tree_adr%
bsr OBJC_DRA ;call objc_draw()
lea DATASTAR,a2 ;data section
moveq #7,d0 ;string len()
bsr CONSTR ;construct string
move.l -32754(a5),d1 ;adr%
bsr KCHAR ;call CHAR{}
bsr END ;edit
This is a rather small example. Imagine having a couple hundred object
definitions. I easily have 200+ object definitions in one of my medium size GEM
projects alone. Resource headers optimize particularly well since the object
numbers almost always fall in the range of 0 to 127.
If the value of the constant happens to be -128 to 127 it ends up as a MOVEQ
#val,dx instruction. If not, MOVE.W #val,dx or MOVE.L #val,dx is used depending
on the type.
Types supported by GBE: byte|, word&, long%, and string$. Other types cannot be
used as constants. For further details, see the DC* meta command.
poll.h
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _SYS_POLL_H
# error "Never use <bits/poll.h> directly; include <sys/poll.h> instead."
#endif
/* Event types that can be polled for. These bits may be set in `events'
to indicate the interesting event types; they will appear in `revents'
to indicate the status of the file descriptor. */
#define POLLIN 0x001 /* There is data to read. */
#define POLLPRI 0x002 /* There is urgent data to read. */
#define POLLOUT 0x004 /* Writing now will not block. */
#ifdef __USE_XOPEN
/* These values are defined in XPG4.2. */
# define POLLRDNORM 0x040 /* Normal data may be read. */
# define POLLRDBAND 0x080 /* Priority data may be read. */
# define POLLWRNORM 0x100 /* Writing now will not block. */
# define POLLWRBAND 0x200 /* Priority data may be written. */
#endif
#ifdef __USE_GNU
/* This is an extension for Linux. */
# define POLLMSG 0x400
#endif
/* Event types always implicitly polled for. These bits need not be set in
`events', but they will appear in `revents' to indicate the status of
the file descriptor. */
#define POLLERR 0x008 /* Error condition. */
#define POLLHUP 0x010 /* Hung up. */
#define POLLNVAL 0x020 /* Invalid polling request. */
/* Canonical number of polling requests to read in at a time in poll. */
#define NPOLLFILE 30
Index
A
ACC?
Advanced debugging
AES
AESPB
ALERT
ALERT()
ALLOC
API/Protocols
APPL.FIND
APPL.YIELD
APPL_CONTROL
APPL_GETINFO
APPL_SEARCH
APPL_YIELD
AP_SEND
ARRAY
ARRAYSIZE
AUTO?
Automation
AVERAGE_RGB
AV_ACCWINDCLOSED
AV_ACCWINDOPEN
AV_COPYFILE
AV_DELFILE
AV_EXIT
AV_FILEINFO
AV_INIT
AV_OPENWIND
AV_PATH_UPDATE
AV_PROTOKOLL
AV_SENDKEY
AV_STARTED
AV_STARTPROG
AV_WHAT_IZIT
AV_XWIND
A~I
B
BAR
BCOMPARE
BCOMPARE%
BCOMPARE&
BCONIN
BCONMAP
BCONOUT
BCONSTAT
BCOSTAT
BCOUNT
BCOUNT%
BCOUNT&
BCRYPT
BEEP
BETWEEN
BEXG
BFILL
BFIND
BFIND%
BFIND&
BFOBSPEC
BF_CHARACTER
BF_FILLPATTERN
BF_FRAMECOL
BF_FRAMESIZE
BF_INTERIORCOL
BF_OBSPEC
BF_TEXTCOL
BF_TEXTMODE
BF_xxx
BINSTR
BIOS
Bios
BIOSKEYS
BITBLK
BI_COLOR
BI_HL
BI_PDATA
BI_WB
BI_X
BI_xxx
BI_Y
BLITMODE
BMIRROR
BMPSIZE
BOUND
BPL
BREPLACE
BSWAP
BSWAP&
BSWAP3
BUFFOPER
BUFFPTR
BXLATE
BZERO
C
C2P
CACHECTRL
CALLOC
CAUXIN
CAUXIS
CAUXOS
CAUXOUT
CCONIN
CCONIS
CCONOS
CCONOUT
CCONRS
CCONWS
CHECKSUM
CICONBLK
CI_COL_DATA
CI_COL_MASK
CI_MAINLIST
CI_NEXT_RES
CI_NUM_PLANES
CI_SEL_DATA
CI_SEL_MASK
CI_xxx
CLEARW
CLOSEW
CLUT?
CMDLINE$
CNECIN
COLDBOOT
COMPILED?
Compiler - change log
Compiler commands
CONSTRAIN
CONTERM
CONTRL()
CPRNOS
CPRNOUT
CPU and FPU Support
CPU Error Detection
CPU020
CPU020?
CPUFLUSH
CRASTER
CRAWCIN
CRAWIO
CRC16
CRC32
CRC8
CREAD
Credits
CRYPT$
CT60_CACHE
CT60_FLUSH_CACHE
CT60_READ_CORE_TEMPERATURE
CT60_RW_PARAMETER
CT60_VMALLOC
CURDIR$
CURSCONF
CWRITE
C_VDI
C_XBIOS
D
DATE
DATE$
DAY
DAYNO
DBMSG
DCHROOT
DCLOSEDIR
DCNTL
DCREATE
DDELETE
DEFFN
DEFLIST
DEFMOUSE num
Degas
DELCOOKIE
Detecting $M Failure
DEVCONNECT
Development
DEXIST
DFREE%
DGETCWD
DGETDRV
DGETPATH
DHST_ADD
DHST_INIT
DIGITAL$
DIM
Disclaimer
DLOCK
DMAREAD
DMASND?
DMASOUND
DMAWRITE
Document not found
DOPENDIR
DOSOUND
DPATHCONF
DR
DREADDIR
DREADLABEL
DREWINDDIR
DRVMAP
DSETDRV
DSETPATH
DSPTRISTATE
DSP_AVAILABLE
DSP_BLKBYTES
DSP_BLKHANDSHAKE
DSP_BLKUNPACKED
DSP_BLKWORDS
DSP_DOBLOCK
DSP_EXECBOOT
DSP_EXECPROG
DSP_FLUSHSUBROUTINES
DSP_GETPROGABILITY
DSP_GETWORDSIZE
DSP_HF0
DSP_HF1
DSP_HF2
DSP_HF3
DSP_HSTAT
DSP_INQSUBRABILITY
DSP_INSTREAM
DSP_IOSTREAM
DSP_LOADPROG
DSP_LOADSUBROUTINE
DSP_LOCK
DSP_LODTOBINARY
DSP_MULTBLOCKS
DSP_OUTSTREAM
DSP_REMOVEINTERRUPTS
DSP_REQUESTUNIQUEABILITY
DSP_RESERVE
DSP_RUNSUBROUTINE
DSP_SETVECTORS
DSP_TRIGGERHC
DSP_UNLOCK
DTA
DWRITELABEL
DXREADDIR
E
EGETPALETTE
EGETSHIFT
EJP?
Emulation notes
ENCOM
ENDSEEK
ENVIRON
ENVIRON$
ERASE
ERL
ERR
ERROR
ESETBANK
ESETCOLOR
ESETGRAY
ESETPALETTE
ESETSHIFT
ESETSMEAR
EXIST()
F
FACCEPT
FATAL
FATTRIB
FBIND
FCHDIR
FCHMOD
FCHOWN
FCHOWN16
FCLOSE
FCNTL
FCONNECT
FCREATE
FDATIME
FDELETE
FDIRFD
FDUP
Features
FEXIST
FFCHMOD
FFCHOWN
FFDOPENDIR
FFORCE
FFSTAT64
FGETCHAR
FGETPEERNAME
FGETSOCKNAME
FGETSOCKOPT
FILECOPY
FILELEN
FILES
FILESELECT
FILESELECT #
FINSTAT
FLINK
FLISTEN
FLOATs
FLOCK
FLOPFMT
FLOPRATE
FLOPRD
FLOPVER
FLOPWR
FMIDIPIPE
FONT_INIT
FONT_SELECT
FOPEN
FORM.KEYBD
FORM_POPUP
FOUTSTAT
FPIPE
FPOLL
FPU882
FPU?
FPUTCHAR
FREAD
FREADLINK
FREADV
FRECVFROM
FRECVMSG
FREEFILE
FRENAME
FSEEK
FSELECT
FSEL_EXINPUT
FSENDMSG
FSENDTO
FSETSOCKOPT
FSHUTDOWN
FSOCKET
FSOCKETPAIR
FSTAT64
FSYMLINK
FSYNC
FWRITE
FWRITEV
FXATTR
F_BGET
F_BLOAD
F_BPUT
F_BSAVE
F_CLOSE
F_CREAD
F_CWRITE
F_ENDSEEK
F_EOF
F_INP
F_INP%
F_INP&
F_INPUT
F_LINE_INPUT
F_LINE_OUTPUT
F_LOC
F_LOF
F_OPEN
F_OUT
F_OUT%
F_OUT&
F_OUTPUT
F_PREAD
F_PWRITE
F_RELSEEK
F_SEEK
G
G.I.S.T.
Gemdos
GEMDOS
GEMSYS
GEMSYS (5 parameters)
GEMSYS n
GEMSYS Table
GETBPB
GETCOOKIE
GETMPB
GETREZ
GETSIZE
GETSTR
GETTIME
GFA-Basic
GHIDEM
GIACCESS
GIST_GET_PRIOR
GIST_INIT_SNDS
GIST_INSTALL_INT
GIST_REMOVE_INT
GIST_SND_OFF
GIST_SND_ON
GIST_STOP_SND
GLOBAL
GMOUSE
GMOUSEK
GMOUSEX
GMOUSEY
GPIO
GRAF_MULTIRUBBER
GRAYSCALE
GSHOWM
GSTICK
GSTRIG
G~H
G~R
H
Help
HIBYTE
HICARD
HIMEM
HINYBLE
HINYBLE{}
HIWORD
HOUR12
HOUR24
I
IB_BCOLOR
IB_CHAR
IB_FCOLOR
IB_HICON
IB_HTEXT
IB_LETTER
IB_PDATA
IB_PMASK
IB_PTEXT
IB_WICON
IB_WTEXT
IB_XCHAR
IB_XICON
IB_XTEXT
IB_xxx
IB_YCHAR
IB_YICON
IB_YTEXT
ICONBLK
IKBD
IKBDWS
Important notes
index
INDEXCOUNT
Info
INITMOUS
INPUTBOX
INPUTRADIO
Interpreter - change log
Interpreter notes
INTIN
Introduction
IOREC
ISASCII
ISBLANK
ISCNTRL
ISPRINT
ISSPACE
J
JDISINT
JENABINT
JOIN
JOYPAD
JPEGD_CLOSEDRIVER
JPEGD_DECODEIMAGE
JPEGD_GETIMAGEINFO
JPEGD_GETIMAGESIZE
JPEGD_GETSTRUCTSIZE
JPEGD_INIT
JPEGD_OPENDRIVER
K
KBDVBASE
KBRATE
KBSHIFT
KEYCLICK
KEYDEF
KEYPAD
KEYREPEAT
KEYTBL
Known problems
L
LCASE$
LDG_CLOSE
LDG_ERROR
LDG_FIND
LDG_INIT
LDG_LIBPATH
LDG_OPEN
LEAP
Library - change log
Library versions
License agreement
LINE-A
Linker - change log
LOADMEM
LOADSTR
LOCKSND
LOGBASE
LOG_FILE
LOG_KILL
LOG_MSG
LOG_SET
Lonny Pursell
LOWER$
LRWABS
LTRIM$
LZ77
M
M68K?
MACCESS
MADDALT
Main
MAKE
MAKE%
MAKE&
MAKE|
MDPEEK
MDPOKE
MEDIACH
MEMAND
MEMBCHG%
MEMBCHG&
MEMBCHG|
MEMBCLR%
MEMBCLR&
MEMBCLR|
MEMBSET%
MEMBSET&
MEMBSET|
MEMBTST%
MEMBTST&
MEMBTST|
MEMEXG%
MEMEXG&
MEMFILL%
MEMFILL&
MEMMIRROR%
MEMMIRROR&
MEMMIRROR3
MEMOR
MEMREPLACE%
MEMREPLACE&
MEMSWAP%
MEMSWAP&
MEMXOR
MEMZERO%
MEMZERO&
MENU m$()
MENU.TEXT
MENU_ATTACH
MENU_ISTART
MENU_POPUP
MENU_REGISTER
MENU_SETTINGS
MENU_TEXT
MERIDIEM
MFPINT
Mhz
MIDIWS
MINUTE
MIRROR
MIRROR$
MIRROR&
MIRROR|
MIRROR3
Misc
MLPEEK
MLPOKE
MNAM
MONTH
Moving from older libs to GBE Lib
MROUND
MSG
MULTITASK?
MVALIDATE
MXALLOC
N
NEAREST_RGB
NETWORK?
New features
Notes
NULL
NVMACCESS
NYBLE
NYBLE{}
O
OB.FLAGS
OB.STATE
OBJC_SYSVAR
OBJC_XFIND
OB_CHECKED
OB_CROSSED
OB_DEFAULT
OB_DISABLED
OB_EDITABLE
OB_EXIT
OB_EXTYPE
OB_FL3DACT
OB_FL3DBAK
OB_FL3DIND
OB_HIDETREE
OB_INDIRECT
OB_LASTOB
OB_OUTLINED
OB_RADIO
OB_RBUTTON
OB_SELECTABLE
OB_SELECTED
OB_SHADOWED
OB_SUBMENU
OB_TEXT$
OB_TOUCHEXIT
OB_WHITEBAK
OB_XYWH
OFFGIBIT
ONGIBIT
Optimizing with GBE
P
P3DBAR
Pack-Ice
PALGET
PALSET
PAUSE
PBAR
PCR
PCR?
PDOMAIN
PEXEC
PFORK
PGETAUID
PGETEGID
PGETEUID
PGETGID
PGETGROUPS
PGETPGRP
PGETPID
PGETPPID
PGETPRIORITY
PGETUID
PHYSBASE
PI
PIXEL15
PIXEL16
PIXEL1M
PIXEL24
PIXEL2P
PIXEL32
PIXEL4P
PIXEL8C
PIXEL8P
PKILL
PLUGIN_CLOSE
PLUGIN_LOAD
PLUGIN_OPEN
PLUGIN_RW
PLUGIN_SET
PLUGIN_UNLOAD
PMSG
PNICE
poll.h
POPUP
PRBAR
PREAD
PRENICE
PROTOBT
PRTBLK
PRUSAGE
PSEMAPHORE
PSETAUID
PSETEGID
PSETEUID
PSETGID
PSETGROUPS
PSETLIMIT
PSETPGRP
PSETPRIORITY
PSETREGID
PSETREUID
PSETUID
PSIGACTION
PSIGBLOCK
PSIGINTR
PSIGNAL
PSIGPAUSE
PSIGPENDING
PSIGSETMASK
PSYSCTL
PTERM
PTERM0
PTERMRES
PTRACE
PTRIANGLE
PUMASK
PUNTAES
PUSRVAL
PVFORK
PWAIT
PWAIT3
PWAITPID
PWRITE
PX_FORMAT
P~I
R
RANDOM%
RBAR
RC_EQUAL
RC_REDRAW
REALLOC
REPLACE$
RGB
RGB1000
RGB256
RGB64K
RSCONF
RSRC_RCFIX
RTRIM$
RWABS
S
S:
SALERT
SBYTE
SCALL
SCRDMP
SCREEN
SECOND
SET.DXYWH
SET.DXYXY
SET.GCBITMAP
SET.MENU
SET.MFDB
SET.PXYWH
SET.PXYXY
SET.RXYWH
SET.SOCKADDR_IN
SET.SXYWH
SET.SXYXY
SETBUFFER
SETCOLOR
SETCOOKIE
SETEXC
SETINTERRUPT
SETMODE
SETMONTRACKS
SETPALETTE
SETPRT
SETSCREEN
SETSTR
SETTIME
SETTRACKS
SFILL
SHEL.WRITE
SHEL_HELP
SHEL_RDEF
SHEL_WDEF
SHUTDOWN
SLBCLOSE
SLBOPEN
SLEEP
SND?
SNDH
SNDSTATUS
SOUNDCMD
speaker
Speed Packer
SPLIT
SREALLOC
SSBRK
SSYSTEM
Start-up code
STE?
STEXT
STIK_CNBYTE_COUNT
STIK_CNGETINFO
STIK_CNGET_BLOCK
STIK_CNGET_CHAR
STIK_CNKICK
STIK_GETVSTR
STIK_GET_ERR_TEXT
STIK_INIT
STIK_KRFREE
STIK_KRGETFREE
STIK_RESOLVE
STIK_TCP_CLOSE
STIK_TCP_OPEN
STIK_TCP_SEND
STIK_TCP_WAIT_STATE
STRARRAYFILL
STRPEEK$
STRPOKE
STRUCT
SUBPTR
SUPER
SUPER?
SUPERSCALAR
SUPEXEC
Support
SUPTIME
SVERSION
SWAP|
SYIELD
SYNC
SYSBELL
SYSCONF
SYSTAB
SYSTAB?
System Table
T
TADJTIME
TALARM
TBITBLT
TEDINFO
TEXT
TE_COLOR
TE_FILLPATTERN
TE_FONT
TE_FONTID
TE_FONTSIZE
TE_FRAMECOL
TE_INTERIORCOL
TE_JUST
TE_PTEXT
TE_PTMPLT
TE_PVALID
TE_TEXTCOL
TE_TEXTMODE
TE_THICKNESS
TE_TMPLEN
TE_TXTLEN
TE_xxx
TGETDATE
TGETTIME
TGETTIMEOFDAY
TICKCAL
TIME
TIME$
TIMESTAMP$
TMALARM
TMOUSE
TPUT
TRIANGLE
TRNFM
TSETDATE
TSETITIMER
TSETTIME
TSETTIMEOFDAY
TT?
Tutorials
U
UB_CODE
UB_PARM
UB_xxx
UCASE$
UNLOCKSND
UNPACK
USERBLK
USERDEF
USERDEFBIT
USERDEFBYT
USERDEFLNG
USERDEFWRD
V
VA_START
VBOX
VCHECKMODE
VCLS
VCURVE
VDI
VDIBASE
VDIPB
VER2STR
VEX_BUTV
VEX_CURV
VEX_MOTV
VEX_TIMV
VGET
VGETMONITOR
VGETRGB
VGETSIZE
VLINE
VPALGET
VPALSET
VPBAR
VPLOT
VPUT
VQF_ATTRIBUTES
VQF_BG_COLOR
VQF_FG_COLOR
VQL_ATTRIBUTES
VQL_BG_COLOR
VQL_FG_COLOR
VQM_ATTRIBUTES
VQM_BG_COLOR
VQM_FG_COLOR
VQR_BG_COLOR
VQR_FG_COLOR
VQT_ATTRIBUTES
VQT_BG_COLOR
VQT_EXT_NAME
VQT_FG_COLOR
VQT_FONTHEADER
VQT_FONTINFO
VQT_NAME
VQT_NAME_AND_ID
VQT_WIDTH
VQT_XFNTINFO
VQ_CHCELLS
VQ_COLOR
VQ_CTAB
VQ_CTAB_ENTRY
VQ_CTAB_ID
VQ_CURADDRESS
VQ_DFLT_CTAB
VQ_EXTND
VQ_HILITE_COLOR
VQ_KEY_S
VQ_MAX_COLOR
VQ_MIN_COLOR
VQ_MOUSE
VQ_PX_FORMAT
VQ_SCRNINFO
VQ_TABSTATUS
VQ_VGDOS
VQ_WEIGHT_COLOR
VRC_COPY
VRO_CPYFM
VRT_CPYFM
VR_CLIP_RECTS_BY_DST
VR_CLIP_RECTS_BY_SRC
VR_RECFL
VR_TRANSFER_BITS
VR_TRNFM
VSC_FORM
VSETMASK
VSETMODE
VSETRGB
VSETSCREEN
VSETSYNC
VSF_BG_COLOR
VSF_COLOR
VSF_FG_COLOR
VSF_INTERIOR
VSF_PERIMETER
VSF_STYLE
VSF_UDPAT
VSGET
VSL_BG_COLOR
VSL_COLOR
VSL_ENDS
VSL_FG_COLOR
VSL_TYPE
VSL_UDSTY
VSL_WIDTH
VSM_BG_COLOR
VSM_COLOR
VSM_FG_COLOR
VSM_HEIGHT
VSM_TYPE
VSPUT
VSR_BG_COLOR
VSR_FG_COLOR
VST_ALIGNMENT
VST_BG_COLOR
VST_COLOR
VST_EFFECTS
VST_FG_COLOR
VST_FONT
VST_HEIGHT
VST_NAME
VST_POINT
VST_ROTATION
VST_WIDTH
VSWR_MODE
VSYNC
VS_CLIP
VS_COLOR
VS_CTAB
VS_CTAB_ENTRY
VS_DFLT_CTAB
VS_HILITE_COLOR
VS_MAX_COLOR
VS_MIN_COLOR
VS_WEIGHT_COLOR
V_ARC
V_BAR
V_BEZ
V_BEZ_FILL
V_BEZ_OFF
V_BEZ_ON
V_BEZ_QUAL
V_CIRCLE
V_CLEAR_DISP_LIST
V_CLSBM
V_COLOR2NEAREST
V_COLOR2VALUE
V_CONTOURFILL
V_CREATE_CTAB
V_CREATE_ITAB
V_CTAB_IDX2VALUE
V_CTAB_IDX2VDI
V_CTAB_VDI2IDX
V_CURADDRESS
V_CURDOWN
V_CURHOME
V_CURLEFT
V_CURRIGHT
V_CURTEXT
V_CURUP
V_DELETE_CTAB
V_DELETE_ITAB
V_DSPCUR
V_EEOL
V_EEOS
V_ELLARC
V_ELLIPSE
V_ELLPIE
V_ENTER_CUR
V_EXIT_CUR
V_FILLAREA
V_GET_CTAB_ID
V_GET_PIXEL
V_GTEXT
V_HARDCOPY
V_HIDE_C
V_JUSTIFIED
V_OPEN_BM
V_OPNBM
V_PIESLICE
V_PLINE
V_PMARKER
V_RBOX
V_RFBOX
V_RMCUR
V_RVOFF
V_RVON
V_SETRGB
V_SHOW_C
V_VALUE2COLOR
W
WAITVBL
WAKETIME
WARMBOOT
WDWIDTH
WEEK
WEEKDAY
WF_INFO
WF_NAME
WF_TOP
WIND_NEW
WIND_SGET
WORK.OUT
Writing a clean GEM application
W_INDEX
X
XBIOS
Xbios
XBTIMER
XLATE$
Y
YEAR
Z
ZTRIM$
*
$Ax
$D+
$H+
$H-
$H1
$Kx
$L-
$Ox
$T#
$T<
$T+
$T-
$T1
$T?
$T~
$U*
$Whhhh
$Zx
_0
_1
_2
_3
_4
_5
_6
_7
_8
_9
_A3
_A4
_A5
_A6
_A7
_AES
_B
_BMPSIZE
_BOOTDEV
_BUILDINFO
_CF_
_CH
_CPU
_CPUID
_CW
_DH
_DW
_DX
_DY
_FPU
_GEMDOS
_GLOBAL
_MCH
_MINT
_NAES
_NVDI
_P
_PX_FORMAT
_SH
_SW
_TOS
_VERSION
_X
_Y
eof