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.