SYS_CopyMemory and SYS_CopyMemoryExt
Posted: 30 May 2021, 04:38
I wrote two useful native routines inspired by SYS_SetMemory_v2_54.
SYS_CopyMemory copies a block of memory from one address to another. The main caveat is that you cannot cross page boundaries, which means that the size of the block must be less than 0x100-lo(srcAddr) and 0x100-lo(dstAddr). It can read and write 12 bytes per scanline in two bursts of 6 bytes. For comparison SYS_SetMemory writes 24 bytes per scanline in three bursts of 8 bytes. The implementation has a neat trick. Instead of restarting the syscall in the usual way, it checks that there is enough time left, patch vTicks, and starts another burst of 6 bytes. That saves a dozen cycles per burst. When it cannot burst 6 bytes, it tries to burst 3, then 1.
SYS_CopyMemoryExt only works when a RAM expansion is detected. It copies a block of memory in a manner similar to SYS_CopyMemory but writes it into another bank. It does this by reading a burst, using ctrl() to switch bank, writing the burst, then using ctrl() again to restore the original bank. To make both extensions fit in a single page, I cut the 3 bytes burst for this one.
Question: can I send a pull request? I am quite eager to have this in devrom because copying across memory banks is something painful to do without using an intermediate buffer in the first 32KB of memory which are already very busy. In addition, having such a native routine allows us to load a GT1 into the memory of a 32KB or 64KB gigatron without having to also find a spot for the loader. The loader can hide in another bank and write into banks 0 and 1 with this call.
I took the SYS spots previously used by the unfinished SYS_LoadBytes and SYS_StoreBytes. This can be changed.
You can check the code at https://github.com/lb3361/gigatron-rom/ ... fbbf1798eb.
I also have two vcpu routines, named memcpy(...) and _memcpyext(...), that split a copy into pieces that don't cross page boundaries. This is what is used by my testing code which can be found at https://github.com/lb3361/gigatron-lcc/ ... emcpyext.c. Screenshot of the test in progress below. Yes this is a working c compiler
SYS_CopyMemory copies a block of memory from one address to another. The main caveat is that you cannot cross page boundaries, which means that the size of the block must be less than 0x100-lo(srcAddr) and 0x100-lo(dstAddr). It can read and write 12 bytes per scanline in two bursts of 6 bytes. For comparison SYS_SetMemory writes 24 bytes per scanline in three bursts of 8 bytes. The implementation has a neat trick. Instead of restarting the syscall in the usual way, it checks that there is enough time left, patch vTicks, and starts another burst of 6 bytes. That saves a dozen cycles per burst. When it cannot burst 6 bytes, it tries to burst 3, then 1.
Code: Select all
#-----------------------------------------------------------------------
# Extension SYS_CopyMemory_DEVROM_80
#-----------------------------------------------------------------------
# SYS function for copying 1..256 bytes
#
# sysArgs[0:1] Destination address
# sysArgs[2:3] Source address
# vAC[0] Count (0 means 256)
#
# Doesn't cross page boundaries
# Overwrites sysArgs[4:7] and vLR
SYS_CopyMemoryExt only works when a RAM expansion is detected. It copies a block of memory in a manner similar to SYS_CopyMemory but writes it into another bank. It does this by reading a burst, using ctrl() to switch bank, writing the burst, then using ctrl() again to restore the original bank. To make both extensions fit in a single page, I cut the 3 bytes burst for this one.
Code: Select all
#-----------------------------------------------------------------------
# Extension SYS_CopyMemoryExt_DEVROM_94
#-----------------------------------------------------------------------
# SYS function for copying 1..256 bytes to a different bank
#
# sysArgs[0:1] Destination address
# sysArgs[2:3] Source address
# vAC[0] Count (0 means 256)
# vAC[1] Bits 7 and 6 contain the bank number
#
# Doesn't cross page boundaries.
# Overwrites sysArgs[4:7], vLR, and vTmp.
# Returns -1 in vAC if no expansion card is present.
I took the SYS spots previously used by the unfinished SYS_LoadBytes and SYS_StoreBytes. This can be changed.
You can check the code at https://github.com/lb3361/gigatron-rom/ ... fbbf1798eb.
I also have two vcpu routines, named memcpy(...) and _memcpyext(...), that split a copy into pieces that don't cross page boundaries. This is what is used by my testing code which can be found at https://github.com/lb3361/gigatron-lcc/ ... emcpyext.c. Screenshot of the test in progress below. Yes this is a working c compiler