ftp.nice.ch/pub/next/tools/emulators/a2.N.bs.tar.gz#/a2/screen.c

This is screen.c in view mode; [Download] [Up]

/*
 *  a2, an Apple II emulator in C
 *  (c) Copyright 1990 by Rich Skrenta
 *
 *  Command line interface written by Tom Markson
 *
 *  Distribution agreement:
 *
 *	You may freely copy or redistribute this software, so long
 *	as there is no profit made from its use, sale, trade or
 *	reproduction.  You may not change this copyright notice,
 *	and it must be included prominently in any copy made.
 *
 *  Send emulator related mail to:  skrenta@blekko.commodore.com
 *				    skrenta@blekko.uucp
 */



#include	<stdio.h>
#include	"a2.h"


extern char screen_map[];		/* at the bottom of this file */
extern int text1[];


int line1[0x400];
int col1[0x400];


info(s)
char *s;
{

	MoveCursor(0, 57);
	printf("%-20s", s);

	last_line = -1;
	last_col = -1;
	fflush(stdout);
}


screen_setup() {
extern int set_text1f();
int line, col;
int addr, base;
int i;

	for (i = 0; i < 0x400; i++) {
		line1[i] = -1;
		col1[i] = -1;
	}

	mem_set[0x04] = set_text1f;
	mem_set[0x05] = set_text1f;
	mem_set[0x06] = set_text1f;
	mem_set[0x07] = set_text1f;

	for (line = 0; line < 24; line++) {
		base = text1[line];
		for (col = 0; col < 40; col++) {
			addr = base + col;
			mem[addr] = 0xA0;
			line1[addr - 0x400] = line;
			col1[addr - 0x400] = col;
		}
	}
}


int last_line = -1;
int last_col = -1;


#define appleout(n)	if (n >= 0x80) putchar(screen_map[n]); else { StartInverse(); putchar(screen_map[n]); EndInverse(); }


set_text1f(addr, n)
unsigned short addr;
unsigned char n;
{
int line, col;
unsigned char c;

	if (mem[addr] == n)		/* no change, don't do anything */
		return;

	mem[addr] = n;
	line = line1[addr - 0x400];
	col = col1[addr - 0x400];

	if (line == -1)
		return;

/*
 *  Stuff to try to make updating more efficient
 *  Is it really worth it?
 */

	if (line == last_line) {
		if (col == 0)
			putchar('\r');
		else switch (col - last_col) {
		case 4:
			c = mem[addr - 3]; appleout(c);
			c = mem[addr - 2]; appleout(c);
			c = mem[addr - 1]; appleout(c);
			break;
		case 3:
			c = mem[addr - 2]; appleout(c);
			c = mem[addr - 1]; appleout(c);
			break;
		case 2:
			c = mem[addr - 1]; appleout(c);
			break;
		case 1:			/* already there */
			break;
		case 0:
			putchar('\b');
			break;
		case -1:
			putchar('\b'); putchar('\b');
			break;
		case -2:
			putchar('\b'); putchar('\b'); putchar('\b');
			break;
		case -3:
			putchar('\b'); putchar('\b'); putchar('\b');
			putchar('\b');
			break;
		default:
			MoveCursor(line, col);
		}
	} else
		MoveCursor(line, col);

	appleout(n);
	fflush(stdout);

	last_line = line;
	last_col = col;
}


set_text1(addr, n)
unsigned short addr;
unsigned char n;
{
int line, col;
unsigned char c;

	if (mem[addr] == n)		/* no change, don't do anything */
		return;

	mem[addr] = n;
	line = line1[addr - 0x400];
	col = col1[addr - 0x400];

	if (line == -1)
		return;

/*
 *  Stuff to try to make updating more efficient
 *  Is it really worth it?
 */

	if (line == last_line) {
		if (col == 0)
			putchar('\r');
		else switch (col - last_col) {
		case 4:
			c = mem[addr - 3]; appleout(c);
			c = mem[addr - 2]; appleout(c);
			c = mem[addr - 1]; appleout(c);
			break;
		case 3:
			c = mem[addr - 2]; appleout(c);
			c = mem[addr - 1]; appleout(c);
			break;
		case 2:
			c = mem[addr - 1]; appleout(c);
			break;
		case 1:			/* already there */
			break;
		case 0:
			putchar('\b');
			break;
		case -1:
			putchar('\b'); putchar('\b');
			break;
		case -2:
			putchar('\b'); putchar('\b'); putchar('\b');
			break;
		case -3:
			putchar('\b'); putchar('\b'); putchar('\b');
			putchar('\b');
			break;
		default:
			MoveCursor(line, col);
		}
	} else
		MoveCursor(line, col);

	appleout(n);

	last_line = line;
	last_col = col;
}


redraw_screen() {
int i, j;
unsigned short base;
unsigned char c;

	ClearScreen();
	for (i = 0; i < 24; i++) {
		base = text1[i];
		for (j = 0; j < 40; j++) {
			c = mem[base + j];
			appleout(c);
		}
		if (i < 23)
			putchar('\n');
	}

	last_line = -1;
	last_col = -1;

	fflush(stdout);
}


/*
 *  Screen display mapping table
 */

char screen_map[] = {

	'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',		/* $00	*/
	'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',		/* $08	*/
	'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',		/* $10	*/
	'X', 'Y', 'Z', '[', '\\',']', '^', '_',		/* $18	*/
	' ', '!', '"', '#', '$', '%', '&', '\'',	/* $20	*/
	'(', ')', '*', '+', ',', '-', '.', '/',		/* $28	*/
	'0', '1', '2', '3', '4', '5', '6', '7',		/* $30	*/
	'8', '9', ':', ';', '<', '=', '>', '?',		/* $38	*/

	'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',		/* $40	*/
	'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',		/* $48	*/
	'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',		/* $50	*/
	'X', 'Y', 'Z', '[', '\\',']', '^', '_',		/* $58	*/
	' ', '!', '"', '#', '$', '%', '&', '\'',	/* $60	*/
	'(', ')', '*', '+', ',', '-', '.', '/',		/* $68	*/
	'0', '1', '2', '3', '4', '5', '6', '7',		/* $70	*/
	'8', '9', ':', ';', '<', '=', '>', '?',		/* $78	*/

	'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',		/* $80	*/
	'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',		/* $88	*/
	'p', 'q', 'r', 's', 't', 'u', 'v', 'w',		/* $90	*/
	'x', 'y', 'z', '[', '\\',']', '^', '_',		/* $98	*/
	' ', '!', '"', '#', '$', '%', '&', '\'',	/* $A0	*/
	'(', ')', '*', '+', ',', '-', '.', '/',		/* $A8	*/
	'0', '1', '2', '3', '4', '5', '6', '7',		/* $B0	*/
	'8', '9', ':', ';', '<', '=', '>', '?',		/* $B8	*/

	'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',		/* $C0	*/
	'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',		/* $C8	*/
	'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',		/* $D0	*/
	'X', 'Y', 'Z', '[', '\\',']', '^', '_',		/* $D8	*/
	' ', '!', '"', '#', '$', '%', '&', '\'',	/* $E0	*/
	'(', ')', '*', '+', ',', '-', '.', '/',		/* $E8	*/
	'0', '1', '2', '3', '4', '5', '6', '7',		/* $F0	*/
	'8', '9', ':', ';', '<', '=', '>', '?',		/* $F8	*/

};

int text1[] = {
	0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
	0x428, 0x4A8, 0x528, 0x5A8, 0x628, 0x6A8, 0x728, 0x7A8,
	0x450, 0x4D0, 0x550, 0x5D0, 0x650, 0x6D0, 0x750, 0x7D0,
	0x478, 0x4F8, 0x578, 0x5F8, 0x678, 0x6F8, 0x778, 0x7F8
};

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.