[net.micro.amiga] Creating a DOS Window in a Custom Screen

andy@cbmvax.cbm.UUCP (Andy Finkel) (10/15/86)

Tricks with AmigaDOS, part II.

As you may recall, part one was all about finding the window pointer and
console.device IO Request Block from a DOS window.  Part II is about how
to go the other way: make an Intuition window into a DOS window.  

Specifically, this is used to get a DOS window to open in a custom
screen. There are reasons why this is something you might want to do...
like, oh, using the Execute command to initialize a new disk in a program
that doesn't use the Workbench screen.

We all knew it was possible...remember the first ABasic ? (by MetaCompCo)


For those of you writing shells...under V1.2 the ability to switch a
window in or out of RAW mode via an AmigaDOS packet can be used to
good advantage when combined with this.


There are 3 files:  window.c which contains most of the program, console.asm
which contains the assembler interface calls to the BCPL routines of 
AmigaDOS, and window.i, the include file I use when I am doing tricks
like this.

Break up the file into its component parts, compile, assemble, and link.

Two warning...under the pressure of 1.2 I've only compiled it under the
Greenhills C cross compiler running on the Sun...so some slight changes
may be needed for other compilers.  I'm only linking with the amiga.lib 
on this one.

The other warning...to finish this quickly (as some people need it now)
I used 3 of the BCPL global routines.  (Sorry).  Actually, I
only had to use 2 (finddevice and loaddevice) but as long as I
was doing it, I went ahead and used the DOS sendpacket).  Assembler versions
of those functions are possible (I think, sigh).

Anyway, another completed chapter in the mysteries of AmigaDos.

				andy finkel
				Commodore-Amiga



----------------------CUT HERE------------------------------------------
***********************************************************************
* window.i
* contents: useful macros/definitions from Tim King
* 9/15/86
*
* (c) 1986 Commodore-Amiga, Inc.
* This file may be used in any manner, as long as this copyright notice
* remains intact.
* 		andy finkel
*		Commodore-Amiga
*
***********************************************************************

procst  macro
        link    a6,\1
        movem.l \2,-(sp)
        sub.l   z,z
        endm

return  macro
        movem.l (sp)+,\1
        unlk    a6
        rts
        endm

callg   macro
        move.l  a6,-(sp)
        move.l  #\1,d0
        move.l  _DOSBase,a6
        jsr     -28(a6)
        move.l  (sp)+,a6
        endm
 
* Registers
Z       equr    a0
*P      equr    a1
*G      equr    a2
L       equr    a3
B       equr    a4
S       equr    a5
R       equr    a6

arg1    equ     8
arg2    equ     12
arg3    equ     16
arg4    equ     20

*****************************
* end of file window.i
*****************************

-------------------------CUT HERE -------------------------------
/*        window.c
   or, how to open a DOS window in a custom screen
   and do something like format a disk
   (c) 1986 Commodore-Amiga, Inc.
   This file may be used in any manner, as long as this copyright notice
   remains intact.
  		andy finkel
 		Commodore-Amiga
*/
#include "exec/types.h"
#include "exec/libraries.h"
#include "graphics/gfx.h"
#include "intuition/intuition.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"

#define BLUE 0 
#define WHITE 1 
#define BLACK 2 
#define RED 3 

struct GfxBase *GfxBase; 
LONG *IntuitionBase;
LONG *DosBase;

extern struct Library *OpenLibrary();
extern struct Screen *OpenScreen();
extern struct Window *OpenWindow();

extern struct MsgPort  *NewConsole();

struct Window   *window=NULL;
struct Screen   *screen=NULL;
struct MsgPort  *task=NULL;
struct Process  *process=NULL;

LONG handle=NULL;

struct NewScreen ns = {
        0,0,
        320,200,4, /* & depth */
        BLUE,WHITE,
        NULL,  /* viewmodes */
        CUSTOMSCREEN,
        NULL, /* default font */
        "Window Test Program",
        NULL, /* no user gadgets */
        NULL
};

struct NewWindow nw = {
        0, 12,          /* starting position (left,top) */
        320,186,        /* width, height */
        BLUE,WHITE,    /* detailpen, blockpen */
        NULL,  /* flags for idcmp */
        SMART_REFRESH|WINDOWDEPTH|WINDOWSIZING|WINDOWDRAG|ACTIVATE, /* window gadget flags */
        NULL,           /* pointer to 1st user gadget */
        NULL,           /* pointer to user check */
        NULL,            /* no title */
        NULL,           /* pointer to window screen (add after it is open */
        NULL,           /* pointer to super bitmap */
        50,50,         /* min width, height */
        320,200,        /* max width, height */
        CUSTOMSCREEN};

main()
{
if((IntuitionBase = OpenLibrary("intuition.library",0)) == NULL)cleanup(20);
if((DosBase = OpenLibrary(DOSNAME, 0)) == NULL) cleanup(20);
if((GfxBase = OpenLibrary("graphics.library", 0)) ==NULL) cleanup(20);

if((screen=OpenScreen(&ns)) == NULL)cleanup(20);
nw.Screen=screen;
if((window=OpenWindow(&nw)) == NULL)cleanup(20); 

/* Start up new console handler task; pass it new window */

if(!(task = NewConsole(window)))cleanup(20);

/* Change AmigaDOS consoletask location. All later calls to */
/* Open("*") by this process will refer to the new window */

process = (struct Process *)FindTask(NULL); 
process -> pr_ConsoleTask = task;

process->pr_WindowPtr=window; /*reset error screen so requesters appear here*/

if (!(handle = Open("*", MODE_OLDFILE))) { /* get a handle on the window */
    CloseConsole(task); /* open failed, kill our console task */
    cleanup(20);
   }

    Write(handle,"\033[20hHello world\n",17);

    Write(handle,"I'm about to format drive 1\n",28);
/* SAMPLE COMMAND; THIS IS OPTIONAL, FOR DEMO PURPOSES ONLY) */
	Execute("format <* >* drive df1: name test",0,0);

	cleanup(0);
}


cleanup(code)
{
struct Process *process;

process = (struct Process *)FindTask(NULL); /* reset error window */
process->pr_WindowPtr=NULL;
process -> pr_ConsoleTask = NULL;;

if(handle)Close(handle);
if(screen)CloseScreen(screen);

if(GfxBase)CloseLibrary(GfxBase);
if(DosBase)CloseLibrary(DosBase);

OpenWorkBench(); /* just in case */
if(IntuitionBase)CloseLibrary(IntuitionBase); 

exit(code);

}
/* end of file window.c */

-------------------------CUT HERE ---------------------
**********************************************
* console.asm
* 
* contents: code to spawn a new console task  
* From Tim King (more or less)
* (C) 1986 Commodore-Amiga
*
* (c) 1986 Commodore-Amiga, Inc.
* This file may be used in any manner, as long as this copyright notice
* remains intact.
* 		andy finkel
*		Commodore-Amiga
*
************************************
	include	"window.i"

	xdef	_NewConsole
	xdef	_CloseConsole
	xref	_DOSBase

startup	equ	28	offset into device style DevList structure
			* (the include file said the DevList structure
			* needed some work !)

act_end		equ	1007

g_sendpkt	equ	48
g_loaddevice	equ	112
g_finddevice	equ	124

* task = NewConsole(Window)
* create a console task in an already opened window
* and return its handle
 
_NewConsole:
	procst	#0,d2/a2/a5
	move.l	#conname,d1	d1 = address of "CON" string
	lsr.l	#2,d1		arg1 = BCPL address of string
	callg	g_finddevice	get console device node
	move.l	d0,d1		send it in arg1
	lsl.l	#2,d0		d0 = address of node
	move.l	d0,a2		save it in a2
	move.l	#-1,startup(a2)	tell it not to create another window
	move.l	arg1(a6),d2	arg2 = window structure pointer
	callg	g_loaddevice
	clr.l	startup(a2)	zero startup- we're cool now
	return	d2/a2/a5

* CloseConsole( task )
* shutdown the console task
_CloseConsole:
	procst	#0,d2-d4
	move.l	arg1(a6),d2	d2 = destination task
	move.l	#act_end,d3	d3 = action
	callg	g_sendpkt	send the pkt off
	return	d2-d4

	cnop	0,4

conname	dc.b	3,'C','O','N'

	end

****************************
* end of file console.asm
****************************
-------------------------CUT HERE *********************

-- 

			andy finkel
			Commodore(Amiga)
			{ihnp4|seismo|allegra}!cbmvax!andy
		or	 pyramid!amiga!andy

Any expressed opinions are mine; but feel free to share.

I disclaim all responsibilities, all shapes, all sizes, all colors.

"Remember, no matter where you grow, there you are." - Buckaroo Bonsai.