The Atari Compendium by Scott Sanders Errata Sheet: 11/1/1993 1.3 (The 260/520/1040ST) The original ST computers contained a 320x200x16 mode, a 640x200x4 mode, and a 640x400x2 mode (not 640x400x1 as stated). 1.5 The MegaSTe has three serial ports, not two (one is shared with the LAN). The TT has a 1280x960x2 mode (not 1280x960x1). 1.6 The Falcon030 may have a 2.5" IDE drive installed, not a half-height drive as stated. 2.3 (Overview) GEMDOS derives its heritage from CPM 68k (not CPM 86k). 2.4 (GEMDOS Directories) Each sub-directory contains a directory named '..' which refers to its parent directory. In addition, each sub-directory contains a directory named '.' which refers to itself. The root directory contains neither of these files. 2.5 (Disk Transfer Address) The DTA structure is never defined. It is as follows: typedef struct _dta { BYTE d_reserved[21]; UCHAR d_attrib; UWORD d_time; UWORD d_date; ULONG d_length; BYTE d_fname[14]; } DTA; 2.17 (Signal Table - SIGABRT) The last sentence in this table entry should be "It is unrecommended that you catch this signal." 2.23 (GEMDOS Time & Date Functions) TOS 1.02 is incorrectly referred to as 1.2. Any references to TOS 1.2 should be considered references to TOS 1.02, likewise with TOS 1.04 or TOS 1.06. 2.38 (Dcntl() - FS_INSTALL entry) The structure fs_descr is defined without the portability macros. 'WORD' should be substituted for 'short' and 'LONG' should be substituted for 'long'. 2.51 (Fchmod() - table) The definition 'S_IRUSER' should be 'S_IRUSR'. 2.54-2.58 (Fcntl() - table) Several constant definitions for the cmd parameter of Fcntl() were omitted. The correct constants are (note: TIOCSTOP was documented, but the constant listed was incorrect): Definition Constant F_SETLKW 0x0007 TIOCSTOP 0x5409 TIOCGXKEY 0x540D TIOCSXKEY 0x540E PSETFLAGS 0x5404 PGETFLAGS 0x5405 PTRACEGFLAGS 0x5007 PTRACESFLAGS 0x5006 PTRACEGO 0x5008 PTRACESTEP 0x500A PLOADINFO 0x500C SHMSETBLK 0x4E01 SHMGETBLK 0x4E00 2.77-2.78 (Fsfirst() and Fsnext()) The DTA structure was never defined. See the note for page 2.5 above. 2.87 (Pexec()) Pexec() mode 6 is available as of 0.15. 3.4 (System Startup) The Fuji logo and hard disk spin-up delay occurs on all TOS versions past 2.06, not just 2.06 and 3.06 as is stated. 3.8 (Searching for a Cookie) The example code references the cookie structure members 'cookie' and 'value' as 'c' and 'v' rather than by their full name. 3.11 (_MCH cookie) The ST Book '_MCH' cookie contains a value of 0x00010008. 3.12 (FSMC cookie) The value field of the 'FSMC' cookie contains a pointer to a structure with information about the current version of GDOS as follows: typedef struct _gdos_info { ULONG gdos_type; UWORD gdos_version; WORD gdos_quality; } GDOS_INFO; The structure member gdos_type will be either '_FSM' for FSMGDOS, '_FNT' for FONTGDOS, or '_SPD' for SpeedoGDOS. The structure member gdos_version contains the currently installed version of GDOS with the major version number being in the high byte and the minor version being in the low byte. The structure member gdos_quality is initialized to 0xFFFF to indicate that printouts will be processed at the 'default' quality setting. Applications may change this value to 0x0000 to force GDOS drivers to output in DRAFT mode or 0x0001 to force GDOS drivers to output in FINAL mode. The variable should be restored to 0xFFFF after each print. 3.13 (BIOS Devices) The Mega STe supports devices 6, 7, and 9 as Modem 1, Modem 2, and Serial 2 respectively. Reliable use of BIOS serial devices other than the ST compatible device #1 on a Falcon030 requires the use of the TSR program "FPATCH2.PRG" (available from Atari Developer Support) or a TOS version > 4.04. 3.31 (Setexc() - table) The vector number for TRAP #1 (GEMDOS) is 0x21. 4.16 (The Serial Port) No mention was made of the Mega STe's serial ports. They bear the same functionality as serial ports on the TT except that there is no Serial 1 port on a Mega STe. The Falcon030 contains an MFP chip, however, it is not used to control any of the serial devices. 4.23 (Bconmap()) The Falcon030 requires "FPATCH2.PRG" or an installed TOS version greater than 4.04 for Bconmap() to work as expected. 4.xx (DSP functions) Most of the DSP functions contain an incorrect function opcode in the 'Binding' section of the function reference. The correct opcode for all DSP functions is properly listed in the 'Opcode' section, however. 4.33 (Dosound()) Dosound(-1) returns a pointer to the sound block of the currently playing sound or NULL if no sound is currently being played. This feature is broken in MultiTOS 1.00-1.08. 4.58 (EsetGray()) Mode 0 of EsetGray() causes the low 12 bits of a palette entry to be interpreted as a TT color. Mode 1 causes the low eight bits of a palette entry to be interpreted as a gray value between 0-255. 4.59 (EsetPalette()) The correct binding for EsetPalette() is: pea palette move.w count,-(sp) move.w start,-(sp) move.w #$54,-(sp) trap #14 lea 10(sp),sp 4.61 (Flopfmt()) buf should be a word-aligned pointer to a buffer large enough to hold one complete track (not sector as stated). 4.74 (Kbrate()) The correct binding for Kbrate() is: move.w rate,-(sp) move.w delay,-(sp) move.w #$23,-(sp) trap #14 addq.l #6,sp 4.80 (Offgibit()) Offgibit() bit #7 toggles SCC A between the Serial 2 and LAN ports on a TT. 4.81 (Ongibit()) For each bit of mask that is set, that bit will be toggled. 4.86 (Rsconf()) Rsconf() with a speed parameter of -2 will return the last set baud rate on TOS 1.06 or TOS 1.04 with "TOS14FX2.PRG". 4.92 (Setscreen()) If any parameter of Setscreen() is -1, then the value is left unchanged. 4.94 (Sndstatus()) Sndstatus() is available when bit #2 of the '_SND' cookie is set. 4.96 (Soundcmd() - table) The sample rates generated by using a TT compatible prescale value with SETPRESCALE are incorrectly identified in MHz rather than KHz. 4.97 (Supexec()) The function pointer taken by Supexec() was not properly prototyped. Supexec() takes a pointer to a function accepting no arguments and returning a LONG. 4.99 (VgetRGB()) VgetRGB() is available when the '_VDO' cookie contains a value of 0x00030000 or higher. 4.100 (VsetMask()) The opcode for VsetMask() is 92 (0x5C). 4.101 (VsetMode()) Vsetmode() should be VsetMode(). In addition, a value of -1 for the mode parameter will return the current mode setting. 5.10 (The IKBD Controller - Kbdvbase()) The chain of events that occurs when an IKBD event is generated is incorrectly documented. When an interrupt occurs on either 6850 chip (IKBD or MIDI), the following chain of events happen: 1. The system interrupt handler installed in MFP #4 is called. This routine determines which 6850 caused the interrupt. 2. If the MIDI 6850 caused the interrupt, midisys() is called immediately. midisys() checks the MIDI control register for either an error condition or a data byte. If a data byte is available, it is placed in the low byte of d0 and sent to midivec(). If an error occurred, vmiderr() is called. 3. If the Keyboard 6850 generated the interrupt, ikbdsys() is called immediately. The ikbdsys() handler checks for an error condition or the availability of a data byte. If an error condition exists, vkbderr() is called. Otherwise, the ikbdsys() handler reads data byte(s) as necessary to form a complete 'packet' depending on what generated the interrupt (joystick, mouse, or keyboard). 4. If the ikbdsys() handler receives a keyboard make or break code, it handles the packet internally. Otherwise, the address of the packet is passed to statvec(), mousevec(), clockvec(), or joyvec(). Handler vectors may be altered by modifying the structure whose address is returned by Kbdvbase() or by using Mfpint() as appropriate. 5.22 (Falcon030 Video Modes) The Falcon030 is capable of producing a wide variety of video modes. The table represents those accessible from the Desktop only. 6.5 (Applications) The sample code contains an error. Replace the lines: if(_AESglobal[0] == -1) menu_register( ap_id, menu_title); with: if(_AESglobal[1] == -1) menu_register( ap_id, menu_title); 6.30 (The Desktop Window) Calling wind_get( 0, WF_WORKXYWH, ...) will return the size of the desktop work area minus the menu bar (not WF_PREVXYWH as stated). 6.37 (_aes) The _aes binding should list the arrays _addrin and _addrout as being of type '.ds.l', not '.ds.w'. 6.51 (appl_init()) appl_init() may return a value of -1 which indicates that the AES failed to initialize the application. GEM applications may not make any AES or VDI calls unless appl_init() succeeds. 6.53 (appl_search()) The type parameter will be filled in with the value 10 to indicate the current system shell. 6.53 (appl_tplay()/appl_trecord) These functions require a patch (available from Atari) to work under TOS 1.0. 6.59 (evnt_button()) evnt_button( 0x101, 0x03, 0x00, ... ) may be used to wait for either the left or right mouse button. This method works with evnt_multi() as well. 6.65 (evnt_mesag() - table) The AC_OPEN message contains the menu identifier returned by menu_register() in msg[4]. msg[3] is unused. 6.73 (form_alert()) Each line of an alert may be as many as 30 characters long (not 40 as is stated). 6.99 (menu_attach()) If you remove a menu with menu_bar(), all attachments are cleared and must be reset upon reenabling the menu. The MENU structure is missing a member. It should be defined as follows: typedef struct _menu { OBJECT *mn_tree; WORD mn_menu; WORD mn_item; WORD mn_scroll; WORD mn_keystate; } MENU; mn_keystate is unused with menu_attach() but is used to return the current keyboard state in menu_popup(). 6.124 (rsrc_rcfix()) rsrc_rcfix() is available as of AES version 4.0 and higher. 6.136 (shel_read()) The last sentence of the 'Parameters' section should be: "The first BYTE of the command line indicates the length of the string which actually begins at &tail[1]." 6.138 (shel_write() - table) shel_write() mode 1 should have a wisgr paramater of 0 to launch a TOS application or a wisgr parameter of 1 to launch a GEM application. 6.145 (wind_create() - table) The SMALLER attribute shows the correct mask but an incorrect bit. The correct bit is 14. 6.156 (wind_update()) The first sentence of page 6.156 should read: As of AES version 4.0, you may logically OR a mask of 0x0100 to either BEG_UPDATE or BEG_MCTRL. 7.4 (VDI Device Identification Numbers - table) The "MEMORY.SYS" driver should always be assigned to device #61. 7.35 (v_clswk()) v_clswk() closes a physical workstation. 7.60 (v_opnvwk()) v_opnvwk() opens a virtual workstation. 7.113 (vqt_name()) As of SpeedoGDOS version 4.20, this call will return the a modified font index for GDOS bitmap fonts to avoid conflicting with outline font indexes. The index will be added to 5000 for bitmap fonts. 11.13 (Illustration) The version of Pagestream shown is actually 2.2, not 2.1. 11.15 (The File Menu) If a menu item 'Recall' appears, it should appear between the 'Open' command(s) and 'Save' command(s). 11.23 (Application Software) The '_IDT' cookie does not contain any information that could be used to determine a nation's currency symbol. Use the '_AKP' cookie if present (or the OSHEADER if not) to determine the country for which this version of TOS was compiled (and thus the correct symbol). Applications (like entertainment software) should place any data/configuration files in a sub-directory of the application folder. Only directly reveal those files which the user may have to launch or manipulate. B.6 (Memory Map) The SCC vectors are present on a Mega STe. B.7 (System Variables) The availability of system variables depends on the installed TOS version, not the computer as might be implied by the layout of the table. The columns next to system variables were shaded based upon the release of TOS which is most often associated with that computer as follows: Computer TOS Version ST 1.00 or 1.04 Mega ST 1.02 STe 1.06 Mega STe 2.0x TT030 3.0x Falcon030 4.0x B.15 (_longframe) This system variable is valid on an ST as well (it will simply contain 0). B.15 (kcl_hook) This vector is jumped through with the keycode contained in the low byte of d0. B.16 (0x00E00000) The operating system ROM's moved to this address as of TOS 1.06. B.16 (0x00FC0000) This block of memory extends to 0x00FEFFFF, not FF7FFFF. The memory between 0x00FF0000 and 0xFF7FFF is reserved for the operating system. B.30 (MFP) The MFP is present on a Falcon, however it is not used for serial communications. C.6 (Image Compression) .IMG files do not always contain a vertical replication count at the beginning of every scanline. ############################################################################ The Atari Compendium by Scott Sanders Additional Errata Compiled by Mark S Baines 03 02 95 4.23 (Bconmap) A zero return value with Bconmap(0) indicates Bconmap availability, not a non-zero value. (Mark Baines). 6.3 TOS 1.0 can support 6 DAs like any other TOS version. (Mark Baker). 6.46 (appl_getinfo) Available from AES 4.00 not 3.40. ap_gtype 4 and above are available from AES 4.10. (Mark Baines). 6.50 (appl_getinfo) The bindings are incorrect: *ap_greturn = intout[0]; *ap_gout1 = intout[1]; *ap_gout2 = intout[2]; *ap_gout3 = intout[3]; *ap_gout4 = intout[4]; (Andre Wiley) 6.50 (appl_getinfo) The Return Values are incorrect. 0 is returned if an error has been returned, and non-zero if successful. (Simon Robins) 6.59 (evnt_button) The "clicks" parameter can be OR'd with 0x0100 (or add 256) as a NOT condition. This makes GEM wait until the buttons are NOT in the specified state. By putting the current button state into the call, you get an event whenever any button changes in state (so you can wait on left and right clicks independently). You can use the same variable for the input and output button states (and this works well). (Evan Langlois). 6.63 (evnt_mesag) MN_SELECTED - msg[4] contains the object number of the menu item or the submenu item if submenus are available. msg[5], msg[6] and msg[7] contain this data as from AES 3.30 not 4.0. msg[7] contains the parent object index of the menu item or the submenu item. WM_TOPPED - the wind_set parameters should be wind_set(handle, WF_TOP, 0, 0, 0, 0). msg[3] contains the handle. WM_ARROWED - msg[4] indicates which action was actually selected not msg[3] which contains the handle. (Mark Baines). 6.64 (evnt_mesag) WM_HSLID - msg[4] contains the new slider position not msg[3] which contains the handle. WM_VSLID - msg[4] contains the new slider position not msg[3] which contains the handle. (Mark Baines). 6.67 (evnt_multi) The final line on page 6.67 should include *mb (mouse buttons) and read: WORD *mx, *my, *mb, *ks, *kc, *mc; and the function declaration altered also. (Simon Robins). 6.67 (evnt_multi) The "clicks" parameter can be OR'd with 0x0100 (or add 256) as a NOT condition. This makes GEM wait until the buttons are NOT in the specified state. By putting the current button state into the call, you get an event whenever any button changes in state (so you can wait on left and right clicks independently). You can use the same variable for the input and output button states (and this works well). (Evan Langlois). 6.91 (graf_mouse) Mode numbers 259 and 260 are incorrect. Mode M_LAST should be M_RESTORE (259) Mode M_RESTORE should be M_PREVIOUS (260) The descriptions are correct. (Evan Langlois and Mark S Baines). 6.99 (menu_attach) Caveat menu_attach on AES 3.40 has a problem with scrolling sub menus if more than 1 sub menu is in the OBJECT tree. The solution is to only have one submenu per OBJECT tree. (Simon Robins). 6.101 (menu_bar) The Return Values are incorrect. 0 is returned if an error has been returned, and non-zero if successful. (Simon Robins) 6.122 (rsrc_gaddr) The Return Values are incorrect. 0 is returned if an error has been returned, and non-zero if successful. (Simon Robins) 6.123 (rsrc_load) The Return Values are incorrect. 0 is returned if an error has been returned, and non-zero if successful. (Mark Baines). 6.123 (rsrc_obfix) The Return Value is presently only ever 1. (Simon Robins) 6.124 (rsrc_rcfix) The Return Values are incorrect. 0 is returned if an error has been returned, and non-zero if successful. (Simon Robins) 6.134 (shel_find) Version Notes: This function is bugged in AES 1.4 (TOS 1.04) and requires the Atari patch program TOS14FIX to be run in the AUTO folder. (Mark Baines). 6.154 (wind_set) wind_set(BEVENT) works on a *clean* Falcon with TOS 4.04 (AES 3.30) despite all docs including TAC saying that it's only available from AES 4. (Ofir Gal). 6.154 (wind_set) Some modes are missing. Mode WF_ICONIFY (26) parm1, parm2, parm3, parm4 specify the x, y, w and h of the icon coordinates returned by evnt_multi(). Mode WF_UNICONIFY (27) parm1, parm2, parm3, parm4 specify the x, y, w and h of the original window coordinates returned by evnt_multi(). Mode WF_UNICONIFYXYWH (28) Mode WF_FTOOLBAR (31) Mode WF_NTOOLBAR (32) Also see Windows 11.7. (Mark S Baines). 6.155 (wind_update) The mode values are incorrect and should be: END_UPDATE 0 BEG_UPDATE 1 END_MCTRL 2 BEG_MCTRL 3 (Tony Wagstaff) 7.104 (vqt_attributes) In the bindings, the values for attr[6] to attr[9] are returned in ptsout[0] to ptsout[3] respectively. Values for attr [0] to [5] are correctly listed as being returned in intout[]. (Robert Cooper). 7.134 (vsl_type) The values for 'type' should number from 1 to 7, not from 0 to 6. (Robert Cooper). 7.135 (vsl_width) The binding is incorrect. The value 'width' should be passed in ptsin[0], not intin[0]. The width actually set is returned in ptsout[0], although the supplied binding does not support this. (Robert Cooper). 7.151 (vst_height) In the bindings, the value for height should be supplied in ptsin[2], not intin[0]. (Robert Cooper). 8.3 (Line-A Variable Table) There are a number of errors here, especially in the size of the variables. A correction would be too large for this file and readers are advised to compare their compiler bindings (e.g. linea.h) with this table. (John Kormylo). 11.6 (Window Messages) WM_BOTTOMED should be WM_BOTTOM. (Mark Baines). Appendix B - Memory Map The Atari A to Z book contains a full and more accurate and up-to-date list of Systems Variables, the Memory Map and Exception Vectors. B.7 (System variables) Which of these are available for a particular TOS is very confused as laid out here. The Addendum notes don't fully explain either. Addresses $400 - $512 TOS 1.0 Addresses $400 - $57E TOS 1.2 Addresses $400 - $5B0 TOS 1.6 and later There is an additional system variable at $600 patchzone, used as an area for patching TOS and other routines. It was introduced with TOS 1.4 and if empty it is set to $0BADC0DE (TOS 1.4) or zero. (Mark Baines). B.15 (System variables) ramtop should be called fmemtop ramvalid should be called fmemvalid both in accordance with nomenclature used elsewhere. (Mark Baines). B.24 - B.25 0x00FF8930 DMA Crossbar Output Select Controller. Bit map patterns for bits 8 to 15 are incorrect. 0x00FF8932 DMA Crossbar Input Select Controller. Bit map patterns for bits 8 to 15 are incorrect. The correct bit map pattens are:- =============================== 0x00FF8930 DMA Crossbar Output Select Controller. Bit +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ | 7| | 6| | 5| | 4| | 3| | 2| | 1| | 0| +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ | | | | | | | | (DMA OUTPUT) | | | | | | | +-- 0==handshake | | | | | +----+-------00==25.175MHz clock | | | | | 01==External clock | | | | | 10==32MHz clock | | | | +----------------- 0==DSP<->DMA Handshaking, | | | | 1==destination != DSP | | | | (DSP OUTPUT) | | | +--- 0==handshake | +----+--------00==25.175MHz clock | 01==External clock | 10==32MHz clock +-------------------0==DSP tristate 1==DSP connected to matrix Bit +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ |15| |14| |13| |12| |11| |10| | 9| | 8| +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ | | | | | | | | (EXTERNAL INPUT) | | | | | | | +-- 0==handshake | | | | | +----+-------00==25.175MHz clock | | | | | 01==External clock | | | | | 10==32MHz clock | | | | +----------------- always 0 | | | | | | | | (ADC INPUT) | | | +--- always 0 | | +--------00==25.175MHz clock | | 01==External clock | +------------- always 0 +------------------ always 0 0x00FF8932 DMA Crossbar Input Select Controller. Bit +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ | 7| | 6| | 5| | 4| | 3| | 2| | 1| | 0| +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ | | | | | | | | (DMA INPUT) | | | | | | | +-- 0==handshake | | | | | +----+-------00==DMA output | | | | | 01==DSP output | | | | | 10==EXT input | | | | | 11==ADC input | | | | +----------------- 0==DSP<->DMA Handshaking, | | | | 1==destination != DSP | | | | (DSP INPUT) | | | +--- 0==handshake | +----+--------00==DMA output | 01==DSP output | 10==EXT input | 11==ADC input +-------------------0==DSP tristate 1==DSP connected to matrix Bit +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ |15| |14| |13| |12| |11| |10| | 9| | 8| +--+ +--+ +--+ +--+ +--+ +--+ +--+ +--+ | | | | | | | | (EXTERNAL OUTPUT) | | | | | | | +-- 0==handshake | | | | | +----+-------00==DMA output | | | | | 01==DSP output | | | | | 10==EXT input | | | | | 11==ADC input | | | | +----------------- always 0 | | | | | | | | (DAC OUTPUT) | | | +--- always 0 | +----+--------00==DMA output | 01==DSP output | 10==EXT input | 11==ADC input +----------------- always 0 (Mark D. S. Himsley amended by Mark Baines) B.28 - B.29 (SCC Registers) These registers only apply to the TT. The MegaSTE and Falcon both report bus errors if you attempt to access any of the registers in this area. (Simon Robins). F.4 (IKBD Scan Codes) The character for the 'Nmpad -' should be a minus sign and not an underline. The scan code for 'CTRL Nmpad +' is 0x4E0B. (Mark Baines). ############################################################################ Letter extracts published in ST Applications Issue 42 page 41 David Bolton For someone starting to program in assembler and wanting to use GEMDOS, BIOS or XBIOS calls they will need to do some hunting unless they have any other reference books for the o/s. Mr Sanders has omitted to mention that return values are to be found in d0.L. Each of the relevant sections in the book has a part entitled "Function Calling Procedure" but none of them tells the reader where return values can be found! Since the procedure is given in assembler I feel this is a bad oversight. The remaining errors/omissions I've found so far have been in the AES, VDl and CPX sections. Those in the AES are associated with the table of opcode/control values on page 6.38. The statement at the start of the table about no AES calls using addrout is wrong: rsrc_gaddr uses it to pass back the address of the object being looked for. Some entries in the table have the wrong values; the entries should read for: appl_search 18, 1, 1, 3; rsrc_rcfix 115, 0, 1, 1; appl_getinfo 130, 1, 4, 0 The VDI section mentions device drivers but unfortunately Scott Sanders hasn't taken the opportunity to pass on any information or guidelines on how to write them (a subject that has been mentioned on more than one occasion in STA). The errors are: v_bez_on p7.29, contrl[1] should equal 0 not 1; v_load_cache p7.59, contrl[3] should be i not --i (intin[0] holds the mode so the last i++ counts that word also); vqt_cachesize p7.104, the assignment to *size should access intout[0] and [1] not the corresponding intin fields; vgt_fontheader p7.109, the opcode should be 232; vqt_name p7.113, the assignment to fontname requires a cast as intout is a word array and fontname is a char/byte array, ie fontname[i] = (char)intout[i + 1]. The v_bez (and v_bez_fill) explanations on p7.26/27 have a couple of errors and are not as clear as they should be (or maybe I'm as thick as two short planks!). The control points are actually expected in the following order: anchor - 1, control - 1, control - 2, anchor - 2 (if you believe the book then there are some interesting curves produced!). The first line in the first "for" loop is rather curious as it won't achieve the desired result. Each word of intin should contain two consecutive characters from bezarr, the code given will only pass the first half of bezarr to the VDI and with $00 between each value. The following code should give the desired effect: for (i = O; i < count; i += 2) intin[i / 2] = ((WORD)bezarr[i]) * 256 + (WORD)bezarr[i + 1]; When bit 0 of a value in bezarr is set the control points start in the NEXT corresponding position in the pxy array, the use of bit 1 is also important. Here are a two examples (the origin is at the top left in each case): count = 4 bezarr = 3, 0, 0, 0, 0 pxy = 50, 50 ignored here 400, 50 anchor - 1 400, 200 control - 1 300, 50 control - 2 300, 200 anchor - 2 Resetting bit 1 to give bezarr = 1, 0, 0, 0, 0 results in this second curve where the first point in pxy is now used. [ images of 2 bezier curves not included here ] v_bez_fill behaves in the same way but additionally the first and last points are connected with a line before doing the fill. Using the same values as above gives: [ images of 2 filled bezier curves not included here] The section on the extensible control panel has some omissions in its explanation. The flags structure in the header (p10.3) is actually a word with each flag in the corresponding nybble. Also for some reason known only to Atari the values in the two colour words are not stored as you would expect. The icon colour (i_color) is in the high nybble of the word as 0xi00, and the text colour (t_color) in the low nybble of the high byte of the word as 0x0t00. For anyone writing CPX's in assembler all the cpx_*** functions expect the return value to be passed back in d0.L. ############################################################################