From: jbickers@templar.actrix.gen.nz (John Bickers)
Newsgroups: comp.sys.amiga.programmer
Subject: FAQ (long).
Date: 12 Jan 93 20:43:26 PST
Organization: TAP

    Well, I couldn't make a fortnightly schedule, so this is now
    monthly. I've rearranged the layout a bit. We also had a news
    blackout here last week.

    ------------------------------ 8< ------------------------------


    Last modified 12th Jan 1993. Please address feedback to:
    jbickers@templar.actrix.gen.nz.


    TABLE OF CONTENTS

 
    1   MAILING LISTS
    2   LIBRARIES
    3   AVAILABLE COMPILERS & TOOLS
    4   COMMUNICATIONS INFORMATION
    4.1     Dropping DTR.
    5   DOS INFORMATION
    5.1     Can an ACTION_READ to a console be aborted?
    5.2     Need a pointer to a CLI window.
    5.3     Checksum errors, trimnews and hard links.
    5.4     Scanning each entry in a multi-assign.
    5.5     Read character from console immediately (raw).
    5.6     How the Amiga FS works.
    6   EXEC INFORMATION
    6.1     What do GURU numbers mean?
    6.2     How do you debug an input handler / task?
    7   GRAPHICS INFORMATION
    7.1     What is DIG/RTG?
    7.2     What is the format of IFF ILBM and ANIM files?
    8   INTUITION INFORMATION
    8.1     How do I block a window from user input?
    8.2     Some Workbench icons disappear during WindowToBack()!
    9   SAS C INFORMATION
    9.1     Are malloc()/free() much slower under 6.1 than 5.10?
    9.2     How do I get rid of the CON: created from Workbench?

*** 1   MAILING LISTS

    A number of mailing lists are set up for email discussion of
    specific subjects. These include:

    a68k-request@castrov.cuc.ab.ca
        Discussion of Charlie Gibb's A68k freeware assembler.

    amigalisp-request@contessa.palo-alto.ca.us
        Discussion of LISP, Scheme, ML, Gofer, functional programming,
        and other such things.

    dice-request@castrov.cuc.ab.ca
        Discussion of Matt Dillon's shareware DICE C compiler.

    xpr-request@aldhfn.akron.oh.us
        Discussion of the XPR file transfer protocol.

*** 2   LIBRARIES

    iff.library [Christian Weber]
        Routines to read and write IFF files, with direct support for
        ILBM and ANIM forms for pictures and animations. ANIM support
        includes decoding of DLTA chunks. It is also XPK-aware. It is
        available from amiga.physik.unizh.ch and on Fish disk #674.

    pattern.library [Angela Schmidt]
        AmigaDOS pattern matching routines which are less buggy than
        OS (KS2.0) or ARP (KS1.2) routines, and include some special-
        case optimizations. It is available from ftp.wustl.edu and on
        Fish disk #625.

    reqtools.library [Nico Franois]
        String, screen, color, file and font requesters, with a 2.0
        look. It is available from amiga.physik.unizh.ch.

    xpkmaster.library [Dominik Mueller et al]
        A variety of data compression and encryption routines managed
        through a set of sublibraries. Can compress RAM to RAM, file
        to RAM, RAM to file, etc. The user and development archives
        are available from amiga.physik.unizh.ch.

    xpr<proto>.library [Willy Langeveld et al]
        A variety of external protocol libraries that meet the XPR 2.0
        specification. The spec. can be found on Fish disk #247. The
        libraries themselves are often distributed independently. Join
        the XPR mailing list for information about XPR 3.0.

*** 3   AVAILABLE COMPILERS & TOOLS

    a68k
        Charlie Gibbs' freeware 680x0 assember, available from
        amiga.physik.unizh.ch.

    AdaEd
        An Ada implementation, available from wuarchive.wustl.edu as
        programming/programming/ada/adaed-1.0.11a.lzh.

    ARexx
        William Hawes' commercial REXX package. The address is:

        Post.: Wishful Thinking Development Corp.,
               PO Box 308, Maynard, MA 01754, USA.
        Voice: +1-508-568-8695

    Comeau C++ 3.0 With Templates
        Comeau Computing's commercial C++ package. Their address is:

        Email: attmail.com!csanta!comeau
        Post.: Comeau Computing,
               91-34 120th Street, Richmond Hill, NY 11418, USA.
        Voice: +1-718-945-0009 / Fax: +1-718-441-2310.

    DICE
        Matt Dillon's shareware C compiler, available from
        amiga.physik.unizh.ch. His address is:

        Email: dillon@overload.berkeley.ca.us
        Post.: Matthew Dillon,
               1005 Apollo Way, Incline Village, NV 89451, USA.

    Gofer
        See the LISP entry for more information.

    GNU C
        Markus Wild's port of this freeware C compiler, available from
        amiga.physik.unizh.ch.

    LISP
        Several implementations are available from gatekeeper.pa.dec.
        com, in the directory /pub/micro/amiga/lisp. The file
        LISP.LIST has pointers to other sources. An up-to-date version
        of this is available via BMS from contessa.palo-alto.ca.us as
        bms:pub/lisp.list. See the Amiga LISP mailing list for more
        information.

    ML
        See the LISP entry for more information.

    PCQ Pascal
        Patrick Quaid's freeware Pascal compiler, available from
        amiga.physik.unizh.ch.

    Scheme
        Suitable Schemes for use with Abelson & Sussman's "Structure
        and Interpretation of Computer Programs" are SIOD, Ed Turner's
        Scheme, or XScheme. If you have experience to the contrary,
        please let amigalisp@contessa.palo-alto.ca.us and the FAQ list
        maintainer know. These systems are available at gatekeeper.pa.
        dec.com, in /pub/micro/amiga/lisp. SIOD is also on Fish disk
        #525, and Scheme is on disk #149.

        See the LISP entry for more information.

*** 4   COMMUNICATIONS INFORMATION

    4.1     Dropping DTR.

    a.  If you are using a CBM device, eg serial.device, you must call
        CloseDevice() to drop DTR. DTR is asserted when you open the
        device, and no other system mechanism is provided to drop it.
        Be aware that this fails if another application has opened the
        device in SHARED mode.

    b.  Many other devices support an extra command to control the DTR
        and RTS lines. This was originated by ASDG. The following is
        extracted from code originally posted by Russell McOrmond:

        #define SIOCMD_SETCTRLLINES 0x10
        #define SIOB_RTSB  0
        #define SIOB_DTRB  1
        #define SIOB_RTSF  (1<<SIOB_RTSB)
        #define SIOB_DTRF  (1<<SIOB_DTRB)

        IOSer.io_Command = SIOCMD_SETCTRLLINES;
        IOSer.io_Offset  = SIOB_DTRF;
        if (raising DTR) IOSer.io_Length = SIOB_DTRF;
        else IOSer.io_Length = 0;

        The io_Offset is a mask of bits to be affected (RTS and DTR),
        and the io_Length is a value to set each bit to. So to drop
        DTR you set the DTR bit in io_Offset, and clear the DTR bit
        in io_Length. To raise DTR again, you set the DTR bit in both
        io_Offset and io_Length.

    c.  If you are using the internal serial port with CBM's
        serial.device, you can drop DTR without calling CloseDevice by
        banging the hardware. Again the following is extracted from
        code originally posted by Russell McOrmond:

        struct CIA *Ciab = (struct CIA *)0xbfd000;

        Disable();
        Ciab->ciaddra |= CIAF_COMDTR;                   /* Set DTR as output */
        if (raising DTR) Ciab->ciapra &= ~CIAF_COMDTR;  /* Raise */
        else Ciab->ciapra |= CIAF_COMDTR;               /* Drop */
        Enable();

*** 5   DOS INFORMATION

    5.1     Can an ACTION_READ to a console be aborted?

    No, with the exception that if you close the console, then all
    pending packets are returned.

    5.2     Need a pointer to a CLI window.

    a.  The following may return a pointer with a value of -1, if the
        console you were launched from has had requesters disabled.

        struct Process *pProc;

            pProc = (struct Process *)FindTask(NULL);
            pWin = pProc->pr_WindowPtr;

    b.  The following code is SAS C specific, but should be easy to
        modify for other compilers:

        /* findwindow.c - utility routine to find window of a CLI.
            From: deven@rpi.edu (Deven T. Corzine)
            Subject: Re: Finding Windows
            Date: 20 Jul 90 16:14:05 GMT
         */
        #include <exec/types.h>
        #include <exec/memory.h>
        #include <proto/exec.h>
        #include <proto/dos.h>

        struct Window __regargs *FindWindow()
        {
           register struct DosLibrary *DOSBase;
           register struct Window *win;
           register struct Process *proc;
           register struct CommandLineInterface *cli;
           register struct InfoData *id;
           register struct StandardPacket *pkt;
           register struct FileHandle *fh;
           register BPTR file;
           register long ret1,ret2;

           if (DOSBase=(struct DosLibrary *) OpenLibrary(DOSNAME,0)) {
              if (id=(struct InfoData *)
                AllocMem(sizeof(struct InfoData),MEMF_PUBLIC|MEMF_CLEAR)) {
                 if (pkt=(struct StandardPacket *)
                   AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) {
                    proc=(struct Process *) FindTask(NULL);
                    if (cli=(struct CommandLineInterface *) (proc->pr_CLI<<2)) {
                       ret1=cli->cli_ReturnCode;
                       ret2=cli->cli_Result2;
                       if (file=Open("*",MODE_NEWFILE)) {
                          if (IsInteractive(file)) {
                             pkt->sp_Msg.mn_Node.ln_Name=(char *) &(pkt->sp_Pkt);
                             pkt->sp_Pkt.dp_Link=&(pkt->sp_Msg);
                             pkt->sp_Pkt.dp_Port=&(proc->pr_MsgPort);
                             pkt->sp_Pkt.dp_Type=ACTION_DISK_INFO;
                             pkt->sp_Pkt.dp_Arg1=((ULONG) id)>>2;
                             fh=(struct FileHandle *) (file<<2);
                             PutMsg(fh->fh_Type,(struct Message *) pkt);
                             WaitPort(&(proc->pr_MsgPort));
                             GetMsg(&(proc->pr_MsgPort));
                             win=(struct Window *) id->id_VolumeNode;
                          }
                          Close(file);
                       }
                       cli->cli_Result2=ret2;
                       cli->cli_ReturnCode=ret1;
                    }
                    FreeMem(pkt,sizeof(struct StandardPacket));
                 }
                 FreeMem(id,sizeof(struct InfoData));
              }
              CloseLibrary((struct Library *) DOSBase);
           }
           return(win);
        }

    5.3     Checksum errors, trimnews and hard links.
            [Randell Jesup]

    The filesystem has a problem with deleting the target of a
    hardlink, especially on dir-cached partitions (DOS\5), but also
    hardlinked directories on FFS, and on files and directories under
    OFS (though you may not see the problem unless you need to recover
    the partition).

    Temporary solutions: don't use hardlinks to directories, and don't
    put UUCP news on DCFS partitions.  This will be fixed in a future
    release of the FS.

    5.4     Scanning each entry in a multi-assign.
            [Randell Jesup]

    BOOL do_something_to_all(char *path, BOOL (*function)(BPTR lock))
    {
    struct DeviceProc *dp = NULL;
    struct MsgPort *old_fsport;
    BPTR lock, old_curdir;
    char *remainder;
    LONG err;

        // NOTE: not strrchr - PathMan has files with ':'s in them
        remainder = strchr(path,':');
        if (remainder == NULL)
            remainder = path;
        else
            remainder++;            /* point past ':' */

        while (1) {
            dp = GetDeviceProc(path,dp);
            if (!dp)
            {           /* getdevproc freed dp for us */
                        // NOTE: 2.04 and 3.0 have a bug, and never return
                        // ERROR_NO_MORE_ENTRIES.  Accept 0 as no error as well
                        // This will be fixed next release.
                err = IoErr();
                if (err == 0 || err == ERROR_NO_MORE_ENTRIES)
                    return TRUE;        // all done
                else
                    return FALSE;       // never found anything
            }
            /* save filesystem port pointer, set default FS to target */
            old_fsport = SetFileSysTask(dp->dvp_Port);
            old_curdir = CurrentDir(dp->dvp_Lock);      // may be NULL

            /* we have an entry, get a lock on the remainder of path */
            lock = Lock(remainder,SHARED_LOCK);

            /* reset filesystem port and current dir */
            (void) SetFileSysTask(old_fsport);
            (void) CurrentDir(old_curdir);

            /* we got a lock on it, call user function.  Function can */
            /* return FALSE to stop the scan. */
            if (!lock || !(*function)(lock))
            {
                UnLock(lock);           // NULL is safe
                FreeDeviceProc(dp);
                return FALSE;
            }
            UnLock(lock);
        }
    }

    Warning: that was written off the top of my head, but I do have
    the source code for reference. Also, at least one developer has
    used this and it works.

    5.5     Read character from console immediately (raw).

    It is often useful to have functions like getchar() return
    immediately when the user presses a key, rather than waiting until
    they hit Enter. To do this, you need to switch your console into
    "raw" mode. The line-based mode is referred to as "cooked" mode.

    a.  Under KS2.0, dos.library has a function SetMode() that does it
        all.

    b.  Under DICE, the link library function setvbuf() also switches
        modes automatically.

    c.  Otherwise, you need to send an ACTION_SCREEN_MODE packet to
        the console yourself. Set arg[0] to -1L for raw mode, 0 for
        cooked mode.

    5.6     How the Amiga FS works.

    [Randell Jesup, on coroutines in Amiga filesystems]

    Yes, they're coroutines (BCPL ones). Anything that blocks in exec
    (i.e. Wait()) will stop all of them. Internally, it switches
    around between them as needed (no preemption). CallCo() will swap
    to a coroutine (much like jsr), WaitCo() returns a results to the
    parent (much like rts). One important difference with subroutines
    is that the coroutines maintain their own stacks and state.
    ResumeCo() is basically a branch to a coroutine (as if it had been
    CallCo'd by your caller - much like exiting a subroutine with jmp
    some_other_subrutine).  There are various other utility functions,
    like StartCo, KillCo, CreateCo, etc.

    Each open filehandle is a coroutine. The master coroutine
    CallCo()'s it when it gets a packet or when IO comes back. Note
    that this is where the stack-based state information of the
    coroutine come into play - a filehandle coroutine does IO by
    queuing a request, and calling WaitCo(). The disk read/write
    coroutine pulls things from the queue and gets woken up when IO is
    done. When an IO is complete and verified, it notes which
    coroutine is waiting for the IO to complete (can be a list), and
    ResumeCo()'s that coroutine. Since the coroutine has a stack, it
    continues at the point after the WaitCo with whatever it was
    doing, now knowing the IO was complete. Note that the master
    coroutine doesn't CallCo() an active filehandle coroutine, it
    queues the packet for later handling.

    If this seems simple, I guarantee you, IT'S NOT. It's mind-warping
    and arcane when you need to care about the coroutines (but easy
    and straightforward when you don't).  A lot of state information
    becomes automatic, without having to build a (massive) explicit
    state machine. I burnt out a lot of brain cells figuring out how
    to handle locking of updates to hash chains in this setup, since
    this required major interactions between coroutines. The end
    result was simple, but it was a bitch to figure out.

*** 6   EXEC INFORMATION

    6.1     What do GURU numbers mean?

    Get Stegan Zeiger's program "alert" from amiga.physik.unizh.ch or
    Fish disk #636. It will translate the 32-bit GURU values into
    something more understandable.

    6.2     How do you debug an input handler / task?

    a.  Create a message port in the parent process to which you can
        send messages from the handler.

    b.  Use the kprintf() routines in debug.lib, optionally trapping
        the output to a console with Sushi.

*** 7   GRAPHICS INFORMATION

    7.1     What is DIG/RTG?

    DIG is Device Independent Graphics. A set of graphics routines
    that does not require a particular device to work.

    RTG is ReTargetable Graphics. A set of graphics routines that
    normally work with a particular device, but can be changed at a
    low level to work with other devices.

    They are basically the same thing, though DIG is more often used
    to refer to things like Postscript where the output device can be
    a monitor, a plotter, a printer, etc. RTG is more often used to
    refer to different display hardware, usually meaning a different
    number of colors or a different pixel format, planar vs chunky.

    7.2     What is the format of IFF ILBM and ANIM files?

    The complete format specs for these files can be found on Fish
    disk #185. That disk also includes public domain code for the
    creation of OPT 5 DLTA chunks for ANIM files.

    It may not be necessary to know the exact format if you use a
    library such as iff.library for loading and saving pictures. This
    library also contains a routine for decoding DLTA chunks from ANIM
    files, including OPT J chunks from the old Sculpt 3D movies. OPT J
    chunks used to be proprietary.

*** 8   INTUITION INFORMATION

    8.1     How do I block a window from user input?

    Normally this is required when you want to open a second window
    that should act like a requester. The solution is to open a real
    requester in the window you want to block, that is 1 pixel by
    1 pixel, and hidden somewhere in your first window. Remove this
    tiny requester when you are ready to close your "requester".

    You can also change the IDCMP flags on your first window so that
    messages don't pile up.

    8.2     Some Workbench icons disappear during WindowToBack()!
            [Markus Juhani Aalto]

    You have to try to lock layers before using WindowToBack().

    /* Lock layers. If someone else has locked it, then we wait. */
    LockLayerRom( WorkbenchScreen->LayerInfo.top_layer );
    Forbid();
    UnlockLayerRom( WorkbenchScreen->LayerInfo.top_layer );

    WindowToBack(MyWindow);     /* Or WindowToFront() */
    Permit();

*** 9   SAS C PROBLEMS

    9.1     Are malloc()/free() much slower under 6.1 than 5.10?

    Performance problems in programs with a lot of small malloc()/
    free() calls may be overcome by reducing the page size used by the
    memory management code. This is done by declaring a global
    constant:

        unsigned long _MSTEP = <whatever>;

    9.2     How do I get rid of the CON: created from Workbench?

    The window is opened by the ___main() function. Refer to Appendix
    1 of the SAS C User's Guide, Volume 1.

--
*** John Bickers, TAP.                   jbickers@templar.actrix.gen.nz ***
***    "Radioactivity - It's in the air, for you and me" - Kraftwerk    ***
Newsgroups: comp.sys.amiga.programmer