;; (WOW! LISP-like comments!)
;; This file is for the MPW assembler.
;; MPW can't deal with assembler code in C source files like CW can.
;; If you do not use MPW then you have no use for this file.
MACRO
	MakeFunction &fnName
		EXPORT &fnName[DS]
 		EXPORT .&fnName[PR]
		
		TC &fnName[TC], &fnName[DS]
			
		CSECT &fnName[DS]
			DC.L .&fnName[PR]
 			DC.L TOC[tc0]
		
		CSECT .&fnName[PR]
		FUNCTION .&fnName[PR]	
ENDM
	
	toc
		tc gZeroDouble[TC], gZeroDouble[ro]
		
	csect gZeroDouble[ro]
		dc.l 0x00000000
		dc.l 0x00000000

	

;===============================
; p is in r3, bytes in r4
; I now use r6 to hold result of ANDing destination address; no longer have to worry about
; clobbering and reloading r0.
	MakeFunction	_BLAsmZeroMemory

	cmplwi		r3,0			; Check for nil pointer
	beqlr-						; Return if equal (to nil)
	li			r0,0			; Load zero value
	cmplwi		r4,16			; If less than 16 bytes to copy...
	ble-		@SetupCopyByte	;	copy byte by bye at end
@AlignByte
	rlwinm.		r6,r3,0,31,31	; Check bit 31
	beq+		@AlignShort		; If bit 31 is clear, try to align to short
	stb			r0,0(r3)		; Store zero byte to ptr
	addi		r3,r3,1			; Increment ptr
	subi		r4,r4,1			; Decrement bytes to copy
@AlignShort
	rlwinm.		r6,r3,0,30,30	; Check bit 30
	beq+		@AlignLong		; If bit 30 is clear, try to align to long
	sth			r0,0(r3)		; Store zero short to ptr
	addi		r3,r3,2			; Increment ptr
	subi		r4,r4,2			; Decrement bytes to copy
@AlignLong
	rlwinm.		r6,r3,0,29,29	; Check bit 29
	beq			@SetupCopyDouble; If bit 29 is clear, try to align to double
	stw			r0,0(r3)		; Store zero long to ptr
	addi		r3,r3,4			; Increment ptr
	subi		r4,r4,4			; Decrement bytes to copy
@SetupCopyDouble
	lwz			r6,gZeroDouble[TC](RTOC)
	lfd			fp0,0(r6)		; Set fp register 0 to zero value. There is no
								;	floating-point load immediate instruction (too bad) so we
								;	have to use a global.
	subi		r3,r3,8			; Back up so store double with update instruction (stfdu)
								;	can add 8 to ptr to get store location
@CheckDouble
	cmplwi		r4,8			; At least 8 bytes left to copy?
	blt-		@DoneWithDouble	; Clean up if not
@ZeroDouble
	stfdu		fp0,8(r3)		; Store double to memory offset by immediate value
								;	(in this case, 8) and increment r3 by that amount
	subi		r4,r4,8			; Decrement bytes to copy
	b			@CheckDouble	; Loop over double-storing code
@DoneWithDouble
	addi		r3,r3,8			; Reset r3 to point to next byte to be zeroed
@SetupCopyByte
	subi		r3,r3,1			; Do the same trick as with doubles, except we
								;	only 'autoincrement' by 1
@CheckByte
	cmplwi		r4,0			; Zero bytes left to copy?
	beqlr-						; Return if so
@CopyByte
	stbu		r0,1(r3)		; Store byte to memory offset by the immediate value (1)
								;	and autoincrement by 1. This is like saying *(++p) = 0;
	subi		r4,r4,1			; Decrement bytes left
	b			@CheckByte		; Loop over byte-storing (exit condition is there)

	csect ._BLAsmZeroMemory[pr]
	dc.b '_BLAsmZeroMemory'
