2016-03-15 05:09:40 +00:00
|
|
|
|
2016-08-10 03:39:52 +00:00
|
|
|
Project: MKBasic (a.k.a. VM6502, a.k.a. VM65, I just can't decide
|
|
|
|
how to name it :-)).
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
Author: Copyright (C) Marek Karcz 2016. All rights reserved.
|
|
|
|
Free for personal and non-commercial use.
|
|
|
|
Code can be distributed and included in derivative work under
|
|
|
|
condition that the original copyright notice is preserved.
|
|
|
|
For use in commercial product, please contact me to obtain
|
|
|
|
permission and discuss possible fees, at: makarcz@yahoo.com
|
|
|
|
This software is provided with no warranty.
|
|
|
|
|
|
|
|
Purpose:
|
|
|
|
|
|
|
|
MOS 6502 emulator, Virtual CPU/Machine and potentially retro-style 8-bit
|
|
|
|
computer emulator.
|
|
|
|
MOS-6502-compatible virtual computer featuring BASIC interpreter, machine code
|
|
|
|
monitor, input/output device emulation etc.
|
2016-08-10 03:39:52 +00:00
|
|
|
Main UI of the program works in DOS/shell console.
|
|
|
|
Graphics display emulation requires SDL2.
|
2019-01-05 04:36:40 +00:00
|
|
|
The best way is to download source code of SDL2 and build it.
|
|
|
|
Makefile-s are included to build under Windows 32/64 (mingw compiler required)
|
|
|
|
and under Linux Ubuntu or Ubuntu based distro (GNU make).
|
2016-08-10 03:39:52 +00:00
|
|
|
SDL2 library must be on your execution path in order to run program.
|
2016-09-08 02:52:01 +00:00
|
|
|
E.g.:
|
|
|
|
set PATH=C:\src\SDL\lib\x64;%PATH%
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
To build under Windows 32/64:
|
|
|
|
|
|
|
|
* Install MINGW64 under C:\mingw-w64\x86_64-5.3.0 folder.
|
|
|
|
* Run mingw terminal.
|
2019-01-05 04:36:40 +00:00
|
|
|
* Build SDL2 library.
|
2016-03-15 05:09:40 +00:00
|
|
|
* Change current directory to that of this project.
|
2016-09-08 02:52:01 +00:00
|
|
|
* Set environment variable SDLDIR. (E.g.: set SDLDIR=C:\src\SDL)
|
2016-03-15 05:09:40 +00:00
|
|
|
* Run: makeming.bat
|
|
|
|
|
|
|
|
To build under Linux:
|
|
|
|
|
|
|
|
* Make sure C++11 compliant version of GCC compiler is installed.
|
2019-01-05 04:36:40 +00:00
|
|
|
NOTE: Under older distros, e.g.: Ubuntu Server 12.04, the newest c++
|
|
|
|
compiler installed may not be modern enough. Follow instructions
|
|
|
|
for your distro to install compatible c++ compiler.
|
|
|
|
E.g.:
|
|
|
|
https://gist.github.com/application2000/73fd6f4bf1be6600a2cf9f56315a2d91
|
|
|
|
* Build SDL2 library (make, make install) or download C/C++ headers and
|
|
|
|
install SDL2 from binary installation package.
|
2016-03-15 05:09:40 +00:00
|
|
|
* Change current directory to that of this project.
|
2019-01-05 04:36:40 +00:00
|
|
|
* Set environment variable SDLDIR. Your C/C++ headers for SDL2 should exist
|
|
|
|
in $SDLDIR/include folder.
|
2016-03-15 05:09:40 +00:00
|
|
|
* Run: make clean all
|
2019-01-05 04:36:40 +00:00
|
|
|
NOTE: To run the emulator under Linux, it may be necessary to set env.
|
|
|
|
variable LD_LIBRARY_PATH, e.g.:
|
|
|
|
export LD_LIBRARY_PATH=/usr/local/lib
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
Program passed following tests:
|
|
|
|
|
|
|
|
* 6502 functional test by Klaus Dormann
|
|
|
|
* AllSuiteA.asm from project hmc-6502
|
|
|
|
|
|
|
|
1. Credits/attributions:
|
|
|
|
|
|
|
|
Parts of this project is based on or contains 3-rd party work:
|
|
|
|
|
|
|
|
- Tiny Basic.
|
|
|
|
- Enhanced Basic by Lee Davison.
|
|
|
|
- Microchess by Peter Jennings (http://www.benlo.com/microchess/index.html).
|
|
|
|
- 6502 functional test by Klaus Dormann.
|
|
|
|
- All Suite test from project hmc-6502.
|
|
|
|
|
|
|
|
2. Format of the memory image definition file.
|
|
|
|
|
2016-04-18 02:54:35 +00:00
|
|
|
Emulator recognizes 4 formats of memory image:
|
|
|
|
|
|
|
|
- raw binary, no header, up to 64 kB of raw data,
|
|
|
|
- binary image with a configuration/snapshot header,
|
|
|
|
- Intel HEX format,
|
|
|
|
- plain text memory image definition file.
|
|
|
|
|
|
|
|
Please see detailed description of each format below:
|
|
|
|
|
2018-09-06 23:11:54 +00:00
|
|
|
Program can load raw binary image of data and MOS 6502 opcodes.
|
2016-03-15 05:09:40 +00:00
|
|
|
Binary image is always loaded from address $0000 and can be up to 64 kB long,
|
2016-04-18 02:54:35 +00:00
|
|
|
so the code must be properly located inside that image. Image can be shorter
|
|
|
|
than 64 kB, user will receive warning in such case, but it will be loaded.
|
|
|
|
Binary image may have header attached at the top.
|
2016-08-10 03:39:52 +00:00
|
|
|
Older version of header consists of magic keyword 'SNAPSHOT' followed by 15
|
|
|
|
bytes of data - this format had no space for expansion and will be removed
|
|
|
|
in future version. All new snapshots are saved in newest format.
|
|
|
|
Current version of header consists of magic keyword 'SNAPSHOT2' followed by
|
|
|
|
128 bytes of data. Not all of the 128 bytes are used, so there is a space
|
|
|
|
for expansion without the need of changing the file format.
|
2016-04-18 02:54:35 +00:00
|
|
|
The header data saves the status of CPU and emulation facilities like
|
|
|
|
character I/O address and enable flag, ROM boundaries and enable flag etc.
|
|
|
|
This header is added when user saves snapshot of the VM from debug console
|
|
|
|
menu with command: Y [file_name].
|
2016-08-10 03:39:52 +00:00
|
|
|
Below is the full detailed description of the header format:
|
|
|
|
|
|
|
|
* MAGIC_KEYWORD
|
|
|
|
* aabbccddefghijklmm[remaining unused bytes]
|
|
|
|
*
|
|
|
|
* Where:
|
|
|
|
* MAGIC_KEYWORD - text string indicating header, may vary between
|
|
|
|
* versions thus rendering headers from previous
|
|
|
|
* versions incompatible - currently: "SNAPSHOT2"
|
|
|
|
*
|
|
|
|
* Data:
|
|
|
|
*
|
|
|
|
* aa - low and hi bytes of execute address (PC)
|
|
|
|
* bb - low and hi bytes of char IO address
|
|
|
|
* cc - low and hi bytes of ROM begin address
|
|
|
|
* dd - low and hi bytes of ROM end address
|
|
|
|
* e - 0 if char IO is disabled, 1 if enabled
|
|
|
|
* f - 0 if ROM is disabled, 1 if enabled
|
|
|
|
* g - value in CPU Acc (accumulator) register
|
|
|
|
* h - value in CPU X (X index) register
|
|
|
|
* i - value in CPU Y (Y index) register
|
|
|
|
* j - value in CPU PS (processor status/flags)
|
|
|
|
* k - value in CPU SP (stack pointer) register
|
|
|
|
* l - 0 if generic graphics display device is disabled,
|
|
|
|
* 1 if graphics display is enabled
|
|
|
|
* mm - low and hi bytes of graphics display base address
|
|
|
|
* [remaining unused bytes are filled with 0-s]
|
|
|
|
|
2016-04-18 02:54:35 +00:00
|
|
|
Header is not mandatory, so the binary image created outside application can
|
|
|
|
also be used. User will receive warning at startup during image load if
|
|
|
|
header is missing, but image will be loaded. In this case, user may need
|
|
|
|
to configure necessary emulation facilities manually in debug console
|
|
|
|
before executing native 6502 code.
|
|
|
|
When binary image with a header is loaded, user can continue executing the
|
|
|
|
program from the place where it was saved by executing command from debug
|
|
|
|
console of the emulator:
|
|
|
|
X pc_value
|
|
|
|
Where:
|
|
|
|
pc_value - the address currently showing in CPU's PC register.
|
|
|
|
If the reset vector is set right, execute the 6502 code right from command
|
|
|
|
line:
|
2018-09-06 23:11:54 +00:00
|
|
|
vm65 -r image_name
|
2016-04-18 02:54:35 +00:00
|
|
|
Above will execute the code set in reset vector without having to start it
|
|
|
|
from debug console. If 6502 code requires character I/O and/or ROM facilities
|
|
|
|
then image should include header with proper setup.
|
2016-03-15 05:09:40 +00:00
|
|
|
Depending on your favorite 6502 assembler, you may need to use proper command
|
|
|
|
line arguments or configuration to achieve properly formatted binary file.
|
|
|
|
E.g.: if using CL65 from CC65 package, create configuration file that defines
|
|
|
|
memory segments that your 6502 code uses, then all of the segments (except the
|
|
|
|
last one) must have attribute 'fill' set to 'yes' so the unsused areas are
|
|
|
|
filled with 0-s.
|
|
|
|
Two CFG files, one for microchess and one for All Suite from hmc-6502 project
|
|
|
|
are supplied with this project and assembler source code adapted to be
|
|
|
|
compiled with CL65.
|
|
|
|
Other assemblers may need a different approach or may not be able to generate
|
2016-04-18 02:54:35 +00:00
|
|
|
binary images in format required for this emulator. In such case you may need
|
|
|
|
to design your own custom conversion tools to generate such images.
|
|
|
|
|
|
|
|
NOTE:
|
|
|
|
Simple conversion utility is supplied with this project (bin2hex), which is
|
|
|
|
described later in this file.
|
|
|
|
|
|
|
|
Emulator recognizes Intel HEX format file. It recognizes properly data
|
|
|
|
records and end-of-file record only at this time. Similar to binary image
|
|
|
|
with no header, when Intel HEX file is loaded, user may need to configure
|
|
|
|
necessary emulation facilities manually in debug console before executing
|
|
|
|
native 6502 code.
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
Program can also load memory image definition file (plain text), which is
|
|
|
|
a format developed especially for this project.
|
|
|
|
|
|
|
|
The format of the plain text memory image definition file is described below:
|
|
|
|
|
|
|
|
; comments
|
|
|
|
ADDR
|
|
|
|
address
|
|
|
|
data
|
|
|
|
ORG
|
|
|
|
address
|
|
|
|
data
|
|
|
|
IOADDR
|
|
|
|
address
|
|
|
|
ROMBEGIN
|
|
|
|
address
|
|
|
|
ROMEND
|
|
|
|
address
|
|
|
|
ENROM
|
|
|
|
ENIO
|
|
|
|
EXEC
|
|
|
|
address
|
2016-08-10 03:39:52 +00:00
|
|
|
ENGRAPH
|
|
|
|
GRAPHADDR
|
|
|
|
address
|
2016-04-18 02:54:35 +00:00
|
|
|
RESET
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
Where:
|
2016-04-18 02:54:35 +00:00
|
|
|
ADDR - label indicating that starting and run address will follow in
|
2016-08-10 03:39:52 +00:00
|
|
|
the next line
|
2016-04-18 02:54:35 +00:00
|
|
|
ORG - label indicating that the address counter will change to the
|
2016-08-10 03:39:52 +00:00
|
|
|
value provided in next line
|
2016-03-15 05:09:40 +00:00
|
|
|
IOADDR - label indicating that character I/O emulation trap address will
|
2016-08-10 03:39:52 +00:00
|
|
|
follow in the next line
|
2016-04-18 02:54:35 +00:00
|
|
|
ROMBEGIN - label indicating that the emulated read-only memory start
|
2016-08-10 03:39:52 +00:00
|
|
|
address will follow in the next line
|
2016-03-15 05:09:40 +00:00
|
|
|
ROMEND - label indicating that the emulated read-only memory end address
|
2016-08-10 03:39:52 +00:00
|
|
|
will follow in the next line
|
2016-04-18 02:54:35 +00:00
|
|
|
ENROM - enable read-only memory emulation
|
|
|
|
ENIO - enable character I/O emulation
|
|
|
|
EXEC - label indicating that the auto-execute address will follow
|
2016-08-10 03:39:52 +00:00
|
|
|
in the next line, 6502 program will auto-execute from that
|
|
|
|
address after memory definition file is done loading
|
|
|
|
ENGRAPH - enable generic graphics display device emulation with default
|
|
|
|
base address
|
|
|
|
GRAPHADDR - label indicating that base address for generic graphics display
|
|
|
|
device will follow in next line, also enables generic graphics
|
|
|
|
device emulation, but with the customized base address
|
2016-04-18 02:54:35 +00:00
|
|
|
RESET - initiate CPU reset sequence after loading memory definition file
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
address - decimal or hexadecimal (prefix $) address in memory
|
|
|
|
|
|
|
|
E.g:
|
|
|
|
ADDR
|
|
|
|
$0200
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
ADDR
|
|
|
|
512
|
|
|
|
|
|
|
|
changes the default start address (256) to 512.
|
|
|
|
|
|
|
|
ORG
|
|
|
|
49152
|
|
|
|
|
|
|
|
moves address counter to address 49152, following data will be
|
|
|
|
loaded from that address forward
|
|
|
|
|
|
|
|
data - the multi-line stream of decimal of hexadecimal ($xx) values
|
|
|
|
of size unsigned char (byte: 0-255) separated with spaces
|
|
|
|
or commas.
|
|
|
|
|
|
|
|
E.g.:
|
|
|
|
$00 $00 $00 $00
|
|
|
|
$00 $00 $00 $00
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
$00,$00,$00,$00
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
0 0 0 0
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
0,0,0,0
|
|
|
|
0 0 0 0
|
|
|
|
|
|
|
|
Each described above element of the memory image definition file is optional.
|
|
|
|
|
|
|
|
3. Character I/O emulation.
|
|
|
|
|
|
|
|
Emulator has ability to simulate a 80x25 text output display device and
|
|
|
|
rudimentary character I/O functions. The emulation is implemented by the means
|
|
|
|
of trapping memory locations defined to be designated I/O emulation addresses.
|
|
|
|
The default memory location is $E000 and also by default, the character I/O
|
|
|
|
is disabled. It can be enabled from the debug console with 'I' command:
|
|
|
|
|
|
|
|
I hexaddr
|
|
|
|
|
|
|
|
E.g.:
|
|
|
|
|
|
|
|
I E000
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
I FE00
|
|
|
|
|
|
|
|
or by putting optional statements in the memory image dedinition file:
|
|
|
|
|
|
|
|
ENIO
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
IOADDR
|
|
|
|
address
|
|
|
|
ENIO
|
|
|
|
|
|
|
|
Where:
|
|
|
|
|
|
|
|
address - decimal or hexadecimal (with prefix '$') address in memory
|
|
|
|
$0000 - $FFFF.
|
|
|
|
|
|
|
|
The same address is used for both, input and output operations.
|
|
|
|
|
|
|
|
Reading from IOADDR inside the 6502 code invokes a blocking character
|
|
|
|
input function from user's DOS/shell session.
|
|
|
|
After user enters the character, the memory location contains the character
|
|
|
|
code and also emulated CPU Acc register contains the same code.
|
|
|
|
|
|
|
|
Reading from IOADDR+1 inside 6502 code invokes a non-blocking character
|
|
|
|
input function from user's DOS/shell session.
|
2016-08-21 05:41:38 +00:00
|
|
|
|
|
|
|
The difference between blocking and non-blocking character input from 6502
|
|
|
|
code perspective:
|
|
|
|
|
|
|
|
- blocking
|
|
|
|
|
|
|
|
Just read from the address. Emulated device will wait for the character
|
|
|
|
input. The 6502 code does not need to be polling the address for
|
|
|
|
a keystroke.
|
|
|
|
|
|
|
|
- non-blocking
|
|
|
|
|
|
|
|
If there is no character/keystroke in the keyboard buffer, the function
|
|
|
|
will move on returning the value of 0. If implementing waiting character
|
|
|
|
input in 6502 code with this function, the 6502 code needs to be polling
|
|
|
|
the value returned from this address in a loop until it is different
|
|
|
|
than 0.
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
Note that there is no clearly distinguished prompt generated by emulator
|
|
|
|
when there is character input operation performed. It is designed like that
|
|
|
|
to avoid interfering with the character I/O performed by native 6502 code.
|
|
|
|
Therefore if user performs multi-step debugging in the debug console and
|
|
|
|
program suddenly stops, it is likely waiting for character input.
|
|
|
|
This is more clear when running the native 6502 code in non-debug execute
|
|
|
|
mode. In this case the I/O operations are represented on the screen instantly
|
|
|
|
and 6502 code may also produce prompts so user is aware when to enter data
|
|
|
|
to the program.
|
|
|
|
|
|
|
|
Writing to IOADDR inside the 6502 code will result in character code
|
|
|
|
being put in the IOADDR memory location and also written to the character
|
|
|
|
output buffer of the emulated display device.
|
|
|
|
|
|
|
|
When VM is running in one of the debug modes, like step-by-step mode
|
|
|
|
(S - step, N - go number of steps) or one of the debug code execution modes
|
|
|
|
(C- continue or G - go/cont. from new address), that character is not
|
|
|
|
immediately transferred to the user's DOS/shell session.
|
|
|
|
It is only written to the emulated display's text memory.
|
|
|
|
|
|
|
|
When VM is running in non-debug code execution mode (X - execute from new
|
|
|
|
address), the character is also output to the native DOS/shell console
|
2016-08-21 05:41:38 +00:00
|
|
|
(user's screen, a.k.a. standard output).
|
2016-03-15 05:09:40 +00:00
|
|
|
The character output history is therefore always kept in the memory of the
|
|
|
|
emulated text display device and can be recalled to the screen in debug
|
|
|
|
console with command 'T'.
|
|
|
|
|
|
|
|
There are 2 reasons for this:
|
|
|
|
|
|
|
|
* Performance.
|
2016-08-21 05:41:38 +00:00
|
|
|
|
2016-03-15 05:09:40 +00:00
|
|
|
In previous version only the emulated text display device approach was used.
|
|
|
|
That meant that each time there was a new character in the emulated display
|
|
|
|
buffer, the entire emulated text output device screen had to be refreshed on
|
|
|
|
the DOS/shell console. That was slow and caused screen flicker when characters
|
|
|
|
were output at high rate of speed.
|
|
|
|
|
|
|
|
* Record of character I/O operation.
|
2016-08-21 05:41:38 +00:00
|
|
|
|
2016-03-15 05:09:40 +00:00
|
|
|
During step-by-step debugging or multiple-step animated registers mode, any
|
|
|
|
characters output is immediately replaced by the registers and stack status
|
2016-08-21 05:41:38 +00:00
|
|
|
on the screen and is not visible on the screen. However user, while debugging
|
|
|
|
must be able to recall the history of the characters output to the emulated
|
|
|
|
text display device if user's program uses character I/O, for normal operation
|
|
|
|
or diagnostic purposes. This is when shadow copy of character I/O comes handy.
|
|
|
|
In real life, text output devices like text terminals, serial terminals,
|
|
|
|
especially the software emulated ones also offer the facilities to buffer the
|
|
|
|
output to memory for later review (history).
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
4. ROM (read-only memory) emulation.
|
|
|
|
|
|
|
|
This facility provides very basic means for memory mapping of the read-only
|
|
|
|
area. This may be required by some 6502 programs that check for non-writable
|
|
|
|
memory to establish the bounds of memory that can be used for data and code.
|
|
|
|
One good example is Tiny Basic.
|
|
|
|
By default the ROM emulation is disabled and the memory range of ROM is
|
|
|
|
defined as $D000 - $DFFF.
|
|
|
|
ROM emulation can be enabled (and the memory range defined) using debug
|
|
|
|
console's command 'K':
|
|
|
|
|
|
|
|
K [rombegin] [romend] - to enable
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
K - to disable
|
|
|
|
|
|
|
|
The ROM emulation can also be defined and enabled in the memory image
|
|
|
|
definition file with following statements:
|
|
|
|
|
|
|
|
ROMBEGIN
|
|
|
|
address
|
|
|
|
ROMEND
|
|
|
|
address
|
|
|
|
ENROM
|
|
|
|
|
2016-08-21 05:41:38 +00:00
|
|
|
For more sophisticated memory mapping schemes including multiple ROM ranges
|
|
|
|
and/or MMU-s that allow to read from ROM, write to RAM in the same range etc.
|
|
|
|
I suggest to write your ROM device emulating code and use it to expand the
|
|
|
|
functionality of this emulator using memory Mapped Devices framework,
|
|
|
|
explained later in this document and in the programmer's reference manual
|
|
|
|
document included with this project.
|
|
|
|
|
2016-03-15 05:09:40 +00:00
|
|
|
5. Additional comments and remarks.
|
|
|
|
|
|
|
|
IOADDR is permitted to be located in the emulated ROM memory range.
|
|
|
|
The writing to IOADDR is trapped first before checking ROM range and writing
|
|
|
|
to it is permitted when character I/O emulation and ROM are enabled at the
|
|
|
|
same time. It is a good idea in fact to put the IOADDR inside ROM range,
|
|
|
|
otherwise memory scanning routines like the one in Tiny Basic may trigger
|
|
|
|
unexpected character input because of the reading from IOADDR during the scan.
|
|
|
|
If you experience unexpected character input prompt while emulating
|
|
|
|
6502 code, this may be the case. Reconfigure your IOADDR to be inside ROM in
|
|
|
|
such case and try again.
|
|
|
|
|
2016-04-18 02:54:35 +00:00
|
|
|
Emulator is "cycle accurate" but not time or speed accurate.
|
|
|
|
This means that each call to MKCpu::ExecOpcode() method is considered a single
|
|
|
|
CPU cycle, so depending on the executed opcode, multiple calls (# varies per
|
|
|
|
opcode and other conditions) are needed to complete the opcode execution and
|
2016-08-10 03:39:52 +00:00
|
|
|
proceed to the next one. Method returns pointer to the virtual CPU registers.
|
|
|
|
One of the members of this structure is named CyclesLeft. When this variable
|
|
|
|
reaches 0, the opcode execution is considered complete.
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
The VMachine class calls the ExecOpcode() method as fast as possible, so it is
|
|
|
|
not real-time accurate, as already mentioned. To implement real-time accurate
|
|
|
|
emulation, the MKCpu::ExecOpcode() method calls would have to be synchronized
|
|
|
|
to some fairly accurate time scale (some kind of timer thread or a different
|
2016-08-21 05:41:38 +00:00
|
|
|
solution) to emulate the timing on the bus signals level. This emulator does
|
|
|
|
not implement such level of accuracy.
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
6. Debugger Console Command Reference.
|
|
|
|
|
|
|
|
S - step
|
|
|
|
Executes single opcode at current address.
|
|
|
|
C - continue
|
|
|
|
Continues code execution from current address until BRK.
|
|
|
|
M - dump memory
|
|
|
|
Usage: M [startaddr] [endaddr]
|
|
|
|
Where: startaddr,endaddr - memory addr. in hexadecimal format [0000..FFFF].
|
|
|
|
Dumps contents of memory, hexadecimal and ASCII formats."
|
|
|
|
G - go/continue from new address until BRK
|
|
|
|
Usage: G [address]
|
|
|
|
Where: address - memory addr. in hexadecimal format [0000.FFFF].
|
|
|
|
Executes code at provided address, interrupted by BRK opcode.
|
|
|
|
X - execute code from new address until RTS
|
|
|
|
Usage: X [address]
|
|
|
|
Where: address - memory addr. in hexadecimal format [0000.FFFF].
|
|
|
|
Executes code at provided address, until RTS (last one).
|
|
|
|
Q - quit
|
|
|
|
Exits from the emulator/debugger.
|
|
|
|
A - set address for next step
|
|
|
|
Usage: A [address]
|
|
|
|
Where: address - memory addr. in hexadecimal format [0000.FFFF].
|
|
|
|
Sets current address to a new value.
|
|
|
|
N - go number of steps
|
|
|
|
Usage: N [steps]
|
|
|
|
Where: steps - number of steps in decimal format
|
|
|
|
Execute number of opcodes provided in steps argument starting
|
|
|
|
from current address.
|
|
|
|
P - IRQ
|
|
|
|
Send maskable interrupt request to CPU (set the IRQ line LOW).
|
|
|
|
W - write to memory
|
|
|
|
Usage: W [address] [hexval] [hexval] ... 100
|
|
|
|
Where: address - memory addr. in hexadecimal format [0000.FFFF],
|
|
|
|
hexval - byte value in hexadecimal format [00.FF].
|
|
|
|
Writes provided values to memory starting at specified address.
|
|
|
|
I - toggle char I/O emulation
|
|
|
|
Usage: I [address]
|
|
|
|
Where: address - memory addr. in hexadecimal format [0000.FFFF],
|
|
|
|
Toggles basic character I/O emulation. When enabled, all writes
|
|
|
|
to the specified memory address also writes a character code to
|
|
|
|
to a virtual console. All reads from specified memory address
|
|
|
|
are interpreted as console character input.
|
2016-08-10 03:39:52 +00:00
|
|
|
V - toggle graphics display (video) emulation
|
|
|
|
Usage: V [address]
|
|
|
|
Where: address - memory addr. in hexadecimal format [0000.FFFF],
|
|
|
|
Toggles basic raster (pixel) based RGB graphics display emulation.
|
|
|
|
When enabled, window with graphics screen will open and several
|
|
|
|
registers are available to control the device starting at provided
|
|
|
|
base address. Read programmers reference for detailed documentation
|
2016-08-21 05:41:38 +00:00
|
|
|
regarding the available registers and their functions.
|
2016-04-18 02:54:35 +00:00
|
|
|
R - show registers
|
|
|
|
Displays CPU registers, flags and stack.
|
|
|
|
Y - snapshot
|
|
|
|
Usage: Y [file_name]
|
|
|
|
Where: file_name - the name of the output file.
|
|
|
|
Save snapshot of current CPU and memory in a binary file.
|
|
|
|
T - show I/O console
|
|
|
|
Displays/prints the contents of the virtual console screen.
|
|
|
|
Note that in run mode (commands X, G or C), virtual screen is
|
|
|
|
displayed automatically in real-time if I/O emulation is enabled.
|
|
|
|
E - toggle I/O local echo
|
|
|
|
Toggles local echo on/off when I/O emulation is enabled.
|
|
|
|
B - blank (clear) screen
|
|
|
|
Clears the screen, useful when after exiting I/O emulation or
|
|
|
|
registers animation (long stack) your screen is messed up.
|
|
|
|
F - toggle registers animation mode
|
|
|
|
When in multi-step debug mode (command: N), displaying registers
|
|
|
|
can be suppressed or, when animation mode is enabled - they will
|
|
|
|
be continuously displayed after each executed step.
|
|
|
|
J - set registers status animation delay
|
|
|
|
Usage: J [delay]
|
|
|
|
Where: delay - time of delay in milliseconds,
|
|
|
|
Sets the time added at the end of each execution step in multi
|
|
|
|
step mode (command: N). The default value is 250 ms.
|
|
|
|
K - toggle ROM emulation
|
|
|
|
Usage: K [rombegin] [romend] - to enable,
|
|
|
|
K - to disable,
|
|
|
|
(OR just use 'K' in both cases and be prompted for arguments.)
|
|
|
|
Where:
|
|
|
|
rombegin - hexadecimal address [0200..FFFF],
|
|
|
|
romend - hexadecimal address [rombegin+1..FFFF].
|
|
|
|
Enable/disable ROM emulation and define address range to which the ROM
|
|
|
|
(read-only memory) will be mapped. Default range: $D000-$DFFF.
|
|
|
|
L - load memory image
|
|
|
|
Usage: L [image_type] [image_name]
|
2016-08-21 05:41:38 +00:00
|
|
|
Where:
|
2016-08-10 03:39:52 +00:00
|
|
|
image_type - A - (auto), B (binary), H (Intel HEX) OR D (definition),
|
2016-04-18 02:54:35 +00:00
|
|
|
image_name - name of the image file.
|
|
|
|
This function allows to load new memory image from either binary
|
|
|
|
image file, Intel HEX format file or the ASCII definition file.
|
2016-08-10 03:39:52 +00:00
|
|
|
With option 'A' selected, automatic input format detection will be
|
|
|
|
attempted.
|
2016-04-18 02:54:35 +00:00
|
|
|
The binary image is always loaded from address 0x0000 and can be up to
|
|
|
|
64kB long. The definition file format is a plain text file that can
|
|
|
|
contain following keywords and data:
|
2016-08-21 05:41:38 +00:00
|
|
|
|
2016-04-18 02:54:35 +00:00
|
|
|
ADDR This keyword defines the run address of the executable code.
|
|
|
|
It is optional, but if exists, it must be the 1-st keyword
|
|
|
|
in the definition file.
|
|
|
|
Address in decimal or hexadecimal ($xxxx) format must follow
|
|
|
|
in the next line.
|
|
|
|
|
|
|
|
ORG Changes the current address counter. The line that follows
|
|
|
|
sets the new address in decimal or hexadecimal format.
|
|
|
|
Data that follows will be put in memory starting from that
|
|
|
|
address. This keyword is optional and can be used multiple
|
|
|
|
times in the definition file.
|
|
|
|
|
|
|
|
IOADDR Defines the address of the character I/O emulation. The
|
|
|
|
next line sets the address of I/O emulation in decimal or
|
|
|
|
hexadecimal format. If the I/O emulation is enabled
|
|
|
|
(see ENIO keyword), then any character written to this
|
|
|
|
address will be sent to the virtual console. The reading
|
|
|
|
from that address will invoke character input from the
|
|
|
|
emulated console. That input procedure is of blocking
|
|
|
|
type. To invoke non-blocking character procedure, reading
|
|
|
|
should be performed from IOADDR+1.
|
|
|
|
|
|
|
|
ROMBEGIN Defines the address in memory where the beginning of the
|
|
|
|
Read Only memory is mapped. The next line that follows this
|
|
|
|
keyword sets the address in decimal or hexadecimal format.
|
|
|
|
|
|
|
|
ROMEND Defines the address in memory where the end of the Read
|
|
|
|
Only Memory is mapped. The next line that follows this
|
|
|
|
keyword sets the address in decimal or hexadecimal format.
|
|
|
|
|
|
|
|
ENIO Putting this keyword in memory definition file enables
|
|
|
|
rudimentary character I/O emulation and virtual console
|
|
|
|
emulation.
|
|
|
|
|
|
|
|
ENROM Putting this keyword in memory definition file enables
|
|
|
|
emulation of Read Only Memory, in range of addresses
|
|
|
|
defined by ROMBEGIN and ROMEND keywords.
|
|
|
|
|
|
|
|
EXEC Define starting address of code which will be automatically
|
|
|
|
executed after the memory image is loaded.
|
|
|
|
The next line that follows this keyword sets the address
|
|
|
|
in decimal or hexadecimal format.
|
|
|
|
|
|
|
|
RESET Enables auto-reset of the CPU. After loading the memory
|
2016-08-21 05:41:38 +00:00
|
|
|
definition file, the CPU reset sequence will be initiated.
|
|
|
|
|
|
|
|
ENGRAPH Enables raster graphics device emulation.
|
|
|
|
|
|
|
|
GRAPHADDR Defines the base address of raster graphics device. The next
|
|
|
|
line that follows sets the address in decimal or hexadecimal
|
|
|
|
format.
|
|
|
|
|
|
|
|
NOTE: The binary image file can contain a header which contains
|
|
|
|
definitions corresponding to the above parameters at fixed
|
|
|
|
positions. This header is created when user saves the snapshot of
|
|
|
|
current emulator memory image and status. Example use scenario:
|
|
|
|
* User loads the image definition file.
|
|
|
|
* User adjusts various parameters of the emulator
|
|
|
|
(enables/disables devices, sets addresses, changes memory
|
|
|
|
contents).
|
|
|
|
* User saves the snapshot with 'Y' command.
|
|
|
|
* Next time user loads the snapshot image, all the parameters
|
|
|
|
and memory contents stick. This way game status can be saved
|
|
|
|
or a BASIC interpreter with BASIC program in it.
|
|
|
|
See command 'Y' for details.
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
O - display op-codes history
|
|
|
|
Show the history of last executed op-codes/instructions, full with
|
2016-08-21 05:41:38 +00:00
|
|
|
disassembled mnemonic, argument and CPU registers and status.
|
|
|
|
NOTE: op-codes execute history must be enabled, see command 'U'.
|
2016-04-18 02:54:35 +00:00
|
|
|
D - diassemble code in memory
|
|
|
|
Usage: D [startaddr] [endaddr]
|
|
|
|
Where: startaddr,endaddr - hexadecimal address [0000..FFFF].
|
|
|
|
Attempt to disassemble code in specified address range and display
|
|
|
|
the results (print) on the screen in symbolic form.
|
|
|
|
0 - reset
|
|
|
|
Run the processor initialization sequence, just like the real CPU
|
|
|
|
when its RTS signal is set to LOW and HIGH again. CPU will disable
|
|
|
|
interrupts, copy address from vector $FFFC to processors PC and will
|
|
|
|
start executing code. Programmer must put initialization routine
|
|
|
|
under address pointed by $FFFC vector, which will set the arithmetic
|
|
|
|
mode, initialize stack, I/O devices and enable IRQ if needed before
|
|
|
|
jumping to main loop. The reset routine disables trapping last RTS
|
|
|
|
opcode if stack is empty, so the VM will never return from opcodes
|
|
|
|
execution loop unless user interrupts with CTRL-C or CTRL-Break.
|
2016-08-21 05:41:38 +00:00
|
|
|
? - display commands menu
|
|
|
|
Display the menu of all available in Debug Console commands.
|
|
|
|
U - enable/disable exec. history
|
|
|
|
Toggle enable/disable of op-codes execute history.
|
|
|
|
Disabling this feature improves performance.
|
2016-09-08 02:52:01 +00:00
|
|
|
Z - enable/disable debug traces
|
|
|
|
Toggle enable/disable of debug traces.
|
|
|
|
2 - display debug traces
|
|
|
|
Display recent debug traces.
|
|
|
|
1 - enable/disable performance stats
|
|
|
|
Toggle enable/disable emulation speed measurement.
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
NOTE:
|
|
|
|
1. If no arguments provided, each command will prompt user to enter
|
|
|
|
missing data.
|
|
|
|
2. It is possible to exit from running program to debugger console
|
|
|
|
by pressing CTRL-C or CTRL-Pause/Break, which will generate
|
|
|
|
a "Operator Interrupt". However in the character input mode
|
|
|
|
use CTRL-Y combination or CTRL-Break (DOS), CTRL-C (Linux).
|
2016-09-08 02:52:01 +00:00
|
|
|
You may need to press ENTER after that in input mode (DOS).
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
7. Command line usage.
|
|
|
|
|
2017-07-28 22:58:48 +00:00
|
|
|
D:\src\wrk\mkbasic>vm65 -h
|
2016-04-18 02:54:35 +00:00
|
|
|
Virtual Machine/CPU Emulator (MOS 6502) and Debugger.
|
|
|
|
Copyright (C) by Marek Karcz 2016. All rights reserved.
|
|
|
|
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
|
2017-07-28 22:58:48 +00:00
|
|
|
vm65 [-h] | [ramdeffile] [-b | -x] [-r]
|
2016-08-10 03:39:52 +00:00
|
|
|
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
Where:
|
|
|
|
|
|
|
|
ramdeffile - RAM definition file name
|
2016-08-10 03:39:52 +00:00
|
|
|
-b - specify input format as binary
|
|
|
|
-x - specify input format as Intel HEX
|
|
|
|
-r - after loading, perform CPU RESET
|
|
|
|
-h - print this help screen
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
When ran with no arguments, program will load default memory
|
|
|
|
definition files: default.rom, default.ram and will enter the debug
|
|
|
|
console menu.
|
2016-08-10 03:39:52 +00:00
|
|
|
When ramdeffile argument is provided with no input format specified,
|
|
|
|
program will attempt to automatically detect input format and load the
|
|
|
|
memory definition from the file, set the flags and parameters depending
|
|
|
|
on the contents of the memory definition file and enter the corresponding
|
|
|
|
mode of operation as defined in that file.
|
|
|
|
If input format is specified (-b|-x), program will load memory from the
|
|
|
|
provided image file and enter the debug console menu.
|
2016-04-18 02:54:35 +00:00
|
|
|
|
|
|
|
8. Utilities.
|
|
|
|
|
|
|
|
Utility bin2hex is supplied with the project to aid in conversion from raw
|
|
|
|
binary memory image to one of the plain text formats recognized by emulator
|
|
|
|
NOTE: In current version, emulator can load raw binary format directly, so
|
|
|
|
usefulness of this utility is somewhat deprecated.
|
|
|
|
|
|
|
|
D:\src\wrk\mkbasic>bin2hex -h
|
|
|
|
|
|
|
|
Program: bin2hex
|
|
|
|
Convert binary file to Intel HEX format.
|
|
|
|
OR
|
|
|
|
Convert binary file to memory image definition for MKBASIC (VM65) emulator.
|
|
|
|
|
|
|
|
Copyright: Marek Karcz 2016. All rights reserved.
|
|
|
|
Free for personal and educational use.
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
|
|
|
|
bin2hex -f input -o output [-w addr] [-x exec] [[-s] [-z] | -i]
|
|
|
|
|
|
|
|
Where:
|
|
|
|
|
|
|
|
input - binary file name
|
|
|
|
output - output file name
|
|
|
|
addr - starting address to load data (default: 2048)
|
|
|
|
exec - address to auto-execute code from (default: 2048)
|
|
|
|
-s - suppress auto-execute statement in output
|
|
|
|
-z - suppress data blocks with 0-s only
|
|
|
|
-i - convert to Intel HEX format
|
|
|
|
NOTE: When this switch is used, addr, exec, -s, -z are ignored,
|
|
|
|
addr = 0, exec is not set and data blocks with 0-s only
|
|
|
|
are always suppressed.
|
|
|
|
|
2016-08-10 03:39:52 +00:00
|
|
|
9. Memory Mapped Device abstraction layer.
|
|
|
|
|
|
|
|
In microprocessor based systems in majority of cases communication with
|
|
|
|
peripheral devices is done via registers which in turn are located under
|
|
|
|
specific memory addresses.
|
|
|
|
Programming API responsible for modeling this functionality is implemented
|
|
|
|
in Memory and MemMapDev classes. The Memory class implements access to
|
|
|
|
specific memory locations and maintains the memory image.
|
|
|
|
The MemMapDev class implements specific device address spaces and handling
|
2016-08-21 05:41:38 +00:00
|
|
|
methods that are triggered when addresses that belong to the device are
|
|
|
|
accessed by the microprocessor.
|
2016-08-10 03:39:52 +00:00
|
|
|
Programmers can expand the functionality of this emulator by adding necessary
|
|
|
|
code emulating specific devices in MemMapDev and Memory classes implementation
|
|
|
|
and header files. In current version, two basic devices are implemented:
|
|
|
|
character I/O and raster (pixel based) graphics display. Both can be activated
|
|
|
|
or inactivated at will and provide simple register based interface that
|
|
|
|
requires no extra memory space use for data.
|
|
|
|
E.g.:
|
|
|
|
Character I/O device uses just 2 memory locations, one for non-blocking I/O
|
|
|
|
and one for blocking I/O. Writing to location causes character output, while
|
|
|
|
reading from location waits for character input (blocking mode) or reads the
|
2016-08-21 05:41:38 +00:00
|
|
|
character from keyboard buffer if available (non-blocking mode) or returns 0.
|
2016-08-10 03:39:52 +00:00
|
|
|
The graphics display can be accessed by writing to multiple memory locations.
|
|
|
|
|
|
|
|
If we assume that GRDEVBASE is the base address of the Graphics Device, there
|
|
|
|
are following registers:
|
|
|
|
|
|
|
|
Offset Register Description
|
2017-07-28 22:58:48 +00:00
|
|
|
----------------------------------------------------------------------------
|
2016-08-10 03:39:52 +00:00
|
|
|
0 GRAPHDEVREG_X_LO Least significant part of pixel's X (column)
|
|
|
|
coordinate or begin of line coord. (0-255)
|
|
|
|
1 GRAPHDEVREG_X_HI Most significant part of pixel's X (column)
|
2017-07-28 22:58:48 +00:00
|
|
|
coordinate or begin of line coord. (0-1)
|
2016-08-10 03:39:52 +00:00
|
|
|
2 GRAPHDEVREG_Y Pixel's Y (row) coordinate (0-199)
|
|
|
|
3 GRAPHDEVREG_PXCOL_R Pixel's RGB color component - Red (0-255)
|
|
|
|
4 GRAPHDEVREG_PXCOL_G Pixel's RGB color component - Green (0-255)
|
|
|
|
5 GRAPHDEVREG_PXCOL_B Pixel's RGB color component - Blue (0-255)
|
2017-07-28 22:58:48 +00:00
|
|
|
6 GRAPHDEVREG_BGCOL_R Backgr. RGB color component - Red (0-255)
|
|
|
|
7 GRAPHDEVREG_BGCOL_G Backgr. RGB color component - Green (0-255)
|
|
|
|
8 GRAPHDEVREG_BGCOL_B Backgr. RGB color component - Blue (0-255)
|
2016-08-10 03:39:52 +00:00
|
|
|
9 GRAPHDEVREG_CMD Command code
|
|
|
|
10 GRAPHDEVREG_X2_LO Least significant part of end of line's X
|
|
|
|
coordinate
|
|
|
|
11 GRAPHDEVREG_X2_HI Most significant part of end of line's X
|
|
|
|
coordinate
|
|
|
|
12 GRAPHDEVREG_Y2 End of line's Y (row) coordinate (0-199)
|
2017-07-28 22:58:48 +00:00
|
|
|
13 GRAPHDEVREG_CHRTBL Set the 2 kB bank where char. table resides
|
|
|
|
14 GRAPHDEVREG_TXTCURX Set text cursor position (column)
|
|
|
|
15 GRAPHDEVREG_TXTCURY Set text cursor position (row)
|
|
|
|
16 GRAPHDEVREG_PUTC Output char. to current pos. and move cursor
|
|
|
|
17 GRAPHDEVREG_CRSMODE Set cursor mode : 0 - not visible, 1 - block
|
|
|
|
18 GRAPHDEVREG_TXTMODE Set text mode : 0 - normal, 1 - reverse
|
|
|
|
|
|
|
|
NOTE: Functionality maintaining text cursor is not yet implemented.
|
2016-08-10 03:39:52 +00:00
|
|
|
|
|
|
|
Writing values to above memory locations when Graphics Device is enabled
|
|
|
|
allows to set the corresponding parameters of the device, while writing to
|
|
|
|
command register executes corresponding command (performs action) per codes
|
|
|
|
listed below:
|
|
|
|
|
|
|
|
Command code Command description
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
GRAPHDEVCMD_CLRSCR = 0 Clear screen
|
|
|
|
GRAPHDEVCMD_SETPXL = 1 Set the pixel location to pixel color
|
|
|
|
GRAPHDEVCMD_CLRPXL = 2 Clear the pixel location (set to bg color)
|
|
|
|
GRAPHDEVCMD_SETBGC = 3 Set the background color
|
|
|
|
GRAPHDEVCMD_SETFGC = 4 Set the foreground (pixel) color
|
|
|
|
GRAPHDEVCMD_DRAWLN = 5 Draw line
|
|
|
|
GRAPHDEVCMD_ERASLN = 6 Erase line
|
|
|
|
|
|
|
|
Reading from registers has no effect (returns 0).
|
|
|
|
|
|
|
|
Above method of interfacing GD requires no dedicated graphics memory space
|
|
|
|
in VM's RAM. It is also simple to implement.
|
2016-08-21 05:41:38 +00:00
|
|
|
The downside - slower performance (multiple memory writes to select/unselect
|
2016-08-10 03:39:52 +00:00
|
|
|
a pixel or set color).
|
|
|
|
I plan to add graphics frame buffer in the VM's RAM address space in future
|
|
|
|
release.
|
|
|
|
|
|
|
|
Simple demo program written in EhBasic that shows how to drive the graphics
|
|
|
|
screen is included: grdevdemo.bas.
|
|
|
|
|
2016-08-21 05:41:38 +00:00
|
|
|
10. Performance considerations.
|
|
|
|
|
|
|
|
Program measures the emulation performance and displays it in the Debug
|
|
|
|
Console. It uses a 1 MHz CPU as a reference to return % of speed compared to
|
|
|
|
assumed 1,000,000 CPU cycles or clock ticks per second - which is considered
|
|
|
|
a 100 % speed.
|
|
|
|
Performance is measured during the whole execution cycle and calculated at the
|
|
|
|
end of the run. Captured speed is summed with previous result and divided by 2
|
|
|
|
to produce average emulation speed during single session.
|
|
|
|
|
|
|
|
This emulator has been optimized for performance. I had issues with
|
2017-07-28 22:58:48 +00:00
|
|
|
emulation speed in previous version, mostly because it was a prototype with
|
|
|
|
many debugging aids enabled by default and not yet optimized for speed.
|
|
|
|
I took a good look at all the critical parts of code and fixed the problems.
|
|
|
|
I am sure there is still space for improvement, but now the emulation speed
|
|
|
|
leaves good margin for expansion with new emulated peripherals and still
|
|
|
|
should compare well to the model 1 MHz CPU.
|
2016-08-21 05:41:38 +00:00
|
|
|
Emulating of pure 6502 machine code with all peripherals (memory mapped
|
|
|
|
devices, I/O etc.) emulation disabled and time critical debugging facility,
|
|
|
|
the op-codes execute history also disabled, returns performance in range of
|
|
|
|
646 % (PC1) and 468 % (PC2) (* see annotation below).
|
|
|
|
Enabling the op-code execute history drops the performance.
|
|
|
|
With all peripherals disabled and op-code history enabled we are down to
|
|
|
|
411 % on PC1 and 312 % on PC2.
|
|
|
|
|
|
|
|
Enabling and adding the emulated memory mapped devices to the pool may cause
|
2016-09-08 02:52:01 +00:00
|
|
|
the emulation speed to drop as well. However even with currently implemented
|
2016-08-21 05:41:38 +00:00
|
|
|
peripherals (char I/O, graphics raster device) enabled and actively used and
|
|
|
|
op-codes execute history enabled the performance is still well above 300 %
|
|
|
|
on both PC1 and on PC2 (* see annotations for PC configurations/specs).
|
|
|
|
The same case but with op-code execute history disabled - performance exceeds
|
|
|
|
400 % on both PC configurations.
|
|
|
|
|
|
|
|
Currently the main emulation loop is not synchronized to an accurate
|
|
|
|
clock tick or raster synchronization signal but just runs as fast as it can.
|
|
|
|
Therefore emulation speed may vary per PC and per current load on the system.
|
|
|
|
|
|
|
|
If this code is to be used as a template to implement emulator of a real-world
|
|
|
|
machine, like C-64 or Apple I, it may need some work to improve performance,
|
|
|
|
but I think is leaves a pretty good margin for expansion as it is.
|
|
|
|
On a fast PC (* see annotation) the emulation speed above 600 % with
|
|
|
|
basically nothing but CPU emulated and op-codes execute history disabled
|
|
|
|
(which should be disabled by default as it is needed for debugging purposes
|
|
|
|
only) is IMO decent if we don't want to emulate MOS 6502 machine with clock
|
|
|
|
much faster than 1 MHz.
|
|
|
|
|
|
|
|
Annotations to 'Performance considerations':
|
|
|
|
*)
|
|
|
|
|
|
|
|
PC1 stats:
|
|
|
|
Type: Desktop
|
|
|
|
CPU: 2.49 GHz (64-bit Quad-core Q8300)
|
|
|
|
RAM: 4,060 MB
|
|
|
|
OS: Windows 10 Pro (no SP) [6.2.9200]
|
|
|
|
|
|
|
|
PC2 stats:
|
|
|
|
Type: Laptop
|
|
|
|
CPU: 2.3 GHz (64-bit Quad-core i5-6300HQ)
|
|
|
|
RAM: 15.9 GB
|
|
|
|
OS: Win 10 Home.
|
|
|
|
|
|
|
|
11. Problems, issues, bugs.
|
2016-08-10 03:39:52 +00:00
|
|
|
|
|
|
|
* Regaining focus of the graphics window when it is not being written to by the
|
|
|
|
6502 code is somewhat flakey. Since the window has no title bar, user can
|
|
|
|
only switch to it by ALT-TAB (windows) or clicking on the corresponding icon
|
|
|
|
on the task bar. However it doesn't always work. Switching to the DOS console
|
|
|
|
of emulator while in emulation mode should bring the graphics window back
|
|
|
|
to front.
|
|
|
|
|
2016-08-21 05:41:38 +00:00
|
|
|
12. Warranty and License Agreement.
|
2016-03-15 05:09:40 +00:00
|
|
|
|
|
|
|
This software is provided with No Warranty.
|
|
|
|
I (The Author) will not be held responsible for any damage to computer
|
|
|
|
systems, data or user's health resulting from using this software.
|
|
|
|
Please use responsibly.
|
|
|
|
This software is provided in hope that it will be be useful and free of
|
|
|
|
charge for non-commercial and educational use.
|
|
|
|
Distribution of this software in non-commercial and educational derivative
|
|
|
|
work is permitted under condition that original copyright notices and
|
|
|
|
comments are preserved. Some 3-rd party work included with this project
|
|
|
|
may require separate application for permission from their respective
|
|
|
|
authors/copyright owners.
|
|
|
|
|
|
|
|
|
|
|
|
|