; osheap_resize_no_fail - Extend or shrink heap without throwing error if shrink fails
; Initial Release 	08-Nov-00	Tony van der Hoff

;OSLib---efficient, type-safe, transparent, extensible,
;   register-safe A P I coverage of RISC O S
;
;   OSLib is free software; you can redistribute it and/or modify
;it under the terms of the GNU General Public Licence as published by
;the Free Software Foundation; either version 1, or (at your option)
;any later version.
;
;   OSLib 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 Licence
;along with this programme; if not, write to the Free Software
;Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A.

	GET HDR.OSHeap

R0      RN      0
R1      RN      1
R2      RN      2
R3      RN      3
R4      RN      4
R5      RN      5
R6      RN      6
R7      RN      7
R8      RN      8
R9      RN      9

A1      RN      0
A2      RN      1
A3      RN      2
A4      RN      3
V1      RN      4
V2      RN      5
V3      RN      6
V4      RN      7
V5      RN      8
V6      RN      9

R       RN      0

SL      RN      10
FP      RN      11
IP      RN      12
SP      RN      13
LR      RN      14
PC      RN      15

	EXPORT	xosheap_resize_no_fail

	AREA	|SWI$$Code|, CODE, READONLY, PIC

;	osheap_resize_no_fail
; 	APCS Compliant
;Entry  A1 =  pointer to heap
;	A2 =  required size change in bytes (signed integer)
;	A3 -> actual size change in bytes (signed integer)
;Exit  	R  =  os_error code
;
;  C Prototype:
;extern os_error *osheap_resize_no_fail( byte* heap,
;				   	 int size_increase
;			               );
;
; This code works around the problem that OSHeap_Resize throws an error if shrink fails.
; OSLib is then unable to return the amount by which the heap shrunk.
; The object code is patched into the library at build time by the MakeFile

xosheap_resize_no_fail ROUT
        MOV     IP, LR			;

        MOV     R3, A2			; required change
        MOV     R1, A1			; pointer to heap
	MOV	R0, #OSHeap_Resize	; reason code
        SWI     XOS_Heap	   	; XOS_Heap
        BVC 	%90			; no error - normal return

        ; Test for Error_HeapExcessiveShrink -  report any other error
	LDR	R1, =Error_HeapExcessiveShrink
	CMP 	R0, R1
	BNE	%99			; return any other error

	; ignore Error_HeapExcessiveShrink
	RSB	R3, R3, #0		; complement R3 to give actual change

	; valid return
90	TEQ	A3, #0			; check null pointer
	STRNE	R3, [A3]		; output R3
	MOV	R,  #0			; clear error pointer

	; exit
99
	[ {CONFIG} = 32
	MOV	PC, IP
	|
        MOVS    PC, IP
	]

	LTORG

	END

