page%swap@Sun.COM (Bob Page) (05/11/89)
Submitted-by: ecarroll@vax1.tcd.ie (Eddy Carroll) Posting-number: Volume 89, Issue 127 Archive-name: util/backdrop.1 Backdrop puts a pattern in the area behind the CLI windows. The only program I had which would give a similar effect was DropCloth by Eric Lavitsky, but this requires Workbench to be loaded. Backdrop won't work very well with Workbench, which suits me fine since I hardly ever use Workbench. [uuencoded exectuable included. ..bob] # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # README # backdrop.c # atoi.a # res.a # tiny.a # Makefile # Sys-Conf.uu # backdrop.uu # backdrop.n # This is archive 1 of a 1-part kit. # This archive created: Thu May 11 00:35:34 1989 echo "extracting README" sed 's/^X//' << \SHAR_EOF > README XThis archive includes all the files necessary to recreate a working copy Xof Backdrop, a utility which puts a pattern in the area behind the CLI Xwindow. See Backdrop.n for more information. X XAlso included is a System-Configuration file which you can copy into the XDEVS directory of your system disk. It makes your Amiga boot up with an Xinterlaced overscan workbench, giving you an resolution of around 704x562 X(on a PAL screen). When used with Backdrop, this can make for a very Xdisplay which looks like those seen on expensive workstations (and Macs). XFor best effect, turn the contrast and brightness down to prevent flicker X(unless you are fortunate enough to have a Flicker Fixer). It's not really Xthat usable on a normal monitor, but it looks impressive. SHAR_EOF echo "extracting backdrop.c" sed 's/^X//' << \SHAR_EOF > backdrop.c X/* X * Backdrop (C) Copyright Eddy Carroll 1989, may be Freely Redistributed X * X * Backdrop allows you to define a pattern which will then be displayed X * in the empty screen area behind all the windows (who said Macintosh? :-) X * X * Usage: Backdrop { -a# | -b# | -f | -p# | -q | -s | B1B2B3B4B5B6B7B8} X * X * If no parameters are given, the default is a half tone grey pattern. X * X * -a or -b followed by a number sets the foreground or background colour X * to the corresponding pen number (0 - 3) X * X * -f and -s select either a SMART_REFRESH or SIMPLE_REFRESH window to X * display the backdrop pattern in. The former gives fast screen updates, X * but uses up quite a bit of memory, whereas the latter uses up very X * little memory but is slower at updating the screen. X * X * -p followed by a number selects the built in pattern corresponding to that X * number. If you try and select a pattern number not available, you get X * the default. X * X * -q kills the background copy of Backdrop currently installed, if any. X * X * A list of 16 hex digits will be interpreted as a user defined pattern, X * which should be viewed as an 8x8 grid. X * X * The first time you run Backdrop, it installs itself in memory. Future X * invocations of Backdrop will merely tell this first copy about any X * changes in parameters, until the -q option is used to remove it. Note X * that all the parameters, including window type, can be changed even X * while Backdrop is currently running. X * X * Compiles under Lattice C V4.0 X * X */ X X#include <exec/types.h> X#include <graphics/gfxbase.h> X#include <graphics/gfxmacros.h> X#include <intuition/intuition.h> X#include <intuition/intuitionbase.h> X#include <libraries/dos.h> X#include <proto/exec.h> X#include <proto/graphics.h> X#include <proto/dos.h> X#include <proto/intuition.h> X#include <string.h> X X#define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c)) X#define YES 1 X#define NO 0 X#define NUMPATS 19 /* Number of predefined patterns available */ X#define REPEAT 9999 /* Special return value indicates reopen window */ X#define UNSET -1 /* Indicates a parameter is currently unset */ X X#define htoi(c) (((c) - '0' - 7 * ((c) >= 'A')) & 0x0F) /* Hex to int */ X Xstruct IntuitionBase *IntuitionBase; Xstruct GfxBase *GfxBase; XULONG BackGroundIO = 0; X Xchar usage1[] = "\ XBackdrop (C) Copyright Eddy Carroll 1989, adds backdrop to Workbench screen\n", Xusage2[] = "\ XUsage: Backdrop {-f | -p# | -q | -s | B1B2B3B4B5B6B7B8}\n\ X\n\ X -a# - Set foreground colour to specified pen #\n\ X -b# - Set background colour to specified pen #\n", Xusage3[] = "\ X -f - Enable fast update (uses more memory)\n\ X -p# - Use specified pattern # (1-5)\n\ X -q - Remove backdrop from memory\n\ X -s - Enable slow update\n\ X B1B2B3B4B5B6B7B8 - 16 hex digits defining an 8x8 pattern\n\ X\n> "; X Xchar Portname[] = "Backdrop"; X Xstruct Pattern { X UWORD value[8]; X} Patterns[] = { X { 0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA }, /* Check */ X { 0xFFFF,0x4040,0x4040,0x4040,0xFFFF,0x0404,0x0404,0x0404 }, /* Brick */ X { 0x8888,0x0000,0x0000,0x0000,0x8888,0x0000,0x0000,0x0000 }, X { 0x8888,0x0000,0x2222,0x0000,0x8888,0x0000,0x2222,0x0000 }, X { 0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000 }, X { 0xAAAA,0x0000,0x5555,0x0000,0xAAAA,0x0000,0x5555,0x0000 }, X { 0x8888,0x2222,0x8888,0x2222,0x8888,0x2222,0x8888,0x2222 }, X { 0xAAAA,0xAAAA,0x5555,0x5555,0xAAAA,0xAAAA,0x5555,0x5555 }, X { 0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333 }, X { 0xFFFF,0x8181,0xBDBD,0xA5A5,0xA5A5,0xBDBD,0x8181,0xFFFF }, X { 0xFEFE,0x8282,0xBABA,0xAAAA,0xBABA,0x8282,0xFEFE,0x0000 }, X { 0x9999,0xCCCC,0x6666,0x3333,0x9999,0xCCCC,0x6666,0x3333 }, X { 0x9999,0x3333,0x6666,0xCCCC,0x9999,0x3333,0x6666,0xCCCC }, X { 0x0000,0x4444,0x2828,0x1010,0x2828,0x4444,0x0000,0x0000 }, X { 0x0000,0x5454,0x0202,0x5858,0x1A1A,0x4040,0x2A2A,0x0000 }, X { 0xAAAA,0x4444,0xAAAA,0x0000,0xAAAA,0x4444,0xAAAA,0x0000 }, X { 0xC3C3,0x6666,0x3C3C,0x1818,0x3C3C,0x6666,0xC3C3,0x8181 }, X { 0xDBDB,0x6666,0x3C3C,0x9999,0x9999,0x3C3C,0x6666,0xDBDB }, X { 0x6666,0xF0F0,0x9999,0x0F0F,0x6666,0xF0F0,0x9999,0x0F0F }, X { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF } X}; X Xstruct MyMsgPort { X struct MsgPort mp; /* A genuine message port */ X struct Pattern pat; /* Current pattern */ X ULONG windowflags; /* Flags for our window */ X UBYTE foreground,background; /* Colours for window */ X} port; X Xtypedef struct MessagePort MP; Xtypedef struct MyMsgPort MyMP; Xtypedef struct IntuiMessage IM; X X#define WINDOWFLAGS (BORDERLESS | BACKDROP) X Xstruct NewWindow nw = { X 0,0, X 320,200, /* Max dimensions will be filled in at run time */ X 0,1, /* These colours are also filled in at run time */ X REFRESHWINDOW, X NULL, /* Window flags will be filled in at run time */ X NULL, NULL, X NULL, X NULL, NULL, X 0,0,0,0, X WBENCHSCREEN X}; X X/* X * The start of the program. All main does is interpret the command line X * parameters, and then determine whether there is already a copy of Backdrop X * running or not. If there isn't, a public message port is set up for X * future reference, else the other copy of Backdrop is informed of the X * changes to the parameters. X * X */ X Xvoid main(argc,argv) Xint argc; Xchar *argv[]; X{ X int quit = NO, error = NO; X UWORD n,i,j; X MyMP *myport; X struct Task *FindTask(), *othertask; X char *p; X int doback(); X void resloop(); X BPTR stdout; X X stdout = Output(); X Write(stdout,usage1,sizeof(usage1)); X X /* Check to see if we are already running. If we are, initialise X * contents of our local port structure with the current contents, X * else initialise them to default values. X */ X X if ((myport = (MyMP *)FindPort(Portname)) == NULL) { X /* --- First time being run --- */ X port.foreground = 1; /* Default pen colour */ X port.background = 0; /* Default background col */ X port.windowflags = SMART_REFRESH | WINDOWFLAGS; /* Window type */ X port.pat = Patterns[0]; /* Default pattern */ X port.mp.mp_Node.ln_Name = Portname; /* Set the port name */ X port.mp.mp_SigBit = AllocSignal(-1L); /* Get signal # for port */ X } else { X /* --- Already running a copy --- */ X port = *myport; /* Get copy of current contents */ X } X X /* Now parse command line, updating parameters as necessary */ X X while (argc > 1) { X if (argv[1][0] == '-') { X n = atoi(&argv[1][2]); /* Get possible second parameter */ X switch (tolower(argv[1][1])) { X case 'a': X port.foreground = n; X break; X case 'b': X port.background = n; X break; X case 'p': X if (n < 0 || n > NUMPATS-1) X n = 0; X port.pat = Patterns[n]; X break; X case 'q': X quit = YES; X break; X case 'f': X port.windowflags = WINDOWFLAGS | SMART_REFRESH; X break; X case 's': X port.windowflags = WINDOWFLAGS | SIMPLE_REFRESH; X break; X default: X error = YES; X break; X } X } else if ((strlen(p = argv[1])) == 16) { X /* Convert 16 digit hex value into pattern */ X for (i = 0; i < 8; i++) { X for (n = 0, j = 0; j < 2; j++,p++) { X n = n<<4 | htoi(*p); X } X port.pat.value[i] = n<<8 | n; X } X } else X error = YES; X X if (error) { X Write(stdout,usage2,sizeof(usage2)); X Write(stdout,usage3,sizeof(usage3)); X exit(10); X } X argv++; X argc--; X } X X /* Now local copy of port contains an up-to-date copy of the X * current settings X */ X X if (myport == NULL) { X /* --- First time being run --- */ X if (quit) X exit(10); /* No work to do if backdrop not active already */ X AddPort(&port); /* Make our port public */ X /* Detach this process from CLI, and setup process ID in port */ X if (!res("Backdrop",4,resloop,4000)) X RemPort(&port); X exit(0); X } else { X othertask = myport->mp.mp_SigTask; X X /* If quit, tell the other copy to quit */ X if (quit) { X Signal(othertask, SIGBREAKF_CTRL_C); X exit(0); X } X X /* Else we have a new pattern to install */ X Forbid(); /* Stop other copy trying to access the array */ X *myport = port; /* Copy updated parameters back to global store */ X Permit(); X Signal(othertask, SIGBREAKF_CTRL_F); /* Force screen update */ X exit(0); X } X} X X/* X * This is the main loop. It just keeps looping around, until it is told X * to exit (via a special return value from doback()). When it returns, X * it actually is returning to AmigaDOS() which will then remove it from X * the system. X * X */ Xvoid resloop() X{ X port.mp.mp_SigTask = FindTask(0L); /* Set pointer to our task */ X while (doback() == REPEAT) /* Do intuition stuff */ X ; X /* We got some kind of exit code, so clean up */ X RemPort(&port); /* Kill our public port */ X} X X/* X * This routine is where all the actual work gets done. A backdrop window X * is opened on the workbench screen, and filled with the current pattern. X * Then it waits for messages from Intuition saying the window needs to be X * refreshed, and for signals from other invocations of Backdrop. A CTRL-C X * signal causes Backdrop to remove itself, and CTRL-F forces the screen X * to be updated. The return value is an error code, in case some resources X * couldn't be allocated (0 or 10). X * X */ X X#define OLIB(a,b) ((a = (struct a *)OpenLibrary(b,33L)) == NULL) X Xint doback() X{ X struct Window *win; X struct RastPort *rp; X struct Screen *scr; X IM *msg; X int err = 10, xmax, ymax,; X ULONG signal,lock; X X if (OLIB(IntuitionBase,"intuition.library")) X goto err1; X X if (OLIB(GfxBase,"graphics.library")) X goto err2; X X /* Now find the maximum size for our window by peeking at the dimensions X * of the Workbench screen. If no workbench screen is open, we exit. X */ X lock = LockIBase(0L); X for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) { X if ((scr->Flags & SCREENTYPE) == WBENCHSCREEN) { X xmax = scr->Width; X ymax = scr->Height; X break; X } X } X UnlockIBase(lock); X X if (scr == NULL) X goto err2; /* If couldn't find workbench screen, we fail */ X X nw.Width = xmax; X nw.Height = ymax; X nw.Flags = port.windowflags; X X if ((win = OpenWindow(&nw)) == NULL) X goto err3; X X err = 0; /* Everything opened ok, so indicate no error */ X rp = win->RPort; X SetDrMd(rp,JAM2); X SetAfPt(rp,&port.pat.value[0],3); /* Set area pattern */ X X X#define IDCMPMASK (1<<win->UserPort->mp_SigBit) X#define CTRL_C (SIGBREAKF_CTRL_C) X#define CTRL_F (SIGBREAKF_CTRL_F) X X while (1) { X SetAPen(rp,port.foreground); X SetBPen(rp,port.background); X RectFill(rp,0,0,xmax,ymax); X signal = Wait(CTRL_C | CTRL_F | IDCMPMASK); X X /* If we got a CTRL_C, break out of this loop */ X if (signal & CTRL_C) X break; X X /* Else was CTRL_F or a refresh event from Intuition */ X X if (signal & IDCMPMASK) { X /* Flush Intuition messages */ X while ((msg = (IM *)GetMsg(win->UserPort)) != NULL) X ReplyMsg((APTR)msg); X } X X /* Now check if user wants a different sort of window type */ X X if (nw.Flags != port.windowflags) { X err = REPEAT; /* Indicate we want to reopen window */ X break; X } X /* Else loop back to start, and force redraw of window */ X } X X /* We get down to here if a CTRL_C is received */ X X err4: X CloseWindow(win); X X err3: X CloseLibrary(GfxBase); X X err2: X CloseLibrary(IntuitionBase); X X err1: X return(err); X} X X/* X * These definitions just stop the corresponding library routines getting X * pulled in, which helps keep the code size down. X */ X Xint brk(){return(0);} Xvoid MemCleanup(){} Xvoid chkabort(){} SHAR_EOF echo "extracting atoi.a" sed 's/^X//' << \SHAR_EOF > atoi.a X* :ts=8 X* X* A very simple function which simply converts an ASCII string to its numeric X* equivalent. It is MUCH smaller than it's equivalent in the Lattice X* library. X* X X xdef atoi X X csect text,0,0,1,2 X Xatoi: X moveq #0,d0 ; Initialise integer to 0 X moveq #0,d1 ; Initialise temporary variable X move.l 4(a7),a0 ; Get pointer to string Xloop: X move.b (a0)+,d1 ; Get next character from string X subi.b #$30,d1 ; Convert to range 0-9 X cmpi.b #10,d1 ; If outside range, X bhi.s exit ; then return to caller X mulu #10,d0 ; Update count X add.l d1,d0 ; Add in new digit X bra.s loop ; And go back for next digit Xexit: X rts ; Return with number in D0 X X end SHAR_EOF echo "extracting res.a" sed 's/^X//' << \SHAR_EOF > res.a X*:ts=8 X***************************************************************************** X* * X* RES.A (C) Copyright Eddy Carroll 1989 * X* * X* This module allows you to make a duplicate copy of your current process. * X* In fact, both processes actually share the same code. However, the * X* seglist pointer of the current process is modified so that when the * X* process terminates, the memory doesn't get freed (if it did, the new * X* process would suddenly find itself deallocated. Hello guru...) * X* This code only works when called from CLI processes. * X* * X* The parameters passed are similar to those for CreateProc(), with the * X* difference that instead of passing a BPTR to a seglist, you pass the * X* address of the function the new process should start executing at. * X* * X* When the new process returns from this function, it will be removed from * X* the system, and its memory (finally) deallocated. * X* * X* The typical use for a function like this is to allow a program to detach * X* itself from a CLI (completely, with no trailing console handles etc.) * X* when it is run. This is a convenient feature for the user, if the program * X* is of the sort designed to sit in the background the whole time, rather * X* than do something immediately, then exit. * X* * X* Lattice provide cback.o which on first look would seem to provide a * X* similar solution. However, cback.o makes it difficult to print error * X* messages to the console if there is an error on the command line - by * X* the time you spot the error, the CLI prompt has already been printed * X* and your error message is printed after it. This looks very messy. * X* In addition, cback.o doesn't let you shut the CLI window after detaching * X* a process, which can be annoying. res doesn't suffer from any such * X* inhibitions. * X* * X* From C, you call it as follows: * X* * X* pid = res(name,pri,func,stacksize) * X* * X* name - pointer to null terminated string * X* pri - integer, priority of the new process * X* func - pointer to the function for new process to call * X* stacksize - integer, size of the stack for the new process * X* * X* pid - Process ID of new process, or 0 if none created * X* * X***************************************************************************** X X INCLUDE "exec/types.i" X INCLUDE "exec/alerts.i" X INCLUDE "exec/nodes.i" X INCLUDE "exec/lists.i" X INCLUDE "exec/ports.i" X INCLUDE "exec/libraries.i" X INCLUDE "exec/tasks.i" X INCLUDE "libraries/dos.i" X INCLUDE "libraries/dosextens.i" X INCLUDE "workbench/startup.i" X INCLUDE "exec/funcdef.i" X INCLUDE "exec/exec_lib.i" X INCLUDE "libraries/dos_lib.i" X X xref SysBase X xref DOSBase X xdef res X XAbsExecBase equ 4 Xsegsize equ 36 ; Size of fake seg. (code = 28 bytes) X X csect text,0,0,1,2 * xref's after this are 16-bit reloc X X xref exit X Xcallsys macro X CALLLIB _LVO\1 X endm X X Xres: X movem.l d2-d4/a2/a3/a6,-(a7) ; Save registers X move.l AbsExecBase.w,a6 ; Get base of Exec library X moveq #0,d1 ; Any sort of memory will do X moveq #segsize,d0 ; Get size of fake segment X callsys AllocMem ; Grab some memory X tst.l d0 ; Did we get any? X beq fatal ; If not, abort immediately! X move.l d0,a3 ; Save pointer to memory X sub.l a1,a1 ; NULL pointer indicates our process X callsys FindTask ; Get pointer to our process block X move.l d0,a2 ; Save it X move.l pr_CLI(A2),a0 ; Get BPTR to our process's segarray X add.l a0,a0 ; Convert BPTR to address X add.l a0,a0 ; X move.l cli_Module(a0),4(a3) ; Make fake segment point to our code X clr.l cli_Module(a0) ; Remove process seg. from CLI seglist X move.l #segsize,(a3) ; Set size of fake seglist X lea.l 8(a3),a2 ; Get pointer to first code byte X X; X; Now a tiny machine code program is constructed. It looks like this: X; X; move.l #$xxxxxx,A4 ; Initialise A4 X; jsr $xxxxxx ; Call user program X; move.l #$xxxxxx,A6 ; Load DOSbase into A6 X; move.l #$xxxxxx,d1 ; Get BPTR to this segment X; jmp UnLoadSeg(A6) ; Unload our process from memory X; X; It's built "on the fly" so to speak, to keep code size down, and also X; because it's a convenient way of initialising all the variables. X; Note that a potential problem exists if DOSBase should somehow alter or X; disappear. We'll assume it will remain relatively stable for the next X; few years anyway :-) X; X X move.l DOSBase,a6 ; Prepare for DOS call X move.w #$287C,(a2)+ ; Store MOVE.L $xxxxxx,A4 instruction X move.l a4,(a2)+ ; Output value of A4 to initialise to X move.w #$4EB9,(a2)+ ; Store JSR $xxxxxx X move.l 36(a7),(a2)+ ; followed by address of user function X move.w #$2C7C,(a2)+ ; Store MOVE.L $xxxxxx,A6 instruction X move.l a6,(a2)+ ; followeds by current DOSbase X; X lea 4(a3),a3 ; Now get seglist ptr to fake segment X move.l a3,d3 ; and convert it to BPTR X lsr.l #2,d3 ; D3 now has seglist ptr to fake seg X move.w #$223C,(a2)+ ; Store MOVE.L $xxxxxx,D1 instruction X move.l d3,(a2)+ ; Followed by BPTR to the segment X move.l #$4EEEFF64,(a2)+ ; Store JMP UnLoadSeg(A6) X; X move.l 28(A7),d1 ; Get pointer to name X move.l 32(A7),d2 ; Get process priority X move.l 40(A7),d4 ; Get stacksize X move.l d1,$03f0 X callsys CreateProc ; Create new process X movem.l (a7)+,d2-d4/a2/a3/a6 ; Pop registers X rts ; Return Xfatal: X moveq #120,d0 ; Set error exit code X jmp exit ; And exit X X end SHAR_EOF echo "extracting tiny.a" sed 's/^X//' << \SHAR_EOF > tiny.a X*:ts=8 X**************************************************************************** X* * X* TINY.A (C) Copyright Eddy Carroll 1989 * X* ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * X* * X* This is a rewrite of the startup code provided with Lattice C V4.0. * X* It is a "bare bones" version, which is substantially smaller, and also * X* allows programs to be linked without needing to access lc.lib (unless * X* of course they are using functions in lc.lib). Only CLI programs are * X* supported, and no default i/o channels or other lattice-specific stuff * X* are initialised. exit() doesn't automatically clean up any more, so * X* don't use things like malloc() and fopen() unless you call free() and * X* fclose() yourself. This replacement is designed for programs that go * X* directly to AmigaDOS and Exec, rather than through the Unix-like Lattice * X* functions. * X* * X* All in all, this version shaves around 1500 bytes off the size of a C * X* program. No guarantees are supplied as regards its suitability for any * X* particular use, other than it works for me. * X* * X* Using it is very simple: Simply modify the command line for BLINK from * X* BLINK FROM LIB:C.O+.... to BLINK FROM TINY.O+... and leave everything * X* else the same. * X* * X* Note that when assembling this, make sure to specify the -u switch on * X* the Lattice assembler's command line. This adds a '_' to all symbols * X* defined. If you are using a different assembler, you need to add a '_' * X* manually yourself. * X* * X**************************************************************************** X X INCLUDE "exec/types.i" X INCLUDE "exec/alerts.i" X INCLUDE "exec/nodes.i" X INCLUDE "exec/lists.i" X INCLUDE "exec/ports.i" X INCLUDE "exec/libraries.i" X INCLUDE "exec/tasks.i" X INCLUDE "libraries/dos.i" X INCLUDE "libraries/dosextens.i" X INCLUDE "workbench/startup.i" X INCLUDE "exec/funcdef.i" X INCLUDE "exec/exec_lib.i" X INCLUDE "libraries/dos_lib.i" X XMAXARGS EQU 32 ; Maximum number of command line arguments from CLI XAbsExecBase EQU 4 ; Welcome to the only fixed point in the universe X X* A useful macro to let us call library routines Xcallsys macro X CALLLIB _LVO\1 X endm X X xdef XCEXIT * exit(code) is standard way to exit C. X xdef exit * X X xref LinkerDB * linker defined base value X xref _BSSBAS * linker defined base of BSS X xref _BSSLEN * linker defined length of BSS X X* library references X X csect text,0,0,1,2 * xref's after this are 16-bit reloc X X xref main * Name of C program to start with. X Xstart: X movem.l d1-d6/a0-a6,-(a7) XREGSIZE EQU (6+7)*4 X lea REGSIZE(a7),A5 * Determine old stack pointer X move.l a0,a2 * Save command pointer X move.l d0,d2 * and command length X lea LinkerDB,a4 * Load base register X X move.l AbsExecBase.W,a6 X move.l a6,SysBase(A4) X move.l a7,_StackPtr(A4) * Save stack ptr X X suba.l a1,a1 X callsys FindTask * Find out our task ID X move.l d0,a3 X X*======================================================================= X*====== CLI Startup Code =============================================== X*======================================================================= X* X* Entry: D2 = command length X* A2 = Command pointer XfromCLI: X move.l a5,D0 * get top of stack X sub.l 4(a5),D0 * compute bottom X add.l #128,D0 * allow for parms overflow X move.l D0,_base(A4) * save for stack checking X*----------------------------------------------------------------------- X* Open the DOS library: X XopenDOS X lea DOSName(A4),A1 X moveq.l #0,D0 X callsys OpenLibrary X move.l D0,DOSBase(A4) X bne getcom XnoDOS: X moveq.l #100,d0 X bra exit2 X X*------ find command name: Xgetcom: X move.l pr_CLI(a3),a0 X add.l a0,a0 * bcpl pointer conversion X add.l a0,a0 X move.l cli_CommandName(a0),a1 X add.l a1,a1 * bcpl pointer conversion X add.l a1,a1 X X*------ collect parameters: X move.l d2,d0 * get command line length X moveq.l #0,d1 X move.b (a1)+,d1 X move.l a1,_ProgramName(A4) X add.l d1,d0 * add length of command name X addq.l #1,d0 * allow for space after command X X clr.w -(A7) * set null terminator for command line X addq.l #1,D0 * force to even number of bytes X andi.w #$fffe,D0 * (round up) X sub.l D0,A7 * make room on stack for command line X subq.l #2,D0 X clr.w 0(A7,D0) X X*------ copy command line onto stack X move.l d2,d0 * get command line length X subq.l #1,d0 X add.l d1,d2 X Xcopy_line: X move.b 0(A2,D0.W),0(A7,D2.W) * copy command line to stack X subq.l #1,d2 X dbf d0,copy_line X move.b #' ',0(a7,d2.w) * add space between command and parms X subq.l #1,d2 X Xcopy_cmd: X move.b 0(a1,d2.w),0(a7,d2.w) * copy command name to stack X dbf d2,copy_cmd X move.l a7,a1 * Get pointer to new command line X X sub.l #(MAXARGS*4),a7 * Reserve space for argv[] X move.l a7,a2 * Initialise base into array X move.l a2,a3 * Save base of argv X moveq #0,d2 * Initialise argc X X* X* From here on down, A1 is pointer into command line X* Xbuild_argv: X bsr.s getnext * Read next character from line X bcs.s doquote * If quote, handle X beq.s build_argv * If white space, skip over it X X lea -1(a1),a0 * Get address of this parameter X bsr.s bumpargv * Store it to argv[] array Xbuild_2: X bsr.s getnext * Get next character X bne.s build_2 * If not white space, keep looking X clr.b -1(a1) * Zero-terminate current argument X bra.s build_argv * And go back to get next argument X Xdoquote: X move.l a1,a0 * Get pointer to this argument X bsr.s bumpargv * Output it to argv[] Xquote_2: X bsr.s getnext * Get next character X bcc.s quote_2 * If not quote, keep looking X clr.b -1(a1) * Zero-terminate current argument Xquote_3: X bsr.s getnext * Get next character X bne.s quote_3 * Skip until space reached X beq.s build_argv * Go back and read next argument X Xbumpargv: X move.l a0,(a2)+ * Output ptr to current argument X addq #1,d2 * Increment argc X cmpi #MAXARGS,d2 * Used up all our arguments yet? X bls.s qrts * If not, then return X moveq #110,d0 * Else set return code X bra.s exit2 * And exit X X* X* Reads next character from command line. If zero, never returns, but X* drops into call to main. Else, returns, with C=1 if character is quote, X* Z=1 if character is white space. X* Xgetnext: X move.b (a1)+,d0 * Get character from command line X beq.s get_2 * Exit if end of line X cmp.b #34,d0 * Check if quote X beq.s isquote * X cmp.b #32,d0 * Check if space X beq.s isspace * X cmp.b #9,d0 * Or tab X beq.s isspace * X cmp.b #10,d0 * Or end of line Xisspace: X andi #$1E,ccr * Clear carry flag, retaining Z Xqrts rts X Xisquote: X ori #1,ccr * Set carry flag X andi #$FB,ccr * Clear zero flag X rts * And return X Xget_2: X move.l a3,-(a7) * Push argv onto stack X move.l d2,-(a7) * Push argc onto stack X X lea _BSSBAS,a3 * get base of BSS X moveq #0,d1 X move.l #_BSSLEN,d0 * get length of BSS in longwords X bra.s clr_lp * and clear for length given Xclr_bss move.l d1,(a3)+ Xclr_lp dbf d0,clr_bss X Xdomain: X jsr main(PC) * Call main(argc,argv) X moveq.l #0,d0 * Set successful status X bra.s exit2 X Xexit: X_exit: XXCEXIT: X move.l 4(SP),d0 * Extract return code Xexit2: X move.l d0,-(a7) X move.l AbsExecBase.W,a6 X move.l DOSBase(A4),a1 X callsys CloseLibrary * Close Dos library X X*------ this rts sends us back to DOS: XexitToDOS: X MOVE.L (A7)+,D0 X movea.l _StackPtr(a4),SP * Restore stack ptr X movem.l (a7)+,d1-d6/a0-a6 X rts X X*----------------------------------------------------------------------- X* Global definitions X* X csect __MERGED,1,,2,2 X* X xdef NULL,SysBase,LoadAddress,DOSBase X xdef _oserr,_OSERR,_ONBREAK X xdef _ProgramName,_StackPtr,_base X* XNULL dc.l 0 X_base dc.l 0 X_oserr equ * X_OSERR dc.l 0 X_ONBREAK dc.l 0 XSysBase dc.l 0 XLoadAddress dc.l 0 X_StackPtr dc.l 0 XDOSBase dc.l 0 X_ProgramName dc.l 0 XDOSName dc.b 'dos.library',0 X X END SHAR_EOF echo "extracting Makefile" sed 's/^X//' << \SHAR_EOF > Makefile X# X# Aztec Make makefile, for Lattice C V4.0 :-) X# X# Backdrop (C) Copyright Eddy Carroll, April 1989 X# X XZOOEXE = backdrop backdrop.doc README System-Configuration XZOOSRC = backdrop.c backdrop.n tiny.a res.a atoi.a tiny.o res.o atoi.o makefile XOBJS = tiny.o res.o atoi.o backdrop.o X X X.c.o: X lc -s -v $*.c X.a.o: X sys:lattice/c/asm -isys:include/ -u $*.a X.n.doc: X nro >$*.doc -ms:an $*.n X X Xall: backdrop backdrop.doc X Xbackdrop: $(OBJS) X blink from $(OBJS) to backdrop sc sd nd map ram:map lib lib:amiga.lib X Xtiny.o: tiny.a Xres.o: res.a Xatoi.o: atoi.a X Xbackdrop.o: backdrop.c Xbackdrop.doc: backdrop.n X Xzoo: backdrop.zoo Xzoosrc: backdropsrc.zoo X Xbackdrop.zoo: $(ZOOEXE) X -delete Backdrop.zoo X zoo a Backdrop.zoo $(ZOOEXE) X Xbackdropsrc.zoo: $(ZOOSRC) X -delete BackdropSrc.zoo X zoo a BackdropSrc.zoo $(ZOOSRC) X Xclean: X -delete "#?.bak" SHAR_EOF echo "extracting Sys-Conf.uu" sed 's/^X//' << \SHAR_EOF > Sys-Conf.uu X Xbegin 644 System-Configuration XM"````@```````)'U```````([)(````!``>A(````````/P`?`#^`'P`A@!X/ XM`(P`?`"&`&X`DP`'`&F``X`$P`'``F``@`%`````@```````````````````J XM`````````````/\````&9@S,``$%50```S,$1.CO`($`+`````!%<'-O;EA;8 XM0T)-7TU04RTQ,C4P70```````````````````````0!0```````!``(```!") XM````0``I17!S;VY86T-"35]-4%,M,3(U,%T`````````````&$`9(``````'L X'`````````'!SC X`` Xend Xsize 232 SHAR_EOF echo "extracting backdrop.uu" sed 's/^X//' << \SHAR_EOF > backdrop.uu X Xbegin 644 backdrop XM```#\P`````````"``````````$```'P````]@```^D```'P2.=^_DOO`#0DZ XM2"0`2?D`````+'@`!"E.`!`I3P`8D\E.KO[:)D`@#9"M``0&@````(`I0``$D XM0^P`)'``3J[]V"E``!QF```(<&1@``#H(&L`K-'(T<@B:``0T\G3R2`"<@`2$ XM&2E)`"#0@5*`0F=2@`)`__Z?P%6`0G<(`"`"4X#4@1^R```@`%."4<C_]A^\V XM`"`@`%."'[$@`"``4<K_^")/G_P```"`)$\F2G0`831E$F?Z0>G__V$<82AF; XM_$(I__]@ZB!)80YA&F3\0BG__V$29OQGV"3(4D(,0@`@8R)P;F!0$!EG)@P`B XM`")G%@P``"!G"@P```EG!`P```H"/``>3G4`/``!`CP`^TYU+PLO`D?Y```#8 XMF'(`(#P````08`(FP5'(__Q.N@#6<`!@!"`O``0O`"QX``0B;``<3J[^8B`?T XM+FP`&$S??WY.=0``2.<X,BQX``1R`'`D3J[_.DJ`9P``<B9`D\E.KO[:)$`@6 XM:@"LT<C1R"=H`#P`!$*H`#PFO````"1%ZP`(+'D````<-/PH?"3,-/Q.N23O* XM`"0T_"Q\),Y'ZP`$)@ODBS3\(CPDPR3\3N[_9"(O`!PD+P`@*"\`*"/!```#^ XM\$ZN_W9,WTP<3G5P>$[Y```!,```<`!R`"!O``02&`0!`#`,`0`*8@C`_``*R XMT(%@[$YU``!.5?_B2.<P`G``*T#_^"M`__PL;``<3J[_Q"M`_^(B+?_B0>P`9 XM-"0(=DTL;``<3J[_T$/L`?`L>``$3J[^>BM`_^Y*K?_N9CH9?``!`]9"+`/7Q XM*7P```D``])![`'Z0^P#PB+8(M@BV"+80>P!\"E(`ZIP_RQX``1.KOZV&4`#F XMKV`0(&W_[D/L`Z!P#2+84<C__`RM`````0`(;P`"`B)M``P@:0`$$!`,```ML XM9@`!`%2(+PA.NO\J6$\B;0`,(&D`!")(4HD2$3M`__8,`0!!;1@,`0!:;A(BN XM2%*)$!%(@$C`!H`````@8`A2B!`02(!(P'(P!$$`"&L``*JPNQ`(9O).^Q`&J XM````<V```(P```!F8```>````'%@``!F````<&```"H```!B8```%@```&%@G XM```","W_]AE``]9@``$2,"W_]AE``]=@``$&,BW_]@Q!``!E!@Q!`!)C!G``I XM.T#_]C`M__9(P.F`0>P!^M'`0^P#PB+8(M@BV"+88```TG`!*T#__&```,@IB XM?```"0`#TF```+PI?```"4`#TF```+!P`2M`__A@``"F(FT`#"!I``0B2$H97 XM9OQ3B9/(*TC_YK+\`!!F``""0FW_]`QM``C_]&1Z<``[0/_R.T#_]@QM``+_1 XM\F1"<``P+?_VZ8`@;?_F$A!(@4C!#!``05S"1`)(@DC")@+GBY:"DH,$@0``* XM`#`"@0````^`@3M`__92;?_R4JW_YF"V,"W_]$C`T(!![`/"T<`P+?_V(@#A= XM08)`,(%2;?_T8(1P`2M`__A*K?_X9SHB+?_B0>P`@20()CP```"<+&P`'$ZND XM_]`B+?_B0>P!'20()CP```#3+&P`'$ZN_]!(>``*3KK\HEA/6*T`#%.M``A@Z XM`/WV2JW_[F9.2JW__&<*2'@`"DZZ_(!83T/L`Z`L>``$3J[^GDAX#Z!(>@":` XM2'@`!$AL`VI.NOQ^3^\`$$J`9@Q#[`.@+'@`!$ZN_IA"ITZZ_$183V!F(FW_I XM[B!I`!`K2/_J2JW__&<:(FW_ZB`\```0`"QX``1.KOZ\0J=.NOP66$\L>``$J XM3J[_?$'L`Z`B;?_N<`TBV%'(__PL>``$3J[_=B)M_^H@/```@``L>``$3J[^= XMO$*G3KK[W%A/3-]`#$Y=3G5(YP`"D\DL>``$3J[^VBE``[!A&@R````G#V?V/ XM0^P#H"QX``1.KOZ83-]``$YU3E7_V$CG(`)P"BM`_^Q#[`-T<"$L>``$3J[]M XMV"E``YA*K`.89P`!V$/L`X9P(2QX``1.KOW8*4`#G$JL`YQG``&R<``L;`.8) XM3J[^8BM`_]P@;`.8*V@`//_T2JW_]&<P(&W_]#`H`!0"0``/4T!F%C`H``Q($ XMP#(H``Y(P2M`_^@K0?_D8`H@;?_T*U#_]&#*(&W_W"QL`YA.KOY<2JW_]&<`6 XM`5`@+?_H.4`#/B`M_^0Y0`-`*6P#T@-(0>P#.BQL`YA.KO\T*T#__$JM__QGK XM``$60JW_[")M__P@:0`R*TC_^")M__AP`2QL`YQ.KOZ>0>P#PB)M__@C2``(1 XM$WP``P`=<``0+`/6+T``"")M__@@+P`(+&P#G$ZN_JIP`!`L`]<O0``((FW_N XM^"`O``@L;`.<3J[^I"\M_^0O+?_H<``O`"\`+RW_^$ZZ`,A/[P`4(FW__"!I\ XM`%9P`!`H``]R`20!X:(`@@``D``@`BQX``1.KO["*T#_X`@M``3_XF9:(FW_R XM_"!I`%9P`!`H``]R`>&A("W_X,"!2H!G*")M__P@:0!6+'@`!$ZN_HPK0/_P^ XM2JW_\&<.(FW_\"QX``1.KOZ&8-@B+`-(LJP#TF<`_S0K?```)P__[$YQ(&W_R XM_"QL`YA.KO^X(FP#G"QX``1.KOYB(FP#F"QX``1.KOYB("W_[$S?0`1.74YU5 XM<`!.=4YU3G5(YS`"+'D```.<(F\`$$SO``\`%$ZN_LY,WT`,3G4``````^P`. XM```!`````````=H````$`````0``!Z8```&.```!%`````X````````#\@``U XM`^H```#F````````````````````````````````````````````````9&]S9 XM+FQI8G)A<GD``````$)A8VMD<F]P("A#*2!#;W!Y<FEG:'0@161D>2!#87)RD XM;VQL(#$Y.#DL(&%D9',@8F%C:V1R;W`@=&\@5V]R:V)E;F-H('-C<F5E;@H`` XM57-A9V4Z($)A8VMD<F]P('LM9B!\("UP(R!\("UQ('P@+7,@?"!",4(R0C-"O XM-$(U0C9"-T(X?0H*"0DM82,@+2!3970@9F]R96=R;W5N9"!C;VQO=7(@=&\@U XM<W!E8VEF:65D('!E;B`C"@D)+6(C("T@4V5T(&)A8VMG<F]U;F0@8V]L;W5RM XM('1O('-P96-I9FEE9"!P96X@(PH`"0DM9B`@+2!%;F%B;&4@9F%S="!U<&1A0 XM=&4@*'5S97,@;6]R92!M96UO<GDI"@D)+7`C("T@57-E('-P96-I9FEE9"!PH XM871T97)N(",@*#$M-2D*"0DM<2`@+2!296UO=F4@8F%C:V1R;W`@9G)O;2!M1 XM96UO<GD*"0DM<R`@+2!%;F%B;&4@<VQO=R!U<&1A=&4*("`@0C%",D(S0C1"" XM-4(V0C="."`M(#$V(&AE>"!D:6=I=',@9&5F:6YI;F<@86X@.'@X('!A='1E6 XM<FX*"CX@`$)A8VMD<F]P``!55:JJ556JJE55JJI55:JJ__]`0$!`0$#__P0$T XM!`0$!(B(````````B(@```````"(B```(B(``(B(```B(@``JJH``*JJ``"JJ XMJ@``JJH``*JJ``!550``JJH``%55``"(B"(BB(@B(HB((B*(B"(BJJJJJE55< XM556JJJJJ55555<S,,S/,S#,SS,PS,\S,,S/__X&!O;VEI:6EO;V!@?___OZ"D XM@KJZJJJZNH*"_OX``)F9S,QF9C,SF9G,S&9F,S.9F3,S9F;,S)F9,S-F9LS,N XM``!$1"@H$!`H*$1$````````5%0"`EA8&AI`0"HJ``"JJD1$JJH``*JJ1$2JJ XMJ@``P\-F9CP\&!@\/&9FP\.!@=O;9F8\/)F9F9D\/&9FV]MF9O#PF9D/#V9F0 XM\/"9F0\/_____________________P`````!0`#(``$````$````````````N XM`````````````````````````````````4)A8VMD<F]P``!I;G1U:71I;VXNX X>;&EB<F%R>0!G<F%P:&EC<RYL:6)R87)Y``````/R> X`` Xend Xsize 3000 SHAR_EOF echo "extracting backdrop.n" sed 's/^X//' << \SHAR_EOF > backdrop.n X.TH BACKDROP 1 "AMIGA Programmer's Manual" "Copyright Eddy Carroll 1989" X.SH NAME Xbackdrop - adds a backdrop behind workbench windows X.SH SYNOPSIS Xbackdrop {-a# | -b# | -f | -p# | -q | -s | b1b2b3b4b5b6b7b8} X.SH DESCRIPTION XBackdrop allows you to define a pattern which will then be displayed on Xthe workbench screen in the normally empty area behind all the windows. XI originally wrote it because I was experimenting an overscan interlaced Xworkbench, and I wanted to get that 'workstation' look. The only program XI had which would give a similar effect was DropCloth by Eric Lavitsky, Xbut this requires Workbench to be loaded. Backdrop will not Xcohabit very well with Workbench, which suits me fine since I hardly Xever use Workbench. X XThe first time you run Backdrop, it detaches itself from the CLI and Xhangs around in memory until you tell it to quit. You can change the Xcurrent settings by running Backdrop again with different options. XOnly those options you specify will be altered, all the others will remain Xunchanged. X XThe following options can be specified: X X-a followed by a number sets the foreground colour used to Xplot the pattern to the pen number specified X(normally 0 to 3). Similarly, -b sets the background colour. X X-f and -s select the window type used by Backdrop. -f uses a SMART_REFRESH Xwindow, which results in fast updating of the screen, but can use up to 64K of Xchip memory (in interlace mode). -s uses a SIMPLE_REFRESH window, which Xgives slower updating of the screen but doesn't use up any chip memory. XIf you can afford the memory, -f looks much more professional. X X-p followed by a number selects one of the built in patterns for display. XPattern 0 is the default pattern. Numbers from 1 upwards select other Xpatterns. If you try to select a non-existant pattern, you get the Xdefault pattern. X X-q tells any copy of Backdrop already resident in memory to remove itself, Xand restore the screen back to normality. If Backdrop isn't already resident, Xthen this option has no effect. X XFinally, you can define your own unique pattern by giving a list of 16 hex Xdigits. These are interpreted as 8 bytes, with each byte corresponding to Xone row of an 8x8 grid. This grid is then replicated over the entire screen Xto form the pattern. Try experimenting with random values to generate some Xunique patterns. X XAny or all of these options may be present on the command line, and Xorder is not important. You can get a summary of these options by invoking XBackdrop with -h (or any other invalid option). X.SH CAVEATS XIf you try running this when Workbench is running, Workbench will disappear X(this could be viewed as a benefit :-) You can quite easily recover XWorkbench by telling Backdrop to quit with the -q option. X.SH DISTRIBUTION XAlthough I retain copyright of Backdrop, it may be freely redistributed Xas long as no charge is made other than to cover distribution costs. X.SH EXAMPLES X.bo "Backdrop Xinstalls a simple backdrop pattern X.br X.bo "Backdrop -a0 -b3 -p1 Xinstalls a red brick wall pattern X.br X.bo "Backdrop -a2 cccc666633339999 Xinstalls dark stripes pattern X.SH AUTHOR XEddy Carroll X.br XThe Old Rectory, X.br XDelgany, Co. Wicklow, X.br XIreland. X XEMAIL: ecarroll@@cs.tcd.ie SHAR_EOF echo "End of archive 1 (of 1)" # if you want to concatenate archives, remove anything after this line exit