home *** CD-ROM | disk | FTP | other *** search
- XREF _SysBase,_DOSBase,_stdout ;from startup code
-
- XREF _LVOWait ;from amiga.lib
- XREF _LVOWaitTOF
- XREF _LVOCloseLibrary,_LVOOpenLibrary
- XREF _LVODelay,_LVOWrite
- XREF _CreateTask,_DeleteTask
-
- XREF sprintf ;from functions.o
-
- ; Task.asm - a cheap sub-task example in by C Scheppner. Asm by JG.
- ; Cheap because there is shared data for communication (ie Counter) rather
- ; than using MsgPorts. This runs the risk of the subTask modifying Counter
- ; while the main task is printing out its value. We could use Forbid() and
- ; Permit() in main() to disable the subTask while we print Count, but then
- ; subTask could not be incrementing Count "during" main.
- ; Link with StartUp.o instead of SmallStart.o because we need _stdout.
-
- LIB_VERSION equ 33
-
- SECTION TaskCode,CODE
-
- XDEF _main
- _main:
- movea.l _SysBase,a6
- ;----Open the graphics library
- moveq #LIB_VERSION,d0
- lea GfxName,a1
- jsr _LVOOpenLibrary(a6)
- move.l d0,_GfxBase
- bne.s .5 ;branch if successful open
- lea CantOpenGfx,a0
- bra.s _cleanexit
- ;----create a subTask by calling CreateTask--------
- ;---CreateTask(subTaskName,0,subTaskRtn,2000)-----
- .5 pea 2000 ;stack size, 2K is just enough for a minor task
- pea subTaskCode ;the code where execution starts
- clr.l -(sp) ;no special termination code, main will delete it
- pea _subTaskName ;name of the task
- jsr _CreateTask ;standard C function in amiga.lib (or Manx c lib)
- lea 16(sp),sp
- move.l d0,_subTaskPtr
- bne.s .6 ;branch if successfully created
- lea CantCreateTask,a0
- bra.s _cleanexit
- ;---for 0 to 9 (ie loop 10 times)---------
- .6 moveq #10-1,d6 ;subtract 1 for the Dbra instruction
- movea.l _DOSBase,a6 ;wait while the subTask increments
- ;----Delay(50) (main is a process and can call Delay. subTask can't.)
- .9 moveq #50,d1
- jsr _LVODelay(a6) ;the Counter every 1/60th of a second.
- ;---Print out the current value (whatever it is) of the Counter to the CLI
- move.l _Counter,-(sp)
- lea _buffer,a0 ;where to store the formatted ascii string
- move.l #CounterFormat,d0
- jsr sprintf
- addq.w #4,sp
- move.l d0,d3 ;length of string
- move.l #_buffer,d2
- move.l _stdout,d1
- beq.s skip ;no _stdout? Must have run from WorkBench
- jsr _LVOWrite(a6)
- skip:
- Dbra d6,.9
- ;---Close everything after 10 loops
- bra.s .14
-
- XDEF _cleanexit
- _cleanexit:
- ;---Print the passed string message (in a0) to the CLI
- move.l _stdout,d1
- beq.s .14 ;no _stdout? Must have run from WorkBench
- move.l a0,d2
- len move.b (a0)+,d0
- bne.s len
- move.l a0,d3
- sub.l d2,d3 ;length of string
- movea.l _DOSBase,a6
- jsr _LVOWrite(a6)
- .14 movea.l _SysBase,a6
- ;---If subTask exists, then set PrepareToDie to tell it "Get ready to be
- ; deleted, you heathen pig!"
- move.l _subTaskPtr,d0
- beq.s .19
- lea _PrepareToDie,a0
- Bset.b #0,(a0)
- ;---(Busy) Wait for subTask to recognize PrepareToDie, then delete subTask.
- ; (subTask will clear PrepareToDie before it goes to sleep)
- .20 Btst.b #0,(a0)
- bne.s .20 ;"Finish incrementing Counter and recognize us, scum!"
- ;----Delete the subTask
- move.l d0,-(sp) ;address of SubTask
- jsr _DeleteTask ;standard C Function
- addq.w #4,sp
- ;---If graphics library is open, close it
- .19 move.l _GfxBase,d0
- beq.s .22
- movea.l d0,a1
- jsr _LVOCloseLibrary(a6)
- ;--- exit the program (i.e. return to the startup code)-----
- .22 rts
-
- ;subTaskCode increments the Counter every 1/60 second until main tells it to
- ;"prepare to be deleted" by setting bit #0 of PrepareToDie. subTask then
- ;clears PrepareToDie, telling main() that it is now waiting to be deleted.
- ;It calls the Wait function with a mask of 0. This task will never wake up
- ;in a million years when you pass a 0 to Wait, but it doesn't matter because
- ;main is going to delete it.
-
- XDEF subTaskCode
- subTaskCode:
- movea.l _GfxBase,a6
- ;---increment the counter until _main() says "PrepareToDie" (sets bit #0)
- .26 jsr _LVOWaitTOF(a6) ;slight delay (of 1/60 sec) inbetween each inc
- addq.l #1,_Counter
- Bclr.b #0,_PrepareToDie ;Should I Wait?
- beq.s .26
- ; At this point, subTask has just cleared PrepareToDie, telling _main
- ; "I'm ready to be deleted". Now, Wait forever (or until _main deletes me)
- moveq #0,d0 ;0 = wait forever, never returns from Wait
- movea.l _SysBase,a6
- jmp _LVOWait(a6)
-
- SECTION TaskData,DATA
-
- XDEF _subTaskPtr,_subTaskName
- _subTaskPtr dc.l 0
-
- ; Data shared by main and subTaskRtn
- XDEF _GfxBase,_Counter,_PrepareToDie
- _GfxBase dc.l 0
- _Counter dc.l 0 ;the hex Counter value
- _PrepareToDie dc.b 0
-
- ; Strings
- _subTaskName dc.b 'Example SubTask',0
- GfxName dc.b 'graphics.library',0
- CantOpenGfx dc.b 'Cannot open graphics.library',0
- CantCreateTask dc.b 'Cannot create the subTask',0
- CounterFormat dc.b 'Counter = %ld',10,0
-
- _buffer ds.b 40 ;we store our ascii "numeral" Counter here
-
- END
-