6502 Based Virtual Computer Copyright (C) 2011 Scott C. Duensing 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_ROM_END = 0xfff9 MM_ROM_START = 0xf000 MM_CLOCK = 0xefa5 MM_PRNG = 0xefa4 MM_KEYBOARD_META = 0xefa3 MM_KEYBOARD_CHARACTER = 0xefa2 MM_DISPLAY_COMMAND = 0xefa1 MM_DISPLAY_DATA = 0xefa0 MM_DISPLAY_ADAPTER = 0xe000 MM_HEAP_END = 0xdfff MM_CODE_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, anything located at MM_CODE_START will be executed. If you wish to relocate your code, either place a JMP at this address or in "machine.js" change the default PC value in the call to "cpu.attach()".