Files
ksymon/samples/ehbasic/min_mon.asm
T
Seth Morabito 795ccfde5d 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.
2012-10-21 20:05:05 -07:00

153 lines
3.5 KiB
NASM

; 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