wip
[virtual-nascom.git] / nascom.c
blobf3346f4d6f58ce9860dc48f79f363b325bd8c546
1 /* VirtualNascom, a Nascom II emulator.
3 Copyright (C) 2000 Tommy Thorn
4 Copyright (C) 1995,1998 Frank D. Cringle.
6 NasEmu is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 A Nascom consists of:
24 - a Z80 CPU,
25 - an UART,
26 - a bitmapped keyboard,
27 - memory:
28 0000 - 07ff 2 KB ROM monitor,
29 0800 - 0bff 1 KB screen memory,
30 0c00 - 0fff 1 KB workspace
31 1000 - dfff memory
32 e000 - ffff 8 KB of MS Basic
34 With the Z80 emulator in place the first thing to get working is the
35 screen memory. The "correct" way to simulate screen memory is to
36 trap upon writes, but that would be slow. We do it any just to get
37 started.
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <getopt.h>
45 #include <ctype.h>
46 #include "simz80.h"
47 #include "nascom.h"
50 unsigned char keym[9] = {
51 0, /* ? ? ? Shift ? ? ? ? */
52 0, /* ?!TXF5BH ! = Up*/
53 0, /* ?!YZD6NJ ! = Left*/
54 0, /* ?!USE7MK ! = Down */
55 0, /* ?!IAW8,L ! = Right */
56 0, /* ??OQ39.; */
57 0, /* ?[P120/: */
58 0, /* ?]R C4VG */
59 0 /* ? ? CR - Newline BS */
62 unsigned char keyp = 0;
63 unsigned char port0;
65 static void
66 usage(void)
68 fprintf(stderr,
69 "Usage: %s {flags} {commands}\n"
70 " -m <file> use <file> as monitor (default is nasysy3.nal)\n"
71 " -v verbose\n"
72 ,progname);
73 exit (1);
76 void load_nascom(const char *file)
78 FILE *f = fopen(file, "r");
79 int a, b1, b2, b3, b4, b5, b6, b7, b8;
80 int count = 0;
81 int ch;
83 if (!f) {
84 perror(file);
85 exit(1);
88 if (vflag)
89 printf("Loading %s", file);
91 for (; !feof(f) ;) {
92 if (fscanf(f, "%x %x %x %x %x %x %x %x %x",
93 &a, &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8) == 9) {
94 RAM(a) = b1;
95 RAM(a+1) = b2;
96 RAM(a+2) = b3;
97 RAM(a+3) = b4;
98 RAM(a+4) = b5;
99 RAM(a+5) = b6;
100 RAM(a+6) = b7;
101 RAM(a+7) = b8;
102 count += 8;
106 ch = fgetc(f);
107 while (ch != -1 && ch != '\n');
109 if (ch == -1)
110 break;
113 fclose(f);
114 if (vflag)
115 printf(". Successfully loaded %d bytes\n", count);
118 int main(int argc, char **argv)
120 int c;
122 setup(argc, argv);
124 monitor = "nassys3.nal";
125 progname = argv[0];
128 #ifdef MMU
129 for (c=0; c<MEMSIZE/4; ++c) pagetable[c]=ram+(c<<12);
130 #endif
132 while ((c = getopt(argc, argv, "m:v")) != EOF)
133 switch (c) {
134 case 'm':
135 monitor = optarg;
136 break;
137 case 'v':
138 vflag = 1;
139 break;
140 case '?':
141 usage();
144 if (vflag)
145 puts("VirtualNascom, a Nascom 2 emulator version " VERSION "\n"
146 "Copyright 2000 Tommy Thorn. Based on\n"
147 "Yet Another Z80 Emulator version " YAZEVERSION
148 ", Copyright 1995,1998 Frank D. Cringle.\n"
149 "NasEmu comes with ABSOLUTELY NO WARRANTY; for details\n"
150 "see the file \"COPYING\" in the distribution directory.\n");
152 load_nascom(monitor);
153 load_nascom("basic.nal");
155 for ( ; optind < argc; optind++)
156 load_nascom(argv[optind]);
158 simz80(pc, 20, NULL /*xhandleevent*/);
160 fprintf(stderr,"HALT\n\r");
161 fprintf(stderr,"PC SP IR IX IY AF BC DE HL AF' BC' DE' HL'\n\r");
162 fprintf(stderr,"%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n\r",pc,sp,ir,ix,iy,af[af_sel],regs[regs_sel].bc,regs[regs_sel].de,regs[regs_sel].hl,af[1-af_sel],regs[1-regs_sel].bc,regs[1-regs_sel].de,regs[1-regs_sel].hl);
163 exit(0);
166 void out(unsigned int port, unsigned char value)
168 unsigned int down_trans;
170 if (0) fprintf(stdout, "[%02x] <- %02x\n", port, value);
172 switch (port) {
173 case 0:
174 /* KBD */
175 down_trans = port0 & ~value;
176 port0 = value;
178 if ((1 & down_trans) && keyp < 9) keyp++;
179 if (2 & down_trans) keyp = 0;
180 break;
182 default: ;
186 int in(unsigned int port)
188 if (0) fprintf(stdout, "<- [%02x]\n", port);
190 switch (port) {
191 case 0:
192 /* KBD */
193 /* printf("[%d]", keyp); */
194 return ~keym[keyp];
195 case 2:
196 /* Status port on the UART */
197 return 0;
198 default:
199 return 0;
203 #if 0
205 #include "xvirtualnascom.h"
206 #include <X11/Intrinsic.h>
207 #include <X11/StringDefs.h>
208 #include <X11/Xos.h>
209 #include <X11/cursorfont.h>
210 #include <X11/Xutil.h>
211 #include <X11/xpm.h>
213 #define XK_MISCELLANY 1
214 #include <X11/keysymdef.h>
216 void slow_write(unsigned int a, unsigned char v)
218 if (INSCREEN(a)) {
219 unsigned int y = (a-0x800) / 64;
220 unsigned int x = (a-0x800) % 64;
221 /* fprintf(stdout, "putbyte %04x %02x '%c'\n", a, v, v); */
222 if (10 <= x && x < 58 && ' ' <= v) {
223 if (y == 15)
224 y = 0;
225 else
226 ++y;
228 xputch(x-10, y, v);
231 if (0x800 <= a && a <= 0xE000)
232 RAM(a) = v;
235 static char * kbd_translation[] = {
236 /* 0 */ "xxxxxxxx",
237 /* 1 */ "xyTXF5BH",
238 /* 2 */ "xyYZD6NJ",
239 /* 3 */ "xyUSE7MK",
240 /* 4 */ "xyIAW8,L",
241 /* 5 */ "xxOQ39.;",
242 /* 6 */ "x[P120/'",
243 /* 7 */ "x]R C4VG",
244 /* 8 */ "x\rxxx-\n\007"
247 void EventHandler(Widget w, caddr_t data, XEvent *ev)
249 KeySym keysym;
250 int i = -1, bit = 0;
252 if (ev->xany.type != KeyPress && ev->xany.type != KeyRelease)
253 return;
255 keysym = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0);
257 if ((unsigned long) keysym < 128) {
258 int ch = toupper(keysym);
259 for (i = 0; i < 9; ++i)
260 for (bit = 0; bit < 8; ++bit)
261 if (kbd_translation[i][7-bit] == ch)
262 goto found;
263 i = -1;
264 found:;
265 } else
266 switch (keysym) {
267 case XK_Shift_L:
268 case XK_Shift_R: i = 0, bit = 4; break;
269 case XK_Up: i = 1, bit = 6; break;
270 case XK_Left: i = 2, bit = 6; break;
271 case XK_Down: i = 3, bit = 6; break;
272 case XK_Right: i = 4, bit = 6; break;
273 case XK_BackSpace: i = 8, bit = 0; break;
274 case XK_Return: i = 8, bit = 1; break;
275 case XK_End: {
276 /* Undocumented hack */
277 FILE *f;
278 f = fopen("screendump", "w");
279 fwrite((const void *) (ram+0x800), 1, 1024, f);
280 fclose(f);
281 if (vflag) printf("Screen dumped\n");
282 break;
285 if (i != -1) {
286 if (ev->xany.type == KeyPress)
287 keym[i] |= 1 << bit;
288 else
289 keym[i] &= ~(1 << bit);
293 #endif