Here's a more universal approach but Adler and Fletcher 64 are only available for x64 and Adler 64 is unverified.
Code:
Procedure AFChecksum(*Buffer, BufferSize.i, Mode.i = 2)
EnableASM
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
MOV edx, *Buffer
MOV ecx, BufferSize
MOV eax, Mode
!push ebx
!push ebp
!push edi
!push esi
!and eax, 7
!shl eax, 4
!lea ebx, [aftable + eax]
!mov ebp, [ebx]
!mov edi, [ebx + 4]
!mov esi, [ebx + 8]
!mov al, [ebx + 12]
!mov [esp - 1], al
!mov ebx, edx
!afchecksum_loop:
!movzx eax, byte [ebx]
!add edi, eax
!add esi, edi
!jns afchecksum_cont
!afchecksum_mod:
!xor edx, edx
!mov eax, edi
!div ebp
!mov edi, edx
!xor edx, edx
!mov eax, esi
!div ebp
!mov esi, edx
!afchecksum_cont:
!inc ebx
!sub ecx, 1
!ja afchecksum_loop
!jnc afchecksum_mod
!mov cl, [esp - 1]
!mov eax, esi
!shl eax, cl
!or eax, edi
!pop esi
!pop edi
!pop ebp
!pop ebx
CompilerCase #PB_Processor_x64
MOV r8, *Buffer
MOV r9, BufferSize
MOV rax, Mode
!and rax, 7
!shl rax, 4
!lea r10, [aftable]
!lea r10, [r10 + rax]
!mov ecx, [r10]
!mov edx, [r10 + 4]
!mov eax, [r10 + 8]
!mov r11, rax
!mov al, [r10 + 12]
!mov [esp - 1], al
!mov r10, rdx
!afchecksum_loop:
!movzx rax, byte [r8]
!add r10, rax
!add r11, r10
!jns afchecksum_cont
!afchecksum_mod:
!xor rdx, rdx
!mov rax, r10
!div rcx
!mov r10, rdx
!xor rdx, rdx
!mov rax, r11
!div rcx
!mov r11, rdx
!afchecksum_cont:
!inc r8
!sub r9, 1
!ja afchecksum_loop
!jnc afchecksum_mod
!mov cl, [esp - 1]
!mov rax, r11
!shl rax, cl
!or rax, r10
CompilerEndSelect
ProcedureReturn
!aftable:
!dd 0xf, 0xf, 0xf, 0x4; Fletcher-8 (mode 0)
!dd 0xff, 0xff, 0xff, 0x8; Fletcher-16 (mode 1)
!dd 0xffff, 0xffff, 0xffff, 0x10; Fletcher-32 (mode 2)
!dd 0xffffffff, 0xffffffff, 0xffffffff, 0x20; Fletcher-64 (mode 3)
!dd 0xd, 0x1, 0x0, 0x4; Adler-8 (mode 4)
!dd 0xfb, 0x01, 0x00, 0x8; Adler-16 (mode 5)
!dd 0xfff1, 0x0001, 0x0000, 0x10; Adler-32 (mode 6)
!dd 0xfffffffb, 0x00000001, 0x00000000, 0x20; Adler-64 (mode 7)
DisableASM
EndProcedure
For Fletcher64 I have a separate x86 version
Code:
Procedure.q Fletcher64(*Buffer, BufferSize.i); x86
EnableASM
MOV edx, *Buffer
MOV ecx, BufferSize
!push edi
!push esi
!mov edi, -1
!mov esi, -1
!fletcher64_loop:
!movzx eax, byte [edx]
!add edi, eax
!adc edi, 0
!add esi, edi
!adc esi, 0
!inc edx
!dec ecx
!jnz fletcher64_loop
!mov edx, esi
!mov eax, edi
!add edx, 1
!adc edx, -1
!add eax, 1
!adc eax, -1
!pop esi
!pop edi
ProcedureReturn
DisableASM
EndProcedure