CPU bug fixes and Simulator enhancements.

Bug Fixes:

- Fixed several bugs in the CPU that caused processor status flags to
  be set incorrectly.  Instructions affected were: STA, STX, STY, CMP,
  CPX, CPY, BIT.

- Made some internal-use-only methods on the CPU class private.

- Fixed incorrect disassembly of (Indirect,X) and (Indirect),Y
  instructions. Although this didn't affect behavior, it certainly
  caused me some confusion in debugging.

- Added missing "BCS" instruction to instruction table.

Enhancements:

- Now includes a full version of Lee Davison's Enhanced 6502 BASIC
  bundled as source code and a ROM image. Get that REAL COMPUTER
  EXPERIENCE!(tm)

- If a file named "rom.bin" exists in the same directory where the
  simulator is executed, it will be loaded at addresses $d000-$ffff.

- Gave the CPU an idle loop to make simulated timing a little more
  realistic (but this is still an area needing major improvement)

- Changed the CPU's toString() method to give better debugging output.

- Added a small typeahead buffer to the Console.

- Better exception messaging.

Misc:

- Bumped version to 0.5, updated README.
This commit is contained in:
Seth Morabito committed 2012-10-21 20:05:05 -07:00
1 parent c1caf8c6b4
commit 795ccfde5d
25 files changed
+13622 -4508

No files matched your search

+34 -4
View File
@@ -1,9 +1,39 @@
A Sample Program
Sample Programs
----------------
When loaded at address $0300, this program will print "Hello, 6502 World!" in
infinite loop.
1. hello.prg
Assembled with the Ophis assembler:
When loaded at address $0300, this program will print "Hello, 6502 World!" in
infinite loop.
2. echo.prg
When loaded at address $0300, this program will echo back to the console
anything typed.
Both hello.prg and echo.prg were assembled with the Ophis assembler:
https://hkn.eecs.berkeley.edu/~mcmartin/ophis/
3. ehbasic.rom
This is Lee Davison's Enhanced 6502 BASIC.
To use this ROM image, just copy the file 'ehbasic.rom' into the directory
where you run Symon. Rename the file to 'rom.bin'. When you start Symon,
the ROM file will be automatically loaded at address $d000.
Click the "Run" button and EhBASIC should automatically start running.
Type 'C' to do a cold start.
Then, type $C000 when prompted for the memory size.
NOTE: EhBASIC only wants upper-case input. This confused me at first!
More information can be found in the 'ehbasic' directory, and by visiting
the EhBASIC web page:
http://mycorner.no-ip.org/6502/ehbasic/index.html
+2 -2
View File
@@ -27,9 +27,9 @@ getkey: lda iostatus ; Read the ACIA status
;; Write the current char in the accumulator to the console
write: pha ; Save accumulator
lda iostatus ; Read the ACIA status
writel: lda iostatus ; Read the ACIA status
and #$10 ; Is the tx register empty?
beq write ; No, wait for it to empty
beq writel ; No, wait for it to empty
pla ; Otherwise, load saved accumulator
sta iobase ; and write to output.
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
*.rom
*.lst
*.map
*.o
+13
View File
@@ -0,0 +1,13 @@
CA=ca65
LD=ld65
all: ehbasic
ehbasic: ehbasic.o
$(LD) -C symon.config -vm -m ehbasic.map -o ehbasic.rom ehbasic.o
ehbasic.o:
$(CA) --listing -o ehbasic.o min_mon.asm
clean:
rm -f *.o *.rom *.map *.lst
+85
View File
@@ -0,0 +1,85 @@
This directoy contains a very slightly modified version of EhBASIC 2.22
to support the Symon simulator.
Usage
-----
The pre-assemled ROM image 'ehbasic.rom' in the "samples" directory is all you
need unless you want to rebuild this source code.
Just copy the image 'ehbasic.rom' to the directory where you run Symon, and
rename the file to 'rom.bin'. It will be loaded at memory location $D000 when
the simulator starts up. Click "Run" and you'll be presented with BASIC.
At the first prompt, type 'C' for a Cold Start
When prompted for free memory, type: $C000
Note that EhBASIC only accepts upper case input, so you'll need to use caps
lock (the cruise control for cool) to really make the most of it.
Building
--------
To build it, you'll need the CC65 tool chain from http://www.cc65.org/
and a suitable version of 'make'. Just typing:
% make
in this directory should re-build everything. You'll get a listing,
some object files, and the ROM image itself.
Changes from the EhBASIC 2.22
-----------------------------
- Minor syntax changes to allow assembly with the cc65 tool chain.
- Memory map modified for Symon.
- At reset, configure the 6551 ACIA for 8-N-1, 2400 baud.
- Monitor routines 'ACIAin' and 'ACIAout' modified for the 6551 ACIA.
Specifically, reading and writing will check the 6551 status register for
the status of rx and tx registers before receive or transmit.
EhBASIC is copyright Lee Davison <leeedavison@googlemail.com>
My changes are so slight that I hesitate to even say this, but for "CYA"
reasons:
Changes are copyright Seth Morabito <web@loomcom.com> and are distributed under
the same license as EhBASIC. I claim no commercial interest whatsoever. Any
commercial use must be negotiated directly with Lee Davison.
Original EhBASIC 2.22 README
----------------------------
Enhanced BASIC is a BASIC interpreter for the 6502 family microprocessors. It
is constructed to be quick and powerful and easily ported between 6502 systems.
It requires few resources to run and includes instructions to facilitate easy
low level handling of hardware devices. It also retains most of the powerful
high level instructions from similar BASICs.
EhBASIC is free but not copyright free. For non commercial use there is only one
restriction, any derivative work should include, in any binary image distributed,
the string "Derived from EhBASIC" and in any distribution that includes human
readable files a file that includes the above string in a human readable form
e.g. not as a comment in an HTML file.
For commercial use please contact me, Lee Davison, at leeedavison@googlemail.com
for conditions.
For more information on EhBASIC, other versions of EhBASIC and other projects
please visit my site at ..
http://mycorner.no-ip.org/index.html
P.S. c't magazin, henceforth refered to as "those thieving german bastards", are
prohibited from using this or any version of EhBASIC for any of their projects
or products. The excuse "we don't charge people for it" doesn't wash, it adds
value to your product so you owe me.
File diff suppressed because it is too large. Load diff
+152
View File
@@ -0,0 +1,152 @@
; minimal monitor for EhBASIC and 6502 simulator V1.05
; To run EhBASIC on the simulator load and assemble [F7] this file, start the simulator
; running [F6] then start the code with the RESET [CTRL][SHIFT]R. Just selecting RUN
; will do nothing, you'll still have to do a reset to run the code.
.feature labels_without_colons
.include "basic.asm"
; put the IRQ and MNI code in RAM so that it can be changed
IRQ_vec = VEC_SV+2 ; IRQ code vector
NMI_vec = IRQ_vec+$0A ; NMI code vector
; setup for the 6502 simulator environment
IO_AREA = $C000
ACIAdata = IO_AREA ; simulated ACIA r/w port
ACIAstatus = IO_AREA+1
ACIAcommand = IO_AREA+2
ACIAcontrol = IO_AREA+3
; now the code. all this does is set up the vectors and interrupt code
; and wait for the user to select [C]old or [W]arm start. nothing else
; fits in less than 128 bytes
.segment "MONITOR"
.org $FF00 ; pretend this is in a 1/8K ROM
; reset vector points here
RES_vec
CLD ; clear decimal mode
LDX #$FF ; empty stack
TXS ; set the stack
; Initialize the ACIA
ACIA_init
LDA #$09
STA ACIAcommand
LDA #$1A ; Set output for 8-N-1 2400
STA ACIAcontrol
; set up vectors and interrupt code, copy them to page 2
LDY #END_CODE-LAB_vec ; set index/count
LAB_stlp
LDA LAB_vec-1,Y ; get byte from interrupt code
STA VEC_IN-1,Y ; save to RAM
DEY ; decrement index/count
BNE LAB_stlp ; loop if more to do
; now do the signon message, Y = $00 here
LAB_signon
LDA LAB_mess,Y ; get byte from sign on message
BEQ LAB_nokey ; exit loop if done
JSR V_OUTP ; output character
INY ; increment index
BNE LAB_signon ; loop, branch always
LAB_nokey
JSR V_INPT ; call scan input device
BCC LAB_nokey ; loop if no key
AND #$DF ; mask xx0x xxxx, ensure upper case
CMP #'W' ; compare with [W]arm start
BEQ LAB_dowarm ; branch if [W]arm start
CMP #'C' ; compare with [C]old start
BNE RES_vec ; loop if not [C]old start
JMP LAB_COLD ; do EhBASIC cold start
LAB_dowarm
JMP LAB_WARM ; do EhBASIC warm start
; byte out to simulated ACIA
ACIAout
PHA ; save accumulator
ACIAout_w
LDA ACIAstatus ; Read 6551 status
AND #$10 ; Is tx buffer full?
BEQ ACIAout_w ; if not, loop back
PLA ; Otherwise, restore accumulator
STA ACIAdata ; write byte to 6551
RTS
; byte in from simulated ACIA
ACIAin
LDA ACIAstatus ; Read 6551 status
AND #$08 ;
BEQ LAB_nobyw ; If rx buffer empty, no byte
LDA ACIAdata ; Read byte from 6551
SEC ; Flag byte received
RTS
LAB_nobyw
CLC ; flag no byte received
no_load ; empty load vector for EhBASIC
no_save ; empty save vector for EhBASIC
RTS
; vector tables
LAB_vec
.word ACIAin ; byte in from simulated ACIA
.word ACIAout ; byte out to simulated ACIA
.word no_load ; null load vector for EhBASIC
.word no_save ; null save vector for EhBASIC
; EhBASIC IRQ support
IRQ_CODE
PHA ; save A
LDA IrqBase ; get the IRQ flag byte
LSR ; shift the set b7 to b6, and on down ...
ORA IrqBase ; OR the original back in
STA IrqBase ; save the new IRQ flag byte
PLA ; restore A
RTI
; EhBASIC NMI support
NMI_CODE
PHA ; save A
LDA NmiBase ; get the NMI flag byte
LSR ; shift the set b7 to b6, and on down ...
ORA NmiBase ; OR the original back in
STA NmiBase ; save the new NMI flag byte
PLA ; restore A
RTI
END_CODE
LAB_mess
.byte $0D,$0A,"6502 EhBASIC [C]old/[W]arm ?",$00
; sign on string
; system vectors
.segment "VECTORS"
.org $FFFA
.word 0 ; NMI vector
.word RES_vec ; RESET vector
.word 0 ; IRQ vector
+18
View File
@@ -0,0 +1,18 @@
MEMORY {
RAM1: start = $0000, size = $C000;
ROM1: start = $D000, size = $2F00, fill = yes;
MONITOR: start = $FF00, size = $FA, fill = yes;
ROMV: start = $FFFA, size = $6, file = %O, fill = yes;
}
SEGMENTS {
CODE: load = ROM1, type = ro;
DATA: load = ROM1, type = ro;
MONITOR: load = MONITOR, type = ro;
VECTORS: load = ROMV, type = ro;
}
SYMBOLS {
__STACKSIZE__ = $0300;
}