234 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
 | 
						|
/* Testing code for SYS_CopyMemory, SYS_CopyMemoryExt.
 | 
						|
 | 
						|
   Compile with  'glcc -map=32k -rom=exp memcpyext.c'
 | 
						|
   
 | 
						|
   -map=32k is used to allow us to swap banks and check that we wrote what we intended.
 | 
						|
   -rom=exp selects implementations of memcpy and _memcpyext that call SYS_CopyMemory
 | 
						|
            and SYS_CopyMemoryExt. These can be seen in gigatron-lcc/gigatron/libc.
 | 
						|
 | 
						|
   Then you can run the resulting gt1 inside gtemuAT67.
 | 
						|
   You need of course to load a rom that contains SYS_CopyMemory 
 | 
						|
   and SYS_CopyMemoryExt.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <gigatron/sys.h>
 | 
						|
#include <gigatron/libc.h>
 | 
						|
#include <stdarg.h>
 | 
						|
 | 
						|
 | 
						|
/* -------------------- QUICK PRINTF CODE ---------------- */
 | 
						|
 | 
						|
#define FGBG 0x3f20
 | 
						|
 | 
						|
typedef struct {
 | 
						|
	char *addr;
 | 
						|
	char x;
 | 
						|
	char y;
 | 
						|
} screenpos_t;
 | 
						|
 | 
						|
void clear_lines(int l1, int l2)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	for (i=l1; i<l2; i++) {
 | 
						|
		char *row = (char*)(videoTable[i+i]<<8);
 | 
						|
		memset(row, FGBG & 0xff, 160);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void clear_screen(screenpos_t *pos)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	for (i=0; i<120; i++) {
 | 
						|
		videoTable[i+i] = 8 + i;
 | 
						|
		videoTable[i+i+1] = 0;
 | 
						|
	}
 | 
						|
	clear_lines(0,120);
 | 
						|
	pos->x = pos->y = 0;
 | 
						|
	pos->addr = (char*)(videoTable[0]<<8);
 | 
						|
}
 | 
						|
 | 
						|
void scroll(void)
 | 
						|
{
 | 
						|
	char pages[8];
 | 
						|
	int i;
 | 
						|
	for (i=0; i<8; i++)
 | 
						|
		pages[i] = videoTable[i+i];
 | 
						|
	for (i=0; i<112; i++)
 | 
						|
		videoTable[i+i] = videoTable[i+i+16];
 | 
						|
	for (i=112; i<120; i++)
 | 
						|
		videoTable[i+i] = pages[i-112];
 | 
						|
}
 | 
						|
 | 
						|
void newline(screenpos_t *pos)
 | 
						|
{
 | 
						|
	pos->x = 0;
 | 
						|
	pos->y += 1;
 | 
						|
	if (pos->y >  14) {
 | 
						|
		scroll();
 | 
						|
		clear_lines(112,120);
 | 
						|
		pos->y = 14;
 | 
						|
	}
 | 
						|
	pos->addr = (char*)(videoTable[16*pos->y]<<8);
 | 
						|
}
 | 
						|
 | 
						|
void print_char(screenpos_t *pos, int ch)
 | 
						|
{
 | 
						|
	unsigned int fntp;
 | 
						|
	char *addr;
 | 
						|
	int i;
 | 
						|
	if (ch < 32) {
 | 
						|
		if (ch == '\n') 
 | 
						|
			newline(pos);
 | 
						|
		return;
 | 
						|
	} else if (ch < 82) {
 | 
						|
		fntp = font32up + 5 * (ch - 32);
 | 
						|
	} else if (ch < 132) {
 | 
						|
		fntp = font82up + 5 * (ch - 82);
 | 
						|
	} else {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	addr = pos->addr;
 | 
						|
	for (i=0; i<5; i++) {
 | 
						|
		SYS_VDrawBits(FGBG, SYS_Lup(fntp), addr);
 | 
						|
		addr += 1;
 | 
						|
		fntp += 1;
 | 
						|
	}
 | 
						|
	pos->x += 1;
 | 
						|
	pos->addr = addr + 1;
 | 
						|
	if (pos->x > 24)
 | 
						|
		newline(pos);
 | 
						|
}
 | 
						|
 | 
						|
screenpos_t pos;
 | 
						|
 | 
						|
void print_unsigned(unsigned int n, int radix)
 | 
						|
{
 | 
						|
	static char digit[] = "0123456789abcdef";
 | 
						|
	char buffer[8];
 | 
						|
	char *s = buffer;
 | 
						|
	do {
 | 
						|
		*s++ = digit[n % radix];
 | 
						|
		n = n / radix;
 | 
						|
	} while (n);
 | 
						|
	while (s > buffer)
 | 
						|
		print_char(&pos, *--s);
 | 
						|
}
 | 
						|
 | 
						|
void print_int(int n, int radix)
 | 
						|
{
 | 
						|
	if (n < 0) {
 | 
						|
		print_char(&pos, '-');
 | 
						|
		n = -n;
 | 
						|
	}
 | 
						|
	print_unsigned(n, radix);
 | 
						|
}
 | 
						|
 | 
						|
int myprintf(const char *fmt, ...)
 | 
						|
{
 | 
						|
	char c;
 | 
						|
	va_list ap;
 | 
						|
	va_start(ap, fmt);
 | 
						|
	while (c = *fmt++) {
 | 
						|
		if (c != '%') {
 | 
						|
			print_char(&pos, c);
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		if (c = *fmt++) {
 | 
						|
			if (c == 'd')
 | 
						|
				print_int(va_arg(ap, int), 10);
 | 
						|
			else if (c == 'u')
 | 
						|
				print_unsigned(va_arg(ap, unsigned), 10);
 | 
						|
			else if (c == 'x')
 | 
						|
				print_unsigned(va_arg(ap, unsigned), 16);
 | 
						|
			else
 | 
						|
				print_char(&pos, c);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	va_end(ap);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* -------------------- THIS IS THE TEST ---------------- */
 | 
						|
 | 
						|
char * const sbuffer = (void*)(0xe000u);
 | 
						|
char * const dbuffer = (void*)(0xe400u);
 | 
						|
 | 
						|
void setbank(int bank)
 | 
						|
{
 | 
						|
	int ctrl = ((ctrlBits_v5 ^ (bank<<6)) & 0xc0 ) ^ ctrlBits_v5;
 | 
						|
	SYS_ExpanderControl(ctrl);
 | 
						|
}
 | 
						|
 | 
						|
void test(int doff, int soff, int len, int dstbank, int srcbank)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	myprintf("[%d:%x,]<-[%d:%x,+%d]\n", dstbank, dbuffer+doff, srcbank, sbuffer+soff, len);
 | 
						|
 | 
						|
	setbank(srcbank);
 | 
						|
	for (i=0; i<1024;i++)
 | 
						|
		sbuffer[i] = (i&0x3f) | ((srcbank&3)<<6);
 | 
						|
	setbank(dstbank);
 | 
						|
	for (i=0; i<1024;i++)
 | 
						|
		dbuffer[i] = (i&0x3f) | ((dstbank&3)<<6);
 | 
						|
 | 
						|
	_memcpyext(((dstbank&3)<<6)|((srcbank&3)<<4),
 | 
						|
		   dbuffer+doff, sbuffer+soff, len);
 | 
						|
 | 
						|
	setbank(dstbank);
 | 
						|
	for (i=0; i<1024;i++)
 | 
						|
		{
 | 
						|
			int expected = (i & 0x3f) | ((dstbank&3)<<6);
 | 
						|
			if (i >= doff && i < doff + len)
 | 
						|
				expected = ( (i-doff+soff) & 0x3f ) | ((srcbank&3)<<6);
 | 
						|
			if (dbuffer[i] != expected)
 | 
						|
				myprintf(" at %d:%x: not %x, %x\n", dstbank, dbuffer+i, expected, dbuffer[i]);
 | 
						|
		}
 | 
						|
	setbank(srcbank);
 | 
						|
	for (i=0; i<1024;i++)
 | 
						|
		{
 | 
						|
			int expected = (i & 0x3f) | ((srcbank&3)<<6);
 | 
						|
			if (sbuffer[i] != expected)
 | 
						|
				myprintf(" at %d:%x: not %x, %x\n", srcbank, sbuffer+i, expected, sbuffer[i]);
 | 
						|
		}
 | 
						|
	setbank(1);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int main()
 | 
						|
{
 | 
						|
	int i,j;
 | 
						|
 | 
						|
	clear_screen(&pos);
 | 
						|
	if (ctrlBits_v5 == 0) {
 | 
						|
		myprintf("No memory expansion\n");
 | 
						|
		return 10;
 | 
						|
	}
 | 
						|
	for (j=1; j<=3; j++)
 | 
						|
		for (i=2; i<=3; i++) {
 | 
						|
			myprintf("========= bank %d to %d\n", j, i);
 | 
						|
			test(255,256,257,i,j);
 | 
						|
			test(34,0,12,i,j);
 | 
						|
			test(34,65,12,i,j);
 | 
						|
			test(84,63,255,i,j);
 | 
						|
			test(34,63,256,i,j);
 | 
						|
			test(128,256,257,i,j);
 | 
						|
			test(256,63,757,i,j);
 | 
						|
	}
 | 
						|
 | 
						|
	for(;;) {
 | 
						|
		myprintf("======== stress test\n");
 | 
						|
		_memcpyext((0xc0 | (0x00 >> 2)), (char*)0x8300u, (char*)0x8300u, 0x7d00u); // bank0->bank3
 | 
						|
		_memcpyext((0x40 | (0xc0 >> 2)), (char*)0x8300u, (char*)0x8300u, 0x7d00u); // bank3->bank1
 | 
						|
		_memcpyext((0x80 | (0x40 >> 2)), (char*)0x8300u, (char*)0x8300u, 0x7d00u); // bank1->bank2
 | 
						|
		_memcpyext((0x00 | (0x80 >> 2)), (char*)0x8300u, (char*)0x8300u, 0x7d00u); // bank2->bank0
 | 
						|
	}
 | 
						|
 | 
						|
}
 |