Code: Select all
Structure FillMemoryExStruct
StructureUnion
b.a
w.w
l.l
q.q
EndStructureUnion
EndStructure
Procedure FillMemoryEx(*Memory, Size, FillData.s)
If Size = 0 : ProcedureReturn : EndIf
; ** convert fill data into bytes **
Protected *m.FillMemoryExStruct = @FillData
Protected *m1.FillMemoryExStruct = @FillData
Protected d.FillMemoryExStruct
Protected b.a, nibble
Repeat
b = *m\b
Select b
Case $30 To $39; 0 - 9
d\q = (d\q << 4) | (b - $30)
nibble + 1
Case $41 To $46; A - F
d\q = (d\q << 4) | (b - $37)
nibble + 1
Case $61 To $66; a - f
d\q = (d\q << 4) | (b - $57)
nibble + 1
Default
If nibble > 8
*m1\q = d\q
*m1 + 8
ElseIf nibble > 4
*m1\l = d\l
*m1 + 4
ElseIf nibble > 2
*m1\w = d\w
*m1 + 2
ElseIf nibble > 0
*m1\b = d\b
*m1 + 1
EndIf
nibble = 0
EndSelect
*m + SizeOf(Character)
Until b = 0
Protected numBytes = *m1 - @FillData
If numBytes = 0 : ProcedureReturn : EndIf
; ** actual fill routine
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Protected r_ebx, r_edi, r_esi
MOV r_ebx, ebx
MOV r_edi, edi
MOV r_esi, esi
MOV esi, FillData
MOV edx, numBytes
MOV edi, *Memory
MOV ecx, Size
!mov ebx, edx
!fmex_loop:
!mov al, [esi]
!inc esi
!dec ebx
!jnz fmex_skip
!sub esi, edx
!mov ebx, edx
!fmex_skip:
!mov [edi], al
!inc edi
!dec ecx
!jnz fmex_loop
MOV ebx, r_ebx
MOV edi, r_edi
MOV esi, r_esi
CompilerElse
MOV r10, FillData
MOV rdx, numBytes
MOV r11, *Memory
MOV rcx, Size
!mov r8, rdx
!fmex_loop:
!mov al, [r10]
!inc r10
!dec r8
!jnz fmex_skip
!sub r10, rdx
!mov r8, rdx
!fmex_skip:
!mov [r11], al
!inc r11
!dec rcx
!jnz fmex_loop
CompilerEndIf
DisableASM
ProcedureReturn
EndProcedure
; ** example code **
memSize = 10000000
*mem = AllocateMemory(memSize)
FillMemoryEx(*mem, memSize, "0D 0A"); fill memory with bytes $0D $0A
FillMemoryEx(*mem, memSize, "0a0d"); fill memory with word $0A0D
FillMemoryEx(*mem, memSize, "1234567890abcdef"); fill memory with quad $1234567890abcdef
FillMemoryEx(*mem, memSize, "0D-0A-12345678"); fill memory with bytes $0D $0A followed by long $12345678