149 lines
4.8 KiB
Text
149 lines
4.8 KiB
Text
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
|