; ; dynTask.s ; ; The background compacting WIMP task ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Dynamite ; ; Dynamite is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Dynamite is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Dynamite. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis GET libs:stream ;----- External dependencies ------------------------------------------------ GET sh.dynHeap GET sh.wSpace GET sh.messages IMPORT dyn_base ;----- Main code ------------------------------------------------------------ AREA |Dynamite$$Code|,CODE,READONLY ; --- dt_service --- ; ; On entry: R1 == service call number ; Other registers depend on R1 ; ; On exit: Depends on service call ; ; Use: Handles service calls for Dynamite EXPORT dt_service dt_service ROUT ; --- Get rid of unwanted services quickly --- CMP R1,#&4A CMPNE R1,#&27 CMPNE R1,#&49 MOVNES PC,R14 ; --- Now dispatch wanted services --- LDR R12,[R12,#0] ;Get my workspace pointer STMFD R13!,{R14} ;Save some useful registers CMP R1,#&27 ;Service_Reset... BEQ %20dt_service CMP R1,#&4A ;Service_StartedWimp BEQ %10dt_service ; --- Service_StartWimp --- LDR R14,dyn_taskHandle ;Get my task handle CMP R14,#0 ;Am I already running? MOVEQ R14,#-1 ;I'm trying to start up STREQ R14,dyn_taskHandle ;Store as my task handle ADREQL R0,dt__commands ;Point to the command string MOVEQ R1,#0 ;Claim the service call LDMFD R13!,{PC}^ ;Return to RISC OS ; --- Service_StartedWimp --- 10dt_service LDR R14,dyn_taskHandle ;Get my task handle CMP R14,#-1 ;Am I already running? MOVEQ R14,#0 ;No -- blank out task handle STREQ R14,dyn_taskHandle ;Store it over the old one LDMFD R13!,{PC}^ ;Return happily ; --- Service_Reset --- 20dt_service MOV R14,#0 ;Blank out my task handle STR R14,dyn_taskHandle ;Store it over the old one LDMFD R13!,{PC}^ ;Return to RISC OS now LTORG ; --- dt__startTask --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Starts up the Dynamite application from a *Command. dt__startTask ROUT LDR R12,[R12] ;Load my workspace address LDR R0,dyn_taskHandle ;Get my task handle variable CMP R0,#-1 ;Am I waiting to start? ADRNEL R0,msg_errDesk ;No -- moan at stupid user ORRNES PC,R14,#V_flag ;And return the error MOV R0,#1 ;We're launching the app STR R0,dyn_launch ;So set the launch flag STMFD R13!,{R14} ;Save a register nicely MOV R0,#2 ;Start my module up ADR R1,dt__myName ;Point to the module name SWI XOS_Module ;Start up the task proper LDMFD R13!,{PC} ;And return to caller dt__myName DCB "Dynamite",0 LTORG ; --- dt_quit --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Closes down Dynamite's WIMP task (used for background ; compaction of the heap). EXPORT dt_quit dt_quit ROUT STMFD R13!,{R0,R1,R14} ;Save some registers LDR R0,dyn_taskHandle ;Find my task handle LDR R1,=&4B534154 ;The magic number thing SWI XWimp_CloseDown ;Close down the application MOV R14,#0 ;Now we don't have a task STR R14,dyn_taskHandle ;So zap my task handle LDMFD R13!,{R0,R1,PC}^ ;And return to caller LTORG ; --- dt_run --- ; ; On entry: R12 == address of module private word ; ; On exit: Via OS_Exit ; ; Use: Runs the Dynamite WIMP task. EXPORT dt_run dt_run ROUT LDR R12,[R12] ;Find my workspace address ADR R13,dyn_pollBlk+256 ;Make a microstack ; --- Is it worth doing anything? --- MOV R0,#0 ;How many Wimp tasks? SWI Wimp_ReadSysInfo ;Read the number back CMP R0,#0 ;Are there any running? SWIEQ OS_Exit ;Nope: then don't bother ; --- Handle the ultra-weird launch sequence --- LDR R14,dyn_launch ;Load the launch flag CMP R14,#0 ;Are we launching? BEQ %50dt_run ;No -- launch then ; --- Start up the WIMP thing --- MOV R0,#200 ;Make it run under RISC OS 2 LDR R1,=&4B534154 ;Get the magic number thing ADR R2,dt__taskName ;Point to the task name SWI Wimp_Initialise ;Start up the WindowManager STR R1,dyn_taskHandle ;Save the task handle ; --- Remove my name from the Switcher's list --- ADR R1,dyn_pollBlk ;Point to the poll block MOV R0,#20 ;Minimum message size STR R0,[R1,#0] ;Save in position 0 MOV R2,#0 ;This is not a reply MOV R3,#&40000 ;The TaskCloseDown message ORR R3,R3,#&000C3 ;It comes in two episodes ADD R0,R1,#12 ;Point to bit of message blk STMIA R0,{R2,R3} ;Build the message in there MOV R0,#17 ;Don't get a reply MOV R2,#0 ;Give everyone a shot at it SWI XWimp_SendMessage ;Send it the message ; --- Now do the main loop --- 00dt_run LDR R14,dyn_hpFlags ;Load the heap's flags TST R14,#hpFlag_tidy ;Is the heap tidy? LDREQ R14,dyn_lockCount ;No -- then load lock count CMPEQ R14,#0 ;Is the heap locked? MOVNE R0,#1 ;Tidy or locked, so be nice MOVEQ R0,#0 ;Otherwise use idles ADR R1,dyn_pollBlk ;Point to my pollblock ADD R13,R1,#256 ;Make a bogus stack SWI Wimp_Poll ;Do the poll thing CMP R0,#0 ;Is it an idle event? SWIEQ Dynamite_Reduce ;Yes -- then reduce the heap CMP R0,#17 ;Is it a message CMPNE R0,#18 ;Of either type LDREQ R0,[R1,#16] ;Get the message type CMPEQ R0,#0 ;Is it a Message_Quit LDRNE R14,dyn_hpFlags ;No -- load the flags BICNE R14,R14,#hpFlag_mSent ;...clear the message sent STRNE R14,dyn_hpFlags ;...save the flags back BNE %00dt_run ;...loop round again ; --- I've been told to quit --- ; ; Seeing as I've viciously and nastily removed myself from ; the TaskManager's task table, I know this must have been ; a broadcast quit, so I hari-kiri with wanton abandon. SWI Wimp_CloseDown ;Close down the task MOV R0,#0 ;No task handle any more STR R0,dyn_taskHandle ;So zero it then SWI OS_Exit ;Farewell, cruel world dt__taskName DCB "DynamiteCompactor",0 ; --- Launch the Compactor task --- 50dt_run MOV R0,#200 ;Make it run under RISC OS 2 LDR R1,=&4B534154 ;Get the magic number thing ADR R2,dt__launchName ;Point to the task name SWI Wimp_Initialise ;Start up the WindowManager MOV R0,#-1 ;Fake a startup sequence STR R0,dyn_taskHandle ;Save this as my task handle LDR R0,=dt__commands ;Point to my main command BL dyn_base ;Find the module base ADD R0,R14,R0 ;Relocate the address SWI Wimp_StartTask ;Start it up nicely SWI Wimp_CloseDown ;Tell WIMP to get knotted SWI OS_Exit ;And kill self evilly dt__launchName DCB "DynamiteLauncher",0 LTORG ; --- dt_message --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Sends a silly message to the Compactor task so that it gets ; control again if it disabled idle events. EXPORT dt_message dt_message ROUT STMFD R13!,{R0-R3,R14} ;Save some registers LDR R14,dyn_taskHandle ;Load my task handle CMP R14,#0 ;Is it vaguely sensible? LDMLEFD R13!,{R0-R3,PC}^ ;No -- don't bother then LDR R14,dyn_hpFlags ;Load the flags TST R14,#hpFlag_mSent ;Has a message been sent? LDMNEFD R13!,{R0-R3,PC}^ ;Yes -- then return ORR R14,R14,#hpFlag_mSent ;Set the flag STR R14,dyn_hpFlags ;And save the flags back ADR R1,dyn_pollBlk ;Point to the poll block MOV R0,#20 ;Minimum message size STR R0,[R1,#0] ;Save in position 0 MOV R2,#0 ;This is not a reply MOV R3,#&4A000 ;A bogus message number ORR R3,R3,#&003C0 ;(My SWI chunk base) ADD R0,R1,#12 ;Point to bit of message blk STMIA R0,{R2,R3} ;Build the message in there MOV R0,#17 ;Don't get a reply MOV R2,R14 ;Get my task handle SWI XWimp_SendMessage ;Send it the message LDMFD R13!,{R0-R3,PC}^ ;And return to caller LTORG ; --- *Commands --- AREA |Dynamite$$Commands|,CODE,READONLY dt__commands DCB "Desktop_DynamiteCompactor",0 DCD dt__startTask DCD 0 DCD synt_compactor DCD help_compactor ;----- That's all, folks ---------------------------------------------------- END