home *** CD-ROM | disk | FTP | other *** search
- /*================================================*/
- /* TVTNEW.C */
- /* */
- /* Requires MASM or A86 to recompile */
- /* */
- /* (c) Copyright 1988 Ralf Brown */
- /* All Rights Reserved */
- /* May be freely copied for noncommercial use as */
- /* long as this copyright notice is kept intact */
- /* and any changes are indicated in the comment */
- /* blocks for the functions */
- /*================================================*/
-
- #pragma inline
-
- #include <stdio.h>
- #include <string.h>
- #include "tvapi.h"
-
- /*================================================*/
-
- static int task_busy = 0 ;
- static void (*start_addr)(int) ;
- static char far *user_stack ;
- static int start_row, start_col ;
- static int free_stack ;
- static int stack_size ;
- static int switchmenu ;
-
- /*================================================*/
- /* task_start initial startup code for task */
- /* Ralf Brown 5/6/88 */
- /* Ralf Brown 6/3/88 move initial win pos'ning */
- /* into here */
- /*================================================*/
-
- static void far task_start(void)
- {
- void (*startaddr)(int) ;
- int parent ;
- char far *stack ;
- int freestack ;
-
- asm mov ax,DGROUP /* restore DS to proper segment */
- asm mov ds,ax
- asm cli /* can't have interrupts when switching stacks */
- asm mov ss,word ptr user_stack+2
- asm mov sp,word ptr user_stack
- asm sti /* interrupts OK now */
- asm mov ax,sp /* store stack pointer for later use */
- asm mov bp,sp /* set up stack frame */
- asm sub sp,12 /* up to 4 bytes for "startaddr", 8 bytes for others */
- asm mov parent,dx /* store the segment of parent's task object */
- asm sub ax,word ptr stack_size /* calculate start of stack area */
- asm mov stack+2,ss
- asm mov stack,ax
-
- startaddr = start_addr ;
- freestack = free_stack ;
- TVwin_move(NIL,start_row,start_col) ; /* move the window to the desired pos */
- if (switchmenu) /* if the child does the win_top, it is put on the */
- {
- TVwin_top(NIL) ; /* Switch Windows menu */
- TVwin_redraw(NIL) ;
- }
-
- /* now we can let the parent task create yet another task, since we're */
- /* done with the static variables */
- task_busy = 0 ;
-
- (*startaddr)(parent) ; /* jump to real start of task */
- TVostack() ; /* started on private stack, have to switch back */
- if (freestack)
- free((char *)stack) ;
- TVtask_free(NIL) ; /* task is done, so kill it */
- }
-
- /*================================================*/
- /* TVnew_task create a new task */
- /* Ralf Brown 5/2/88 */
- /* Ralf Brown 6/3/88 add parms for init win pos */
- /* Ralf Brown 7/23/88 add switch_menu parameter */
- /*================================================*/
-
- OBJECT pascal TVtask_new(OBJECT parent,char *title,int row,int col,int rows,int cols,char *stack,int stacksize,void (*startaddr)(int),int switch_menu)
- {
- PARMLIST8 p ;
- char old_title[32] ;
- int i ;
-
- busy_wait:
- asm mov al,1
- asm lock xchg al,task_busy
- asm or al,al
- asm jz busy_done
- TVpause() ;
- asm jmp busy_wait
- busy_done:
-
- start_addr = startaddr ;
- start_row = row ;
- start_col = col ;
- switchmenu = switch_menu ;
- if (stack == NULL)
- {
- if (stacksize < 256)
- stacksize = 256 ;
- if ((stack = malloc(stacksize)) == NULL)
- return NIL ; /* can't get stack, so can't run */
- stack = stack + stacksize ;
- free_stack = TRUE ;
- stack_size = stacksize ;
- }
- else
- free_stack = FALSE ;
- user_stack = (char far *) stack ;
- p.num_args = 8 ;
- if (title)
- {
- p.arg[0] = (DWORD)(char far *)title ;
- p.arg[1] = (DWORD) strlen(title) ;
- }
- else
- {
- TVqry_title(parent,old_title,sizeof(old_title)) ;
- p.arg[0] = (DWORD)(char far *)old_title ;
- for (i = sizeof(old_title)-1 ; i > 0 && old_title[i] == ' ' ; i--)
- ;
- p.arg[1] = (DWORD) i ;
- }
- if (rows < 0)
- TVqry_size(parent,&rows,&i) ;
- if (cols < 0)
- TVqry_size(parent,&i,&cols) ;
- p.arg[2] = (DWORD) rows ;
- p.arg[3] = (DWORD) cols ;
- p.arg[4] = (DWORD) 0 ; /* no additional allocation */
- p.arg[5] = (DWORD) -1 ; /* use default task stack size */
- p.arg[6] = (DWORD) 0 ;
- p.arg[7] = (DWORD) (void far (*)(void)) task_start ;
- TVsendmsg(NEW_MSG, parent?TOS:ME, parent, (PARMLIST *)&p) ;
- if (!switch_menu) /* if the parent does the win_top, the task is not */
- { /* put on the Switch Windows menu */
- while (task_busy)
- TVpause() ; /* give child task a chance to start up */
- TVwin_top((OBJECT) p.arg[0]) ;
- TVwin_redraw((OBJECT) p.arg[0]) ;
- }
- return (OBJECT) p.arg[0] ;
- }
-
- /* End of TVTNEW.C */
-