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()+

FSEL_EXINPUT

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()+
stat=APPL_SEARCH(mode,fout$[,tout,aout]) (v3.7) appl_search()+

FORM_POPUP

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+

FORM.KEYBD

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()+

INPUTBOX

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+

INPUTRADIO

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

~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()+

VQ_PX_FORMAT

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()+

_PX_FORMAT

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()+

MEDIACH

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()+

F_INPUT

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()+

F_LINE_INPUT

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()+
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