I compared the AROS "clearmem" code with the corresponding code in Kickstart 1.3 ($FF4EF4).
This routine is called with a BPTR in D1, and a length/count (number of longwords) in D2.
There are differences between the AROS and Kickstart versions of this routine:
- If count is negative (bit 31 set), the Kickstart routine just returns (with the original BPTR in D1 unchanged).
- If count is not negative, the Kickstart routine returns a pointer to the memory in D1. (That is, D1 on entry shifted right by 2.)
- The AROS version clears one fewer longword than the Kickstart version. Kickstart clears count+1 longwords, e.g. if D2 contain 10, the routine clears 11 longwords. Like the current AROS code, the Kickstart routine uses a DBF loop to do the clearing, so only the lower word of the length in D2 is used.
A modified version of clearmem that should behave more like the Kickstart one is below (completely untested). The Kickstart routine uses A3 as a scratch register so is slightly shorter than this.
BCPL clearmem /* -50, void, @buff, lw_length */
move.l %d1,%d0 ;Value which is returned if length negative
tst.l %d2 ;Check length
bmi.b .Done ;Do nothing if negative
.Continue
lsl.l #2,%d1 ;BPTR to APTR
move.l %d1,%d0 ;Routine returns pointer to memory (maybe an undocumented feature?)
.Lclearmem_loop:
clr.l %a0@(%d1)
addq.l #4,%d1
dbf %d2,.Lclearmem_loop
.Done
BRTS
Negative length check added.
Other suggestion not done, side-effects in original code will be never copied 1:1 without proof that they are actually used.
It's quite likely the Kickstart routine clearing one more longword than the argument is by design; if not, surely a memory-corrupting bug like that would have been found before Kickstart 1.3?
Do you know which programs use the clearmem routine? I can try disassembling some to hopefully determine what they are trying to do and give a definite answer.
On the Workbench 1.3.2 disk, these programs call clearmem a.k.a. clearvec:
- c/SetDate
- c/Dir
- l/Newcon-Handler
- l/Shell-Seg
- l/Ram-Handler
- l/Aux-Handler
As you're probably only too aware, getting a meaningful disassembly of BCPL programs is a bit of a pain. :-/
However I did disassemble SetDate and it appears to confirm that BCPL clearvec should clear argument+1 longwords. Here's an extract:
; Struct DateStamp is 3 longwords, the 3rd being number of ticks past the minute
.ArgsOkay MOVEQ #2,D2 ;To clear *3* longwords
MOVE.L ($8C,A1),D1 ;BPTR to memory for datestamp
MOVE.L #$A8,D0
MOVEA.L (-$50,A2),A4 ;clearvec
JSR (A5)
MOVE.L ($8C,A1),D1 ;BPTR to memory for datestamp
MOVE.L #$A8,D0
MOVEA.L ($158,A2),A4 ;datstamp
JSR (A5)
The AROS clearmem bug is probably masked due to AROS getvec always using MEMF_CLEAR. And in the SetDate case it doesn't matter because the datstamp call will fill the buffer anyway. And clearmem is only used by a few programs as far as I know. (It's used internally by dos.library too.)