home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / a / assembly / TimeSlice / asm / TimeSlicer
Encoding:
Text File  |  1992-06-25  |  10.2 KB  |  543 lines

  1.     SETTYPE "MODULE"
  2.     OBJECT "!YAMU.Initiator"
  3.     ORG 0
  4.     ASSUME PC,0
  5.     ASSUME R12,&10000000
  6.  
  7.     SET VSTR,"1.00"
  8.  
  9.     DD LANGUAGE,0,0,SERVICE,TITLE,HELP,0,0,0,0,0
  10.  
  11. TITLE   DB "Initiator",0
  12.     ALIGN
  13.  
  14. HELP    DB "Initiator",9,"`VSTR` (",OSVAR "Sys$Date" RIGHT 6," ",OSVAR "Sys$Year",")",0
  15.     ALIGN
  16.  
  17. TASKDESC
  18.     DB "Init",0
  19.     ALIGN
  20.  
  21. LANGUAGE
  22.     LOCALS
  23.     MOV R11,R0
  24.  
  25.     ; Claim memory
  26.  
  27.     MOV R0,#6
  28.     LIT R3,WEND-WSTART
  29.     SWI "OS_Module"
  30.     STR R2,[R12]
  31.     STR R12,[R2]
  32.     MOV R12,R2
  33.  
  34.     ; Initialise variables
  35.  
  36.     MOV R0,#0
  37.     ST R0,MEMORYMAPVETOED
  38.     ST R0,OUTBUFFERREAD
  39.     ST R0,OUTBUFFERWRITE
  40.     ST R0,MESSAGES
  41.     ST R0,SUSPENDED
  42.     ST R0,TERMINATING
  43.     ST R0,HANDLESUSED
  44.  
  45.     ; Register as Wimp task
  46.  
  47.     MOV R0,#200
  48.     LIT R1,&4B534154
  49.     ADR R2,TASKDESC
  50.     SWI "Wimp_Initialise"
  51.     ST R1,TASKHANDLE
  52.  
  53.     ; Calculate appropriate (initial) slot size.  This is not calculated
  54.     ; in any special way, it just tries to allocate a reasonable amount
  55.     ; of space.  The newer applications ask the Wimp for more space if
  56.     ; they run out.
  57.  
  58.     MVN R0,#0
  59.     MVN R1,#0
  60.     SWI "Wimp_SlotSize"
  61.     ADD R0,R0,R1
  62.     ADD R0,R0,R2
  63.     CMP R0,#512*1024
  64.     MOVGE R0,#512*1024
  65.     SUBLT R0,R0,#64*1024
  66.     CMP R0,#0
  67.     MOVLE R0,#16*1024
  68.     MVN R1,#0
  69.     SWI "Wimp_SlotSize"
  70.  
  71.     ; Initialise environment, so that funny things don't happen when the
  72.     ; background task calls the exit handler, etc.  In fact the exit
  73.     ; handler has to come back into this code in order for us to tidy up.
  74.  
  75.     MOV R0,#6 ; Error handler
  76.     ADR R1,ERRORHANDLER
  77.     MOV R2,R12
  78.     ADR R3,ERRORBUFFER
  79.     SWI "OS_ChangeEnvironment"
  80.     ADR R0,OLDERRORHANDLER
  81.     STMIA R0,{R1-R3}
  82.  
  83.     MOV R0,#11 ; Exit handler
  84.     ADR R1,EXITHANDLER
  85.     MOV R2,R12
  86.     MOV R3,#0
  87.     SWI "OS_ChangeEnvironment"
  88.     ADR R0,OLDEXITHANDLER
  89.     STMIA R0,{R1-R3}
  90.  
  91.     ; Set interruption of background task
  92.  
  93.     BL SETCALLAFTER
  94.     BL CLAIMVECS
  95.  
  96.     ; And start the task off
  97.  
  98.     MOV R0,R11
  99.     SWI "OS_Write0"         ; This just writes the name of the command
  100.     SWI "OS_NewLine"        ; run into the output buffer.
  101.     MOV R0,R11
  102.     SWI "OS_CLI"            ; Execute the * command that runs the task.
  103.  
  104.     ; This may return, if no application is started.  In this case, there
  105.     ; is an outstanding ticker event to cancel, but apart from that we
  106.     ; just exit.
  107.  
  108.     ADR R13,USRSTACK
  109.     BL CANCELTICKER         ; Cancel the descheduling time-out.
  110.     BL RELEASEVECS          ; Release vectors we have claimed.
  111.     B KILLMODULE
  112.  
  113. MAINLOOP
  114.     BL RELEASEVECS          ; Must release all vectors before polling.
  115. A
  116.     MOV R0,#0
  117.     ADR R1,POLLBLOCK
  118.     SWI "Wimp_Poll"
  119.     TEQ R0,#0
  120.     BLNE NONIDLEPOLL
  121.     ADR R13,USRSTACK
  122.     BL RECEIVEMESSAGES
  123.     BNE A
  124.  
  125.     ; See whether the output buffer is empty - if not we wait until it
  126.     ; has been emptied before running the task again.
  127.  
  128.     LD R0,OUTBUFFERREAD
  129.     LD R1,OUTBUFFERWRITE
  130.     TEQ R0,R1
  131.     BNE A
  132.  
  133.     ; If the task has been stopped by the controlling task, don't
  134.     ; reschedule it.
  135.  
  136.     LD R0,SUSPENDED
  137.     TEQ R0,#0
  138.     BNE A
  139.  
  140.     ; Set up conditions for re-entering task
  141.  
  142.     BL SETCALLAFTER         ; Create a new CallAfter event
  143.     BL CLAIMVECS            ; and claim the vectors again.
  144.  
  145.     ; If the task is being terminated, get ready to call OS_Exit
  146.  
  147.     LD R0,TERMINATING
  148.     TEQ R0,#0
  149.     MOV R0,#0
  150.     ST R0,TERMINATING
  151.  
  152.     ; Back into the task again.  When restoring the registers, note that
  153.     ; the correct method for doing this is very dependent on the current
  154.     ; processor mode - what is shown is NOT a general way of restoring
  155.     ; a register dump after an exception.
  156.  
  157.     ADR R0,REGBUF
  158.     LDMEQIA R0,{R0-PC}^     ; Restore the task's registers.
  159.     LDMIA R0,{R0-R14}
  160.     MOV R0,#0
  161.     LIT R1,&58454241
  162.     MOV R2,#2
  163.     SWI "OS_Exit"           ; Task is being terminated.  Note how we can
  164.                 ; even call OS_Exit "within" a CallBack handler.
  165.  
  166.     ; General rubbish to do with being a Wimp task, nothing amazing here.
  167.  
  168. NONIDLEPOLL
  169.     TEQ R0,#17
  170.     TEQNE R0,#18
  171.     MOVNES PC,R14
  172.     LD R0,POLLBLOCK+16
  173.     TEQ R0,#0 ; Message_Quit
  174.     MOVNES PC,R14
  175.     ADR R13,USRSTACK
  176.     BL CANCELTICKER
  177.     MOV R0,#0
  178.     ST R0,OUTBUFFERREAD
  179.     ST R0,OUTBUFFERWRITE
  180.  
  181.     ; and continue into KILLMODULE, below.
  182.  
  183.     ; Code to kill the module off.  Nothing here that you don't get in
  184.     ; other modules, the only point worthy of note is that we hang around
  185.     ; in this routine until all the characters have been read out of the
  186.     ; circular buffer.
  187.  
  188. KILLMODULE
  189.     LOCALS
  190.  
  191.     ; Restore environment
  192.  
  193.     MOV R0,#6 ; Error handler
  194.     ADR R1,OLDERRORHANDLER
  195.     LDMIA R1,{R1-R3}
  196.     SWI "OS_ChangeEnvironment"
  197.  
  198.     MOV R0,#11 ; Exit handler
  199.     ADR R1,OLDEXITHANDLER
  200.     LDMIA R1,{R1-R3}
  201.     SWI "OS_ChangeEnvironment"
  202.  
  203.     ; Write the return code into the message word, for the foreground
  204.     ; task
  205.  
  206.     LD R0,RETURNCODE
  207.     ORR R0,R0,#&80000000
  208.     ST R0,MESSAGES
  209.  
  210.     ; Now call Wimp_Poll until all the characters have been removed from
  211.     ; the buffer and the return code has been read
  212.  
  213. A
  214.     MOV R0,#0
  215.     ADR R1,POLLBLOCK
  216.     SWI "Wimp_Poll"
  217.     LD R0,OUTBUFFERREAD
  218.     LD R1,OUTBUFFERWRITE
  219.     TEQ R0,R1
  220.     BNE A
  221.     LD R0,MESSAGES
  222.     TEQ R0,#0
  223.     BNE A
  224.  
  225.     ; Finish off as a Wimp task
  226.  
  227.     LD R0,TASKHANDLE
  228.     LIT R1,&4B534154
  229.     SWI "Wimp_CloseDown"
  230.  
  231.     ; Release workspace
  232.  
  233.     MOV R0,#7
  234.     MOV R2,R12
  235.     SWI "OS_Module"
  236.  
  237.     ; Zero private word so RISC OS doesn't free it again!!
  238.  
  239.     LD R0,PRIVATEWORD
  240.     MOV R1,#0
  241.     STR R1,[R0]
  242.  
  243.     ; ExitAndDie to end program and kill module; don't set return code
  244.     ; as this was set by foreground task.
  245.  
  246.     MOV R0,#0
  247.     MOV R1,#0
  248.     MOV R2,#0
  249.     ADR R3,TITLE
  250.     SWI "OS_ExitAndDie"
  251.  
  252.     ; Just a standard service call handler.  Traps Service_Memory so we
  253.     ; get to keep the memory that the pre-empted task will run in!
  254.  
  255. SERVICE
  256.     ; Nothing to do here except veto attempts by the Wimp to remove all
  257.     ; our memory - this is tried once at the start.
  258.  
  259.     TEQ R1,#&11 ; Service_Memory
  260.     MOVNES PC,R14
  261.     STMFD R13!,{R0,R12,R14}
  262.     LDR R12,[R12]
  263.     LD R0,MEMORYMAPVETOED
  264.     TEQ R0,#0
  265.     LDMNEFD R13!,{R0,R12,PC}^
  266.     MOV R1,#0
  267.     MOV R0,#1
  268.     ST R0,MEMORYMAPVETOED
  269.     LDMFD R13!,{R0,R12,PC}^
  270.  
  271.     ; Claim write character (so we redirect the program's output into
  272.     ; the circular buffer) and open file (so we know what files the
  273.     ; program has open, so we can close them again if it is killed).
  274.  
  275. CLAIMVECS
  276.     MOV R0,#3 ; WrchV
  277.     ADR R1,WRCHV
  278.     MOV R2,R12
  279.     SWI "OS_Claim"
  280.  
  281.     MOV R0,#&D ; FindV
  282.     ADR R1,FINDV
  283.     MOV R2,R12
  284.     SWI "OS_Claim"
  285.  
  286.     MOVS PC,R14
  287.  
  288. RELEASEVECS
  289.     MOV R0,#3 ; WrchV
  290.     ADR R1,WRCHV
  291.     MOV R2,R12
  292.     SWI "OS_Release"
  293.  
  294.     MOV R0,#&D ; FindV
  295.     ADR R1,FINDV
  296.     MOV R2,R12
  297.     SWI "OS_Release"
  298.  
  299.     MOVS PC,R14
  300.  
  301.     ; Schedule a descheduling event.
  302.  
  303. SETCALLAFTER
  304.     MOV R0,#20
  305.     ADR R1,INTERRUPT
  306.     MOV R2,R12
  307.     SWI "OS_CallAfter"
  308.     MOVS PC,R14
  309.  
  310. CANCELTICKER
  311.     STMFD R13!,{R0,R1,R14}
  312.     ADR R0,INTERRUPT
  313.     MOV R1,R12
  314.     SWI "OS_RemoveTickerEvent"
  315.     LDMFD R13!,{R0,R1,PC}^
  316.  
  317. WRCHV
  318.     STMFD R13!,{R1-R2}
  319.     LD R1,OUTBUFFERREAD
  320.     LD R2,OUTBUFFERWRITE
  321.     ADD R2,R2,#2
  322.     BIC R2,R2,#&400
  323.     TEQ R1,R2
  324.     BLEQ CANCELTICKER
  325.     BLEQ SETCALLBACK
  326.     LD R1,OUTBUFFERWRITE
  327.     ADR R2,OUTBUFFER
  328.     STRB R0,[R1,R2]
  329.     ADD R1,R1,#1
  330.     BIC R1,R1,#&400
  331.     ST R1,OUTBUFFERWRITE
  332.     LDMFD R13!,{R1-R2}
  333.     LDMFD R13!,{PC}^
  334.  
  335. FINDV
  336.     LOCALS
  337.     TEQ R0,#0 ; Closing a file
  338.     BEQ A
  339.     STMFD R13!,{R12}
  340.     STMFD R13!,{PC}
  341.     MOVS PC,R14
  342.     MOV R0,R0 ; Our code is re-entered a word further down, so we waste
  343.           ; this word.
  344.     LDMFD R13!,{R12}
  345.     LDMVSFD R13!,{PC}
  346.     STMFD R13!,{R2,R3}
  347.     ADR R2,HANDLES
  348.     LD R3,HANDLESUSED
  349.     TEQ R3,#32
  350.     MOVEQ R3,#31
  351.     STR R0,[R2,R3,LSL #2]
  352.     ADD R3,R3,#1
  353.     ST R3,HANDLESUSED
  354.     LDMFD R13!,{R2,R3}
  355.     LDMFD R13!,{PC}^
  356. A
  357.     TEQ R1,#0 ; Closing all files
  358.     BEQ B
  359.     STMFD R13!,{R2,R8,R9,R14}
  360.     LD R8,HANDLESUSED
  361.     ADR R9,HANDLES
  362. C
  363.     TEQ R8,#0
  364.     LDMEQFD R13!,{R2,R8,R9,PC}^
  365.     LDR R2,[R9],#4
  366.     SUB R8,R8,#1
  367.     TEQ R1,R2
  368.     BNE C
  369.     MOV R2,#0
  370.     STR R2,[R9,#-4]
  371.     LDMFD R13!,{R2,R8,R9,PC}^
  372. B
  373.     STMFD R13!,{R0,R14}
  374.     MOV R0,#0
  375.     ST R0,HANDLESUSED
  376.     LDMFD R13!,{R0,PC}^
  377.  
  378. INTERRUPT
  379.     ; Remember that we must not corrupt R14svc, so we have to mess about
  380.     ; with changing processor mode.
  381.  
  382.     STMFD R13!,{R0,R14}     ; R14irq goes onto irq stack.
  383.     MOVS R0,PC              ; Preserve old processor mode.
  384.     TEQP PC,#3
  385.     MOV R0,R0
  386.     STMFD R13!,{R14}
  387.     BL SETCALLBACK          ; Use CallBack code.
  388.     LDMFD R13!,{R14}
  389.     TEQP R0,#0
  390.     MOV R0,R0
  391.     LDMFD R13!,{R0,PC}^
  392.  
  393.     ; The following is just standard CallBack code, it restores the
  394.     ; handler address to its old value before returning to the main
  395.     ; program loop.
  396.  
  397. SETCALLBACK
  398.     STMFD R13!,{R0-R3,R14}
  399.     MOV R0,#7               ; CallBack
  400.     ADR R1,CALLBACKHANDLER
  401.     MOV R2,R12
  402.     ADR R3,REGBUF
  403.     SWI "OS_ChangeEnvironment"
  404.     ADR R14,OLDCALLBACK
  405.     STMIA R14,{R1-R3}
  406.     SWI "OS_SetCallBack"
  407.     LDMFD R13!,{R0-R3,PC}^
  408.  
  409. CALLBACKHANDLER
  410.     TEQP PC,#0
  411.     MOV R0,R0
  412.     MOV R0,#7
  413.     ADR R1,OLDCALLBACK
  414.     LDMIA R1,{R1-R3}
  415.     SWI "OS_ChangeEnvironment"
  416.     B MAINLOOP
  417.  
  418.     ; If we get an error reported, we write it into the circular buffer
  419.     ; and kill the program.
  420.  
  421. ERRORHANDLER
  422.     MOV R12,R0
  423.     MOV R0,#2
  424.     ST R0,RETURNCODE
  425.     SWI "OS_NewLine"
  426.     ADR R0,ERRORBUFFER+8
  427.     SWI "OS_Write0"
  428.     SWI "OS_NewLine"
  429.     ADR R13,USRSTACK
  430.     BL CANCELTICKER
  431.     BL RELEASEVECS
  432.     B KILLMODULE
  433.  
  434.     ; If the program exits, we tidy up.
  435.  
  436. EXITHANDLER
  437.     ST R2,RETURNCODE
  438.     ADR R13,USRSTACK
  439.     BL CANCELTICKER
  440.     BL RELEASEVECS
  441.     B KILLMODULE
  442.  
  443.     ; These messages control the pre-empted task.  They allow the
  444.     ; controlling process to stop and restart it, terminate it (which
  445.     ; invokes the program's exit handler) and kill it (which will never
  446.     ; reschedule it, and just closes all its files before shutting down).
  447.  
  448. RECEIVEMESSAGES
  449.     LOCALS
  450.     STMFD R13!,{R0,R14}
  451.     LD R0,MESSAGES
  452.     STMFD R13!,{R0}
  453.     TST R0,#&80000000
  454.     MOVEQ R0,#0
  455.     ST R0,MESSAGES
  456.     LDMFD R13!,{R0}
  457.     TEQ R0,#1 ; Suspend
  458.     BEQ A
  459.     TEQ R0,#2 ; Restart
  460.     BEQ B
  461.     TEQ R0,#3 ; Terminate
  462.     BEQ C
  463.     TEQ R0,#4 ; Kill
  464.     BEQ D
  465.     LDMFD R13!,{R0,PC}^
  466. A
  467.     MOV R0,#1
  468.     ST R0,SUSPENDED
  469.     LDMFD R13!,{R0,PC}^
  470. B
  471.     MOV R0,#0
  472.     ST R0,SUSPENDED
  473.     LDMFD R13!,{R0,PC}^
  474. C
  475.     MOV R0,#1
  476.     ST R0,TERMINATING
  477.     LDMFD R13!,{R0,PC}^
  478. D
  479.     MOV R9,#0
  480.     LD R10,HANDLESUSED
  481.     ADR R11,HANDLES
  482. E
  483.     TEQ R10,#0
  484.     BEQ F
  485.     MOV R0,#0
  486.     LDR R1,[R11],#4
  487.     TEQ R1,#0
  488.     ADDNE R9,R9,#1
  489.     SWINE "OS_Find"
  490.     SUB R10,R10,#1
  491.     B E
  492. F
  493.     BL CLAIMVECS
  494.     SWI "OS_WriteS"
  495.     DB 13,10,10,"Killed",13,10,0
  496.     ALIGN
  497.     MOV R0,R9
  498.     ADR R1,ERRORBUFFER
  499.     MOV R2,#16
  500.     SWI "OS_ConvertCardinal4"
  501.     SWI "OS_Write0"
  502.     SWI "OS_WriteS"
  503.     DB " file(s) closed",13,10,0
  504.     ALIGN
  505.     BL RELEASEVECS
  506.     MOV R0,#2
  507.     ST R0,RETURNCODE
  508.     B KILLMODULE
  509.  
  510.     DSECT
  511.     ORG &10000000
  512. WSTART
  513.  
  514.  
  515. PRIVATEWORD     ALLOC 4
  516. MESSAGES        ALLOC 4         ; Messages are written here by a controlling
  517.                 ; task.
  518. OUTBUFFERREAD   ALLOC 4
  519. OUTBUFFERWRITE  ALLOC 4
  520. OUTBUFFER       ALLOC 1024      ; The output circular buffer
  521. TASKHANDLE      ALLOC 4
  522. MEMORYMAPVETOED ALLOC 4
  523. SUSPENDED       ALLOC 4
  524. TERMINATING     ALLOC 4
  525. HANDLESUSED     ALLOC 4
  526. RETURNCODE      ALLOC 4
  527. REGBUF          ALLOC 4*16
  528. OLDCALLBACK     ALLOC 4*3
  529. OLDERRORHANDLER ALLOC 4*3
  530. OLDEXITHANDLER  ALLOC 4*3
  531. HANDLES         ALLOC 4*32
  532. POLLBLOCK       ALLOC 256
  533. ERRORBUFFER     ALLOC 256+4+4
  534.  
  535.         ALLOC 64
  536. USRSTACK
  537.  
  538.  
  539. WEND
  540.     DEND
  541.  
  542.     END
  543.