kervinck / gigatron-rom

System, apps and tooling for the Gigatron TTL microcomputer
BSD 2-Clause "Simplified" License
236 stars 80 forks source link

Added SYS_ScanMemory_DEVROM_50 #203

Closed lb3361 closed 3 years ago

lb3361 commented 3 years ago

Summary

This pull request adds a sys call SYS_ScanMemory that scans up to 256 bytes of memory in a single page, searching for two possible target bytes. This is useful for instance to search for the terminating zero of a c string (strlen) or to find a character in a string (strchr). I use this in the C compiler library to convert a lot of the strxxx() functions into optimized memcpy() calls (themselves using SYS_CopyMemory).

Example

For instance the function

/* Scans memory region [s,s+n) and return a pointer to the first byte 
   equal to either c0 or c1. Return zero if not found. 
   This is fast when there is a SYS call. */
extern void *_memchr2(const void *s, char c0, char c1, size_t n);

is implemented in https://github.com/lb3361/gigatron-lcc/blob/master/gigatron/libc/memchr.s, possibly using this SYS call within each page intersecting the memory block. This function is in turn used to implement strcpy(), strcat(), strncpy(), strncat(), strchr(), strrchr(), and strlen(). In short, with the optimized memcpy(), it helps having nimble C string manipulation.

Implementation

Implementation is a simple SYS call restart scheme but taking a shortcut as long as there is sufficient time in the current time slice, line 5623, similar to LSLN in fact. The current code processes one byte every 30 cycles (5 us). One could go faster at the expense of more code, but this is already 10 times faster than the equivalent loop in vCPU code.

Testing

The GLCC test program for string operations returns identical outputs when using this SYS call or when using the original vCPU implementation. No timing errors were reported by gtsim or gtemuat67.

at67 commented 3 years ago

Looks good, is compatible with ROMvX0 as well.