// File: rellla[P]E3DC-Rscp/RscpProtocol.cpp
// Function: RscpProtocol::createFrameAsBuffer(SRscpFrameBuffer*, unsigned char const*, unsigned short, bool)
int32_t RscpProtocol::createFrameAsBuffer(SRscpFrameBuffer* frameBuffer, const uint8_t * data, uint16_t dataLength, bool calcCRC) {
	if(frameBuffer == NULL) {
		return RSCP::ERR_INVALID_INPUT;
	}
	// calculate the required frame size
	size_t sFrameSize =  sizeof(SRscpFrameHeader);
	// allocate the required memory
	frameBuffer->data = (uint8_t *) malloc(sFrameSize + dataLength + (calcCRC ? 4 : 0));
	if(frameBuffer->data == NULL) {
		return RSCP::ERR_NO_MEMORY;
	}
	// set the memory size
	frameBuffer->dataLength = sFrameSize + dataLength + (calcCRC ? 4 : 0);
	// set initial header values
	memset(frameBuffer->data, 0, sizeof(SRscpFrameHeader));
	SRscpFrame* tmpFrame = reinterpret_cast<SRscpFrame*>(frameBuffer->data);
	tmpFrame->header.magic = RSCP::MAGIC;
	tmpFrame->header.ctrl.bits.crc = calcCRC;
	tmpFrame->header.ctrl.bits.version = RSCP::VERSION;
	tmpFrame->header.dataLength = dataLength;
	setHeaderTimestamp(tmpFrame);

	// insert data from the SRscpValues
	memcpy(&tmpFrame->header + 1, data, dataLength);

	// calculate CRC if necessary and add to the frame
	if(calcCRC) {
		uint32_t uCRC32 = calculateCRC32(frameBuffer->data, frameBuffer->dataLength - sizeof(uint32_t));
		memcpy(&frameBuffer->data[frameBuffer->dataLength - sizeof(uCRC32)], &uCRC32, sizeof(uCRC32));
	}

	return RSCP::OK;
}

// Assembly:
subq $0x48, %rsp
movb %r8b, %al
movq %rdi, 0x38(%rsp)
movq %rsi, 0x30(%rsp)
movq %rdx, 0x28(%rsp)
movw %cx, 0x26(%rsp)
andb $0x1, %al
movb %al, 0x25(%rsp)
movq 0x38(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, 0x30(%rsp)
jne 0x7acf
movl $0xffffffff, 0x44(%rsp) # imm = 0xFFFFFFFF
jmp 0x7c43
movq $0x12, 0x18(%rsp)
movq 0x18(%rsp), %rdi
movzwl 0x26(%rsp), %eax
addq %rax, %rdi
movb 0x25(%rsp), %dl
xorl %eax, %eax
movl $0x4, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
cltq
addq %rax, %rdi
callq 0x21d0
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, (%rax)
movq 0x30(%rsp), %rax
cmpq $0x0, (%rax)
jne 0x7b23
movl $0xfffffffe, 0x44(%rsp) # imm = 0xFFFFFFFE
jmp 0x7c43
movq 0x18(%rsp), %rax
movzwl 0x26(%rsp), %ecx
addq %rcx, %rax
movb 0x25(%rsp), %sil
xorl %ecx, %ecx
movl $0x4, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movl %eax, %ecx
movq 0x30(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x30(%rsp), %rax
movq (%rax), %rdi
xorl %esi, %esi
movl $0x12, %edx
callq 0x20e0
movq (%rsp), %rdi
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movw $0xdce3, (%rax)         # imm = 0xDCE3
movb 0x25(%rsp), %cl
andb $0x1, %cl
movq 0x10(%rsp), %rax
movzbl %cl, %ecx
movw %cx, %dx
movw 0x2(%rax), %cx
andw $0x1, %dx
shlw $0xc, %dx
andw $0xefff, %cx            # imm = 0xEFFF
orw %dx, %cx
movw %cx, 0x2(%rax)
movq 0x10(%rsp), %rax
movw 0x2(%rax), %cx
andw $0xf0ff, %cx            # imm = 0xF0FF
orw $0x100, %cx             # imm = 0x100
movw %cx, 0x2(%rax)
movw 0x26(%rsp), %cx
movq 0x10(%rsp), %rax
movw %cx, 0x10(%rax)
movq 0x10(%rsp), %rsi
callq 0x78a0
movq 0x10(%rsp), %rdi
addq $0x12, %rdi
movq 0x28(%rsp), %rsi
movzwl 0x26(%rsp), %eax
movl %eax, %edx
callq 0x2130
testb $0x1, 0x25(%rsp)
je 0x7c3b
movq (%rsp), %rdi
movq 0x30(%rsp), %rax
movq (%rax), %rsi
movq 0x30(%rsp), %rax
movl 0x8(%rax), %eax
subq $0x4, %rax
movzwl %ax, %edx
callq 0x7910
movl %eax, 0xc(%rsp)
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq 0x30(%rsp), %rcx
movl 0x8(%rcx), %ecx
subq $0x4, %rcx
movl 0xc(%rsp), %edx
movl %edx, (%rax,%rcx)
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
addq $0x48, %rsp
retq
nopl (%rax)