/* 
   boxomatic.c    by Gregg Williams               finished 29 May 86
                     BYTE Magazine
                     PO Box 372
                                 Hancock NH  03449

                                     Phone: 603-924-9281
                                     BIX: greggw

   This program shows:
                   dual playfield with bottom playfield visible "under" top
                     playfield and scrolling in two dimensions

           use of the foll=          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

POPCLI II by John Toebes © 1986 The Software Distillery.  All Rights Reserved
 235 Trillingham Ln, Cary, NC 27511
 
Contributions to continue development of this and other fine products for the
Amiga should be sent to the Software Distillery at the above address.

Other Products produced by the Software Distillery are:
   BLINK  - the Turbo-charged Alink replacement
   HACK   - The Amiga port of the famous UNIX game
   MAKE   - A software development tool one shouldn't be without
   KERMIT - The World renown file transfer protocol brought to the Amiga
   ICONEXEC, SETALTERNATE, SETWINDOW - Icon manipulation tools
   TSIZE  - A short utility for determining directory sizes.
All of these are available on our BBS.

Permission is hereby granted to distribute this program provided both this
documentation accompanies the executable and that no charge is made for its
distribution.

POPCLI is designed to solve two problems at once.  First it provides a simple
way of starting another CLI at any time without having to load workbench or
exit whatever program you may be using.  Second it has a builtin screen saver
mode that automatically turns off the Amiga display when there has been no
input for a given period of time.

Once POPCLI is running, you can use it to get a new CLI from whatever program
you are running by pressing Left Amiga and ESC at the same time.  What this
does is to bring the workbench screen to the front and then start up a new
CLI window on the workbench screen.  This is extremely handy when you start
a program from CLI and then find you need to do a CLI command.

The other function that POPCLI performs is to blank the screen for you.  This
saves on the wear of the monitor phospher.  It will do this for you
automatically any time that you have not pressed any key or moved the mouse
for a given period of time regardless of what has been written to the screen.
This is useful when you leave the Amiga on unattended so that you don't have
to mess with the brightness control or worse yet tunr the monitor off putting
wear and tear on its power supply.  Furthermore it only takes a touch of the
mouse or any key on the keyboard to bring it all back.

To use POPCLI, you need to execute the command:
  RUN POPCLI <seconds> <command>

Where <seconds> is any number of seconds after which the screen saver is to
go into effect.  If nothing is specified it defaults to turning off the
screen after 300 seconds. (Five minutes)  Note that it makes its decision to
shut blank the screen solely upon the absence of any keyboard, gameport, or
mouse input.  Even if a program is printing to the screen it will shut down.
This is not a problem, to unblank the screen merely move the mouse or touch any
key (SHIFT or CTRL are excellent choices since they don't do anything).

<command> is the command to be executed when the Left Amiga and ESC keys are
pressed simaultaneously.  By default the command is
   NEWCLI >NIL:
to bring up a CLI window in the center of the screen.  Note the >NIL: on the
command to supress any output that the NEWCLI program may give.  This is
important because at the time the command is executed, the original window
may be long gone.  If you wish to have a CLI come up elsewhere on the screen
you can put the window definition in the command such as:
   NEWCLI >NIL: CON:0/0/640/200/MYCLI
Which will open a CLI to fill the entire screen.  POPCLI does no parsing on
the command, merely passing the ENTIRE string without any processing to
AmigaDOS.

If you wish to specify a command with POPCLI you must include the seconds
value followed by one or more spaces.  Some valid commands are:
   RUN POPCLI 200
   RUN POPCLI 200 NEWCLI >NIL: CON:0/0/640/100/MYWINDOW
   RUN POPCLI 10
   RUN POPCLI 180 NEWCLI >NIL: CON:0/10/640/120/POPUP

To install a copy of POPCLI on your workbench, put a copy of POPCLI in your
C directory and edit the Startup-Sequence file in the S directory to add
a RUN POPCLI command of your own taste.

Notes:
1) Once POPCLI is installed, the only way to get rid of it is to reboot.
2) POPCLI blanks the screen by creating a one bit-blane lo-res screen in front
   of all other screens and setting the background color to solid black.  It
   then turns off the display freeing the cycles for any program that might
   be running.
3) Once the screen blanks, if the AMIGA is left undisturbed for 68.096 years
   the screen may briefly flash back on for the next 68.096 years.  I have not
   taken the time to test this.  If this turns out to be a problem, please
   let me know.

Enhancements Provided under POPCLI II:

* POPCLI now runs from WORKBENCH.  An icon is provided for doing so.  When
  run from workbench, the default command and default times will be used.

* When run from CLI, the original window now goes away.  In doing so, it
  also appears that incompatibilities with 1.2 have been removed.  Please
  feel free to comment on potential future improvements.

* The size of the screen used to blank the display has been reduced to reduce
  memory required to blank the screen.

* POPCLI has been recompiled to take advantage of the latest features of 3.04
  Lattice and BLINK.  Although source is being distributed, it is not likely
  that a version of POPCLI could be reconstructed without these products.
s     Ú(   LONG    pr_Result2          * Value of secondary result from last call
    BPTR    pr_CurrentDir       * Lock associated with current directory
    BPTR    pr_CIS              * Current CLI Input Stream
    BPTR    pr_COS              * Current CLI Output Stream
    APTR    pr_ConsoleTask      * Console handler process for current window
    APTR    pr_FileSystemTask   * File handler process for current drive
    BPTR    pr_CLI              * pointer to ConsoleLineInterpreter
    APTR    pr_ReturnAddr       * pointer to previous stack frame
    APTR    pr_PktWait          * Function to be called when awaiting msg
    APTR    pr_WindowPtr        * Window pointer for errors
    LABEL   pr_SIZEOF           * Process

* DOS Processes started from the CLI via RUN or NEWCLI have this additional
* set to data associated with them

 STRUCTURE CommandLineInterface,0
    LONG   cli_Result2         * Value of IoErr from last command
    BSTR   cli_SetName         * Name of current directory
    BPTR   cli_CommandDir      * Lock associated with command directory
    LONG   cli_ReturnCode      * Return code from last command
    BSTR   cli_CommandName     * Name of current command
    LONG   cli_FailLevel       * Fail level (set by FAILAT)
    BSTR   cli_Prompt          * Current prompt (set by PROMPT)
    BPTR   cli_StandardInput   * Default (terminal) CLI input
    BPTR   cli_CurrentInput    * Current CLI input
    BSTR   cli_CommandFile     * Name of EXECUTE command file
    LONG   cli_Interactive     * Boolean True if prompts required
    LONG   cli_Background      * Boolean True if CLI created by RUN
    BPTR   cli_CurrentOutput   * Current CLI output
    LONG   cli_DefaultStack    * Stack size to be obtained in long words
    BPTR   cli_StandardOutput  * Default (terminal) CLI output
    BPTR   cli_Module          * SegList of currently loaded command
    LABEL  cli_SIZEOF          * CommandLineInterface

	xdef	_XCEXIT			* exit(code) is standard way to leave C.

	xref	_LinkerDB		* linker defined base value
	xref	__BSSBAS		* linker defined base of BSS
	xref	__BSSLEN		* linker defined length of BSS

	xref	_Debug
	xref	__main			* Name of C program to start with.
	xref	_MemCleanup
	xref	_AbsExecBase
	xref	_FindTask
	xref	_DOSBase
	xref	_MathBase
	xref	_MathTransBase

*	library references

	csect	text,0,0,1,2	* any xref's after this are 16-bit reloc

	xref	_LVOAlert
	xref	_LVOFindTask
	xref	_LVOForbid
	xref	_LVOGetMsg
	xref	_LVOOpenLibrary
	xref	_LVOCloseLibrary
	xref	_LVOReplyMsg
	xref	_LVOWait
	xref	_LVOWaitPort
	xref	_LVOOpen
	xref	_LVOClose
	xref	_LVOCurrentDir

start:
	move.l	d0,dosCmdLen
	move.l	a0,dosCmdBuf
	move.l	a7,d0			* save old stack ptr
	movem.l	d1-d6/a0-a6,-(a7)
	move.l	d0,a5
	move.l	_AbsExecBase,a6
	move.l	a6,_SysBase
	move.l	a7,__StackPtr		* Save stack ptr
	clr.l	_WBenchMsg

*------ get the address of our task
	suba.l	a1,a1
	jsr	 _LVOFindTask(a6)
	move.l	d0,a4

*------ are we running as a son of Workbench?
	move.l	pr_CurrentDir(A4),_curdir
	tst.l	pr_CLI(A4)
	beq	fromWorkbench

*=======================================================================
*====== CLI Startup Code ===============================================
*=======================================================================

fromCLI:
	move.l	a5,D0		* get top of stack
	sub.l	4(a5),D0	* compute bottom 
	move.l	D0,__base	* save for stack checking
*------	attempt to open DOS library:
	bsr	openDOS

*------ find command name:
	clr.l	-(sp)
	jsr	_FindTask
	addq.l	#4,sp
	move.l	d0,a0
	move.l	pr_CLI(a0),a0
	add.l   a0,a0		* bcpl pointer conversion
	add.l   a0,a0
	move.l	cli_CommandName(a0),a1
	add.l   a1,a1		* bcpl pointer conversion
	add.l   a1,a1

*------	collect parameters:
	move.l	dosCmdLen,d0		* get command line length
	moveq.l	#0,d1
	move.b	(a1)+,d1
	move.l	a1,__ProgramName
	add.l	d1,d0			* add length of command name
	addq.l	#1,d0			* allow for space after command	

	clr.w	-(A7)			* set null terminator for command line
	addq.l	#1,D0			* force to even number of bytes
	andi.w	#$fffe,D0		*(round up)
	sub.l	D0,A7			* make room on stack for command line
	subq.l	#2,D0
	clr.w	0(A7,D0)

*------ copy command line onto stack
	move.l	dosCmdLen,d0		* get command line length
	move.l	dosCmdBuf,a0
	move.l	d0,d2
	subq.l	#1,d0
	add.l	d1,d2

copy_line:
	move.b	0(A0,D0.W),0(A7,D2.W)	* copy command line to stack
	subq.l	#1,d2
	dbf	d0,copy_line
	move.b	#' ',0(a7,d2.w)		* add space between command and parms
	subq.l	#1,d2

copy_cmd:
	move.b	0(a1,d2.w),0(a7,d2.w)	* copy command name to stack
	dbf	d2,copy_cmd
	move.l	A7,A1
	move.l	A1,-(A7)		* push command line address
	bra	goto_main		        * call C entrypoint

*=======================================================================
*====== Workbench Startup Code =========================================
*=======================================================================

fromWorkbench:

	move.l	TC_SPLOWER(a4),__base	* set base of stack
*------ open the DOS library:
	bsr	openDOS

*------ we are now set up.  wait for a message from our starter
	bsr	waitmsg
	move.l	d0,_WBenchMsg
	move.l	d0,-(SP)
*
	move.l	d0,a2			* get first argument
	move.l	sm_ArgList(a2),d0
	beq.s	do_cons
	move.l	_DOSBase,a6
	move.l	d0,a0
	move.l	wa_Lock(a0),d1
	move.l	d1,_curdir
	jsr	_LVOCurrentDir(a6)
do_cons:TE   LaceWB;
    UBYTE   WorkName[FILENAME_SIZE];
    BYTE    RowSizeChange;
    BYTE    ColumnSizeChange;
    BYTE    padding[14];
};
#define LACEWB 0x01
#define PARALLEL_PRINTER 0x00
#define SERIAL_PRINTER  0x01
#define BAUD_110        0x00
#define BAUD_300        0x01
#define BAUD_1200       0x02
#define BAUD_2400       0x03
#define BAUD_4800       0x04
#define BAUD_9600       0x05
#define BAUD_19200      0x06
#define BAUD_MIDI       0x07
#define FANFOLD         0x00
#define SINGLE          0x80
#define PICA            0x000
#define ELITE           0x400
#define FINE            0x800
#define DRAFT           0x000
#define LETTER          0x100
#define SIX_LPI         0x000
#define EIGHT_LPI       0x200
#define IMAGE_POSITIVE  0x00
#define IMAGE_NEGATIVE  0x01
#define ASPECT_HORIZ    0x00
#define ASPECT_VERT     0x01
#define SHADE_BW        0x00
#define SHADE_GREYSCALE 0x01
#define SHADE_COLOR     0x02
#define US_LETTER       0x00
#define US_LEGAL        0x10
#define N_TRACTOR       0x20
#define W_TRACTOR       0x30
#define CUSTOM          0x40
#define CUSTOM_NAME             0x00
#define ALPHA_P_101             0x01
#define BROTHER_15XL            0x02
#define CBM_MPS1000             0x03
#define DIAB_630                0x04
#define DIAB_ADV_D25            0x05
#define DIAB_C_150              0x06
#define EPSON                   0x07
#define EPSON_JX_80             0x08
#define OKIMATE_20              0x09
#define QUME_LP_20              0x0A
#define HP_LASERJET             0x0B
#define HP_LASERJET_PLUS        0x0C
#define SBUF_512        0x00
#define SBUF_1024       0x01
#define SBUF_2048       0x02
#define SBUF_4096       0x03
#define SBUF_8000       0x04
#define SBUF_16000      0x05
#define SREAD_BITS      0xF0
#define SWRITE_BITS     0x0F
#define SSTOP_BITS      0xF0
#define SBUFSIZE_BITS   0x0F
#define SPARITY_BITS    0xF0
#define SPARITY_NONE     0
#define SPARITY_EVEN     1
#define S