6502 Based Virtual Computer
Copyright (C) 2011 Scott C. Duensing <scott@jaegertech.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
---
This is a simple (and fictional) 6502-based computer written in JavaScript.
Features:
- 6502 CPU (lacks interrupt support at this time).
- 16 color, 80x25 text display.
- "Hardware" psuedo-random number generator.
- Keyboard.
- Simple clock.
Notes:
- All hardware components are in the "computer" folder.
- A sample "Hello World" is in the "software" folder.
- "machine.html" loads everything and provides a DIV for the display.
- "machine.js" glues all the components together into a computer.
Memory Map:
MM_IRQ_VECTOR = 0xfffe;
MM_RESET_VECTOR = 0xfffc;
MM_NMI_VECTOR = 0xfffa;
MM_CLOCK = 0xfff9;
MM_PRNG = 0xfff8;
MM_KEYBOARD_META = 0xfff7;
MM_KEYBOARD_CHARACTER = 0xfff6;
MM_DISPLAY_COMMAND = 0xffa1;
MM_DISPLAY_DATA = 0xffa0;
MM_DISPLAY_ADAPTER = 0xf000;
MM_HEAP_END = 0xefff;
MM_HEAP_START = 0x0200;
MM_STACK = 0x0100;
MM_ZERO_PAGE = 0x0000;
Display Adapter:
You can either jam bytes right into display memory (beginning at
MM_DISPLAY_ADAPTER) or use the simple BIOS included in the adapter. ("BOS"?
displays don't do input!)
Each character on the display is comprised of two bytes: The character to
display, and the color attributes (in that order). Colors are stored with the
foreground value in the lower nibble of the attribute byte and the background
in the high nibble. Color values are:
0 = Black
1 = Blue
2 = Green
3 = Cyan
4 = Red
5 = Magenta
6 = Brown
7 = Light Gray
8 = Gray
9 = Light Blue
10 = Light Green
11 = Light Cyan
12 = Light Red
13 = Light Magenta
14 = Yellow
15 = White
Using the BIOS provides several conveniences over writing directly to the
framebuffer, including tab stops, line wrapping, scrolling, and more. Access
to the BIOS is through two memory locations, one for data (MM_DISPLAY_DATA)
and one for issuing commands to operate on that data (MM_DISPLAY_COMMAND).
Available commands are:
0 = Store Data LSB (data byte stored for later)
1 = Clear Display to Current Color (no data byte needed)
2 = Set Cursor X (position 0-79 stored in data byte)
3 = Set Cursor Y (position 0-24 stored in data byte)
4 = Get Cursor X (position returned in data byte)
5 = Get Cursor Y (position returned in data byte)
6 = Set Color (same format as above, store in data byte)
7 = Draw Character in Current Color (character code in data byte)
8 = Draw String in Current Color (see below)
For drawing strings, first write the LSB of the address of the string in
memory to MM_DISPLAY_DATA and then write a 0 to MM_DISPLAY_COMMAND to store
the LSB. Then write the MSB to MM_DISPLAY_DATA and 8 to MM_DISPLAY_COMMAND to
draw the string. Since no length information is provided, strings must be
zero terminated.
Keyboard:
The current status of the keyboard can be read from two bytes,
MM_KEYBOARD_CHARACTER and MM_KEYBOARD_META. MM_KEYBOARD_CHARACTER always
contains the value of the most recently pressed key. MM_KEYBOARD_META
contains the current state of the keyboard's Shift, Control, and Alt keys
in the following bits:
0 = Shift
1 = Control
2 = Alt
If you wish to wait for a keypress, write a 0 to MM_KEYBOARD_CHARACTER and
then poll until the value changes.
Random Number Generator:
To make it easy to get a random number for use in your code, a psuedo-random
number generator is provided. Simply read from MM_PRNG for a random value
between 0 and 255, inclusive.
Clock:
The value at MM_CLOCK increments every 100 milliseconds. It is intended for
simple timing operations and not actual "wall clock" time keeping.
Code Start:
By default, when the CPU starts, it begins executing the code pointed to
by the reset vector. This address must be filled in before calling cpu.reset.
---
NOTES:
Abstraction with util.js is poor. Same with memory map.
Video display sucks.
- Needs real graphics.
- Needs to parse special symbols in strings to clear screen, set colors, move cursor, bell, etc.
Save / Load machine snapshots.
Sound.
Networking?
128k?
640x400