; ; libOpts.s ; ; Allow options for library units to be declared ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sapphire library. ; ; Sapphire 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. ; ; Sapphire 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 Sapphire. 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 sapphire:sapphire GET sapphire:suballoc ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- libOpts_register --- ; ; On entry: R0 == address of an options block ; ; On exit: -- ; ; Use: Adds the block given to the library options. EXPORT libOpts_register libOpts_register ROUT STMFD R13!,{R0,R1,R12,R14} ;Save some registers WSPACE lo__wSpace ;Locate my workspace BL sub_init ;Awaken suballoc just in case MOV R1,R0 ;Look after the block addr MOV R0,#8 ;Allocate a small link block BL sub_alloc ;Try to allocate memory LDMVSFD R13!,{R0,R1,R12,PC}^ ;If it failed, don't bother STR R1,[R0,#0] ;Remember this block pointer LDR R14,lo__head ;Load the current list head STR R14,[R0,#4] ;Save this as the next link STR R0,lo__head ;And save new list head LDMFD R13!,{R0,R1,R12,PC}^ ;And return to caller LTORG ; --- libOpts_find --- ; ; On entry: R0 == magic marker word ; ; On exit: CS if found, and ; R0 == address of options block ; else CC, and ; R0 corrupted ; ; Use: Tries to find an option with the given marker, which will ; normally be a four-character text string. The first match ; found will be returned. The options blocks are searched in ; reverse order of registration (i.e. blocks registered later ; will override blocks registered reviously). EXPORT libOpts_find libOpts_find ROUT STMFD R13!,{R1-R3,R12,R14} ;Save some registers away WSPACE lo__wSpace ;Find my workspace MOV R2,R0 ;Look after the marker LDR R1,lo__head ;Load the list head block ; --- Scan through the list --- 10libOpts_find CMP R1,#0 ;Reached the end yet? BEQ %50libOpts_find ;Yes -- return to caller LDMIA R1,{R0,R1} ;Load the block ptr and link ; --- See if we can find it in here --- 20libOpts_find LDMIA R0!,{R3,R14} ;Load marker and size word CMP R2,R3 ;Does this match up? BEQ %40libOpts_find ;Yes -- found it then CMP R3,#-1 ;Is this the block end? ADDNE R0,R0,R14 ;No -- move on to next item BNE %20libOpts_find ;And loop round again B %10libOpts_find ;Try the next options block ; --- Found a match --- 40libOpts_find LDMFD R13!,{R1-R3,R12,R14} ;Restore registers ORRS PC,R14,#C_flag ;Return successfully ; --- Failed to find a match --- 50libOpts_find LDMFD R13!,{R1-R3,R12,R14} ;Restore registers BICS PC,R14,#C_flag ;Return unsuccessfully LTORG lo__wSpace DCD 0 ;----- Workspace ------------------------------------------------------------ ^ 0,R12 lo__wStart # 0 lo__head # 4 ;Base of the options list lo__wSize EQU {VAR}-lo__wStart AREA |Sapphire$$LibData|,CODE,READONLY DCD lo__wSize DCD lo__wSpace DCD 0 DCD 0 ;----- That's all, folks ---------------------------------------------------- END