home *** CD-ROM | disk | FTP | other *** search
RISC OS BBC BASIC V Source | 1995-10-08 | 14.3 KB | 420 lines |
- WimpSWIVe 0.05 - Wimp SWI trapping module
- by AjC of DoggySoft
- Requires BAX 1.00 or later to compile. Source best viewed in a big mode, 114 column formatting
- Note - the list of SWI traps is checked through _backwards_ when looking for pre-trapping code. This means
- that traps at the start of the list get called _after_ those at end. This may confuse some people. ;-)
- trapped_chunk=&400C0
- specialswi=&400F5-&400C0
- chainchunks=512
- os_module_claim=6
- os_module_release=7
- os_module_extend=13
- Workblock constants - wimpprivateword MUST be the first item (don't ask why...)
- w=0 :wk_wimpprivateword=w
- w+=4:wk_wimpswihandler=w
- w+=4:wk_chainptr=w
- w+=4:wk_numberoftraps=w
- code 100000
- 0,"Error in compilation, pass "+
- pass+": "+
- $+", at line "+
- pass=4
- O%=code:P%=0
- [OPT pass
- Equd 0
- Equd mod_init
- Equd mod_quit
- Equd mod_service
- Equd mod_title
- Equd mod_help
- Equd 0
- .mod_chunk
- Equd trapped_chunk
- Equd swi_handler
- Equd swi_table
- Equd 0
- .mod_title
- Equz "WimpSWIVe"
- Align
- .mod_help
- Equs "WimpSWIVe"+
- 2" Equz "0.05 (30 Oct 1995)"
- Align
- .swi_table
- Equz "Wimp"
- Equz "Initialise"
- Equz "CreateWindow"
- Equz "CreateIcon"
- Equz "DeleteWindow"
- Equz "DeleteIcon"
- Equz "OpenWindow"
- Equz "CloseWindow"
- Equz "Poll"
- Equz "RedrawWindow"
- Equz "UpdateWindow"
- Equz "GetRectangle"
- Equz "GetWindowState"
- Equz "GetWindowInfo"
- Equz "SetIconState"
- Equz "GetIconState"
- Equz "GetPointerInfo"
- Equz "DragBox"
- Equz "ForceRedraw"
- I Equz "SetCaretPosition"
- J Equz "GetCaretPosition"
- Equz "CreateMenu"
- Equz "DecodeMenu"
- Equz "WhichIcon"
- Equz "SetExtent"
- Equz "SetPointerShape"
- Equz "OpenTemplate"
- Equz "CloseTemplate"
- Equz "LoadTemplate"
- Equz "ProcessKey"
- Equz "CloseDown"
- Equz "StartTask"
- Equz "ReportError"
- W Equz "GetWindowOutline"
- Equz "PollIdle"
- Equz "PlotIcon"
- Equz "SetMode"
- Equz "SetPalette"
- Equz "ReadPalette"
- Equz "SetColour"
- Equz "SendMessage"
- Equz "CreateSubMenu"
- Equz "SpriteOp"
- Equz "BaseOfSprites"
- Equz "BlockCopy"
- Equz "SlotSize"
- Equz "ReadPixTrans"
- Equz "ClaimFreeMemory"
- Equz "CommandWindow"
- Equz "TextColour"
- Equz "TransferBlock"
- Equz "ReadSysInfo"
- Equz "SetFontColours"
- Equz "GetMenuState"
- Equz "RegisterFilter"
- Equz "AddMessages"
- Equz "RemoveMessages"
- o Equz "SetColourMapping"
- Equz "TextOp"
- q Equz "SetWatchdogState"
- Equz "Extend"
- Equz "ResizeIcon"
- Equb 0
- .wimpmodulename
- Equz "WindowManager"
- Align
- z .wswi
- Equs "WSWI"
- .error_cantquit
- Equd 0
- ~V Equz "WimpSWIVe cannot be quit right now, as some clients are still using it"
- Align
- .error_badrelease
- Equd 0
- % Equz "Bad WimpSWIVe release"
- Align
- .mod_init
- StmFd R13!,{R0-R5,R14}
- ! Mov R0,#os_module_claim
- Mov R3,#w
- Q Swi "XOS_Module" ; claim workspace
- AddVs R13,R13,#4
- LdmVsFd R13!,{R1-R5,Pc}
- .init_jumpin
- Str R2,[R12]
- Mov R12,R2
- Mov R0,#18
- Adr R1,wimpmodulename
- a Swi "XOS_Module" ; find out details of WIMP module
- AddVs R13,R13,#4
- LdmVsFd R13!,{R1-R5,Pc}
- * Str R4,[R12,#wk_wimpprivateword]
- Ldr R0,[R3,#&20]
- Add R3,R3,R0
- \ Str R3,[R12,#wk_wimpswihandler] ; store details in workspace
- Mov R0,#0
- ( Str R0,[R12,#wk_numberoftraps]
- ! Mov R0,#os_module_claim
- Mov R3,#chainchunks
- Swi "XOS_Module"
- AddVs R13,R13,#4
- LdmVsFd R13!,{R1-R5,Pc}
- ^ Str R2,[R12,#wk_chainptr] ; initialise null vector chain
- LdmFd R13!,{R0-R5,Pc}^
- .mod_quit
- StmFd R13!,{R0-R3,R14}
- Ldr R12,[R12]
- ( Ldr R0,[R12,#wk_numberoftraps]
- Teq R0,#0
- LdmNeFd R13!,{R0-R3,R14}
- AdrNe R0,error_cantquit
- ] OrrNeS Pc,R14,#1<<28 ; check we're allowed to quit
- # Mov R0,#os_module_release
- # Ldr R2,[R12,#wk_chainptr]
- Swi "XOS_Module"
- # Mov R0,#os_module_release
- Mov R2,R12
- _ Swi "XOS_Module" ; free claimed RMA then go away
- LdmFd R13!,{R0-R3,Pc}^
- .mod_service
- Teq R1,#&27
- MovNeS Pc,R14
- Ldr R12,[R12]
- StmFd R13!,{R0-R5,R14}
- d B init_jumpin ; re-init when reset service happens
- .swi_handler
- Ldr R12,[R12]
- StmFd R13!,{R9,R10,R14}
- Mov R14,#0
- v StmFd R13!,{R14} ; unset post-flag, initially no post-trapping required
- Teq R11,#specialswi
- LdrEq R14,wswi
- TeqEq R0,R14
- t BEq ourspecialswi ; check if the WimpSWIVe control SWI has been called
- # Ldr R9,[R12,#wk_chainptr]
- ) Ldr R10,[R12,#wk_numberoftraps]
- Add R9,R9,R10,Lsl#4
- .checkchainlooppre
- Sub R9,R9,#16
- SubS R10,R10,#1
- BMi swi_donepre
- Ldr R14,[R9]
- Tst R14,#1<<6
- BNe preloopallswis
- And R14,R14,#63
- Teq R14,R11
- j BNe checkchainlooppre ; go through chain looking for SWI to trap
- .preloopallswis
- Ldr R14,[R9,#12]
- Teq R14,#0
- MovNe R14,#1
- m StrNe R14,[R13] ; set the post-flag if post-trapping required
- Ldr R14,[R9,#8]
- Teq R14,#0
- h BEq checkchainlooppre ; if no pre-trapping to do, back to loop
- StmFd R13!,{R9,R10,R12}
- Orr R10,R14,#3
- Orr R10,R10,#1<<27
- Ldr R12,[R9,#4]
- Mov R9,R11
- ! Adr R14,backfrompretrap
- Orr R14,R14,#3
- Orr R14,R14,#1<<27
- MovS Pc,R10
- Y.backfrompretrap ; call a pre-trap routine
- Mov R10,Pc
- And R10,R10,#&F0000000
- Cmn R9,#1
- LdrEq R9,[R13,#24]
- BicEq R9,R9,#&F0000000
- OrrEq R9,R9,R10
- s StrEq R9,[R13,#24] ; if interception, update return PSR with new flags
- LdmFd R13!,{R9,R10,R12}
- BNe checkchainlooppre
- LdmFd R13!,{R14}
- Teq R14,#0
- LdmEqFd R13!,{R9,R10,Pc}^
- ) Ldr R14,[R12,#wk_numberoftraps]
- Sub R10,R14,R10
- Sub R10,R10,#1
- t B checkchainlooppost ; if interception, act as if SWI had been executed -
- t ; jump into post-trap loop with chain pointer intact
- t ; so that any post-code is called whose pre-code has
- m ; already been done. (Only if post-flag set.)
- .swi_donepre
- LdmFd R13!,{R14}
- Teq R14,#0
- LdmEqFd R13!,{R9,R10,R14}
- r LdrEq Pc,[R12,#wk_wimpswihandler] ; pass on to real SWI if no post-trapping required
- LdmFd R13!,{R9,R10}
- StmFd R13!,{R12}
- ! Adr R14,backfromrealswi
- Orr R14,R14,#3
- Orr R14,R14,#1<<27
- ) Ldr Pc,[R12,#wk_wimpswihandler]
- \.backfromrealswi ; call the swi and post-trap
- LdmFd R13!,{R12}
- StmFd R13!,{R9,R10}
- Mov R10,Pc
- And R10,R10,#&F0000000
- Ldr R9,[R13,#8]
- Bic R9,R9,#&F0000000
- Orr R9,R9,R10
- b Str R9,[R13,#8] ; update return PSR with new flags
- # Ldr R9,[R12,#wk_chainptr]
- ) Ldr R10,[R12,#wk_numberoftraps]
- Sub R9,R9,#16
- .checkchainlooppost
- Add R9,R9,#16
- SubS R10,R10,#1
- LdmMiFd R13!,{R9,R10,Pc}^
- Ldr R14,[R9]
- Tst R14,#1<<6
- BNe postloopallswis
- And R14,R14,#63
- Teq R14,R11
- o BNe checkchainlooppost ; go through chain looking for SWI to post-trap
- .postloopallswis
- Ldr R14,[R9,#12]
- Teq R14,#0
- d BEq checkchainlooppost ; if not post-trapping, back to loop
- StmFd R13!,{R9,R10,R12}
- Ldr R12,[R13,#20]
- And R12,R12,#&F0000000
- Orr R10,R14,#3
- Orr R10,R10,#1<<27
- !` Orr R10,R10,R12 ; pass returned flags to routine
- "" Adr R14,backfromposttrap
- Orr R14,R14,R12
- Orr R14,R14,#3
- Orr R14,R14,#1<<27
- Ldr R12,[R9,#4]
- Mov R9,R11
- MovS Pc,R10
- )Z.backfromposttrap ; call a post-trap routine
- Mov R10,Pc
- + And R10,R10,#&F0000000
- Ldr R9,[R13,#20]
- Bic R9,R9,#&F0000000
- Orr R9,R9,R10
- /b Str R9,[R13,#20] ; update return PSR with new flags
- LdmFd R13!,{R9,R10,R12}
- 1 B checkchainlooppost
- .ourspecialswi
- StmFd R13!,{R0-R4}
- Tst R1,#1<<31
- BEq ourswi_release
- 7^ B ourswi_claim ; split into claim and release
- .ourswi_claim
- :( Ldr R0,[R12,#wk_numberoftraps]
- Add R1,R0,#1
- Mov R0,R0,Lsl#4
- Mov R1,R1,Lsl#4
- Mov R2,#chainchunks
- Sub R2,R2,#1
- Bic R0,R0,R2
- Bic R1,R1,R2
- Teq R0,R1
- C$ BEq claim_noneedtoaddchunk
- D" Mov R0,#os_module_extend
- E# Ldr R2,[R12,#wk_chainptr]
- Mov R3,#chainchunks
- Swi "XOS_Module"
- BVs ourswi_error
- I` Str R2,[R12,#wk_chainptr] ; claim extra memory if required
- .claim_noneedtoaddchunk
- LdmFd R13,{R0-R4}
- Tst R1,#1<<30
- Mp BEq claim_add_lowpriority ; more complex routine needed for low-prio traps
- Bic R1,R1,#1<<31
- O# Ldr R0,[R12,#wk_chainptr]
- P) Ldr R14,[R12,#wk_numberoftraps]
- Add R0,R0,R14,Lsl#4
- Ra StmIa R0,{R1-R4} ; copy information to chain block
- S( Ldr R0,[R12,#wk_numberoftraps]
- Add R0,R0,#1
- Ul Str R0,[R12,#wk_numberoftraps] ; increment numberoftraps, adding it to list
- LdmFd R13!,{R0-R4,R14}
- Wr LdmFd R13!,{R9,R10,Pc}^ ; and intercept SWI, having replaced functionality
- .claim_add_lowpriority
- Z# Ldr R0,[R12,#wk_chainptr]
- [( Ldr R1,[R12,#wk_numberoftraps]
- .claim_lowprioloop
- Cmp R1,#0
- BLe claim_lowputtit
- Ldr R14,[R0]
- Tst R14,#1<<30
- AddEq R0,R0,#16
- SubEq R1,R1,#1
- ct BEq claim_lowprioloop ; find first entry in list to be hi-pri, or list end
- Add R2,R0,R1,Lsl#4
- .claim_budgeuploop
- Cmp R2,R0
- BLe claim_lowputtit
- Ldr R14,[R2,#-16]!
- Str R14,[R2,#16]
- Ldr R14,[R2,#4]
- Str R14,[R2,#20]
- Ldr R14,[R2,#8]
- Str R14,[R2,#24]
- Ldr R14,[R2,#12]
- Str R14,[R2,#28]
- pa B claim_budgeuploop ; shift up all entries after this
- .claim_lowputtit
- Ldr R14,[R13,#4]
- Bic R14,R14,#1<<31
- Str R14,[R0]
- Ldr R14,[R13,#8]
- Str R14,[R0,#4]
- Ldr R14,[R13,#12]
- Str R14,[R0,#8]
- Ldr R14,[R13,#16]
- zZ Str R14,[R0,#12] ; copy new entry into list
- {( Ldr R0,[R12,#wk_numberoftraps]
- Add R0,R0,#1
- }Y Str R0,[R12,#wk_numberoftraps] ; increment numberoftraps
- LdmFd R13!,{R0-R4,R14}
- r LdmFd R13!,{R9,R10,Pc}^ ; and intercept SWI, having replaced functionality
- .ourswi_release
- # Ldr R9,[R12,#wk_chainptr]
- ) Ldr R10,[R12,#wk_numberoftraps]
- .checkchainreleaseloop
- SubS R10,R10,#1
- ! AdrMi R0,error_badrelease
- l BMi ourswi_error ; complain if we reached the end of the list
- Ldr R0,[R9]
- And R0,R0,#63
- And R14,R1,#63
- Teq R0,R14
- LdrEq R0,[R9,#4]
- TeqEq R0,R2
- LdrEq R0,[R9,#8]
- TeqEq R0,R3
- LdrEq R0,[R9,#12]
- TeqEq R0,R4
- AddNe R9,R9,#16
- l BNe checkchainreleaseloop ; check if values match, try next lot if not
- Add R0,R9,#16
- .releaseblockmoveloop
- Teq R10,#0
- LdmGtIa R0!,{R1-R4}
- StmGtIa R9!,{R1-R4}
- SubGt R10,R10,#1
- ` BGt releaseblockmoveloop ; shove list after released down
- ( Ldr R0,[R12,#wk_numberoftraps]
- Sub R1,R0,#1
- Mov R0,R0,Lsl#4
- Mov R1,R1,Lsl#4
- Mov R2,#chainchunks
- Sub R2,R2,#1
- Bic R0,R0,R2
- Bic R1,R1,R2
- Teq R0,R1
- ) BEq release_noneedtoremovechunk
- " Mov R0,#os_module_extend
- # Ldr R2,[R12,#wk_chainptr]
- Mov R3,#chainchunks
- Rsb R3,R3,#0
- Swi "XOS_Module"
- h Str R2,[R12,#wk_chainptr] ; release any extra chunks we don't need
- .release_noneedtoremovechunk
- ( Ldr R0,[R12,#wk_numberoftraps]
- Sub R0,R0,#1
- r Str R0,[R12,#wk_numberoftraps] ; take one off, leaving things nice and consistent
- LdmFd R13!,{R0-R4,R14}
- r LdmFd R13!,{R9,R10,Pc}^ ; and intercept SWI, having replaced functionality
- .ourswi_error
- Mov R9,R0
- LdmFd R13!,{R0-R4,R14}
- Mov R0,R9
- LdmFd R13!,{R9,R10,R14}
- Q OrrS Pc,R14,#1<<28 ; return an error
- g Equs
- 10+"In an emergency, we walk."+
- 10+"And... anything below here is probably a virus."
- "OS_File",10,"<Program$Path>WimpSWIVe",&FFA,,code,O%
-