AVR-based 6502 Emulator

Topics pertaining to the emulation or simulation of the 65xx microprocessors and their peripheral chips.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

I have updated my website with the latest version of the Emulator. Thanks to Klaus' recommendations, the speed is over 2 MHz. I also fixed a bug in the EEPROM Write feature.

http://sbc.rictor.org/avr65c02.html

Enjoy!

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

I added the CC65 target source files for the Emulator to my webpage. One will load programs into RAM and can be run from the SBC-2OS. The other creates a 48k image that can be loaded directly into the Emulator ROM and will run on boot-up.

Find them here:
http://sbc.rictor.org/avr65c02.html

I've been blessed with a promotion at work that will take away more of my precious "free-time." I will probably not work on the Emulator any more for a while. I will try to keep up with this forum and answer any questions I can.

Daryl
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

I found some problems in my emulation thanks to Klaus' great test suite. I have made the changes and will release an update as soon as I verify it on my SBC-4 (just for peace of mind).

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

My final update to the Emulator is now online. Thanks again to Klaus for providing the tools to test the opcode behavior.

You can find it here -> http://sbc.rictor.org/avr65c02.html

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

this is really a cool emulator. During my holidays, which finished yesterday, I accidentally stepped over your emulator, when I was doing some research for another small project I'm currently working at. So instead of spending time for my project I spent hours to understand the AVR assembler code. I'm really impressed.

Now back the first thing I did was soldering the required parts together to run the emulator. Building (I use a 20MHz Crystal, I didn't have 24MHz Crystal or Oscillator) the Image for 20MHz was not a problem and it works, however I have problems to use the monitor commands
  • *********************************
    AVR 65C02 Emulator
    By Daryl Rictor (c) 2013

    Press Enter to Start System
    Press 'U' to upload new ROM image
    .
    Version 3.1 - Starting Emulator...
    .

    65C02 Monitor v5.2 (6-28-13) Ready
    with Enhanced Basic Interpreter (c) Lee Davison,
    FIGForth, and MicroChess (c) Peter Jennings
    (Press ? for help)
    >0300.3FF


    >
I expect now 16 lines with 16 bytes but nothing happens, just a gives me a new prompt? Also other commands to not behave as expected, others like L(ist) work.

What do I wrong?

Regards

Peter
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

found the problem, the Terminalprogram sent a CR+LF on <ENTER> per default, SBC Monitor does not like it :roll:, changed it to CR only now it works as expected. This emulator is really amazing. Now I have a 65C02 SBC in a pocket and can develop my projects on the road. And the speed at 20MHz is by far enough, never forget, at my times a 1Mhz 6502 was state of the art.

Regards

Peter
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

I'm glad you found the problem, Peter. I was just starting to troubleshoot it when I saw your response.

I do want to check that you adjusted the default code to compensate for the 20MHz clock.

In bootload.asm and avr6502.asm, there are USART init routines that look like this:

Code: Select all

	ldi		i, 0x0C				; 
										 ; 			16MHZ	20MHZ	24MHz
	ldi		j, 0x00				; 115200	xxxx	000A	000C
	sts		UBRR0H, j			 ;  19200	0033	0040	004D
	sts		UBRR0L, i			 ;  9600	 0067	0081	009B
										 ;  4800 	00CF	0103	0137
										 ;  2400	 019F 	0208	0270
Did you change the "ldi i, 0x0C" to "ldi i, 0x0A" ?

If not, you should to prevent serial corruption.

I'm glad you found the project useful. Thanks for providing feedback and I hope you will enjoy using it!

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

thanks for the hint, yes I changed the uart bitrate settings right from the beginning. So the startup messages always showed correctly. Now I will start to investigate into some changes. My goal is to emulate some legacy 6502 computers.

Regards


Peter
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

is there any reason why the initialisation code is duplicated in bootloader and the main file avr6502.asm? I think all the stuff in avr6502 coulde be either omitted or moved to bootloader. Also you can just leave RAMPZ set to one, the emulator always reads from the lower half (using lpm) and the startupcode uses the upper half (using elpm)

Regards Peter
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

I duplicated the code because the code in avr6502.asm can be updated by the user and downloaded without having a special programmer. I felt have the code twice was acceptable to allow for future "field" changes.

As far as RAMPZ goes, this was the first time I had used an AVR with more than 64k of flash, and I only discovered RAMPZ after I had trouble with the prompts in the bootloader code and I admit I did not fully research its use. Thanks for pointing out that I don't need to reset it.

You mentioned earlier that you wanted to emulate some legacy computers. Keep in mind that the memory map is pretty fixed, to allow for the best efficiency in address conversion in the emulator.

Cheers!

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

yes I'm aware that your memory map is highly optimized for speed. So any change will have a negative impact on speed. But legacy means 1MHz 6502 speed will be enough. On the other hand your emulator code requires only very limited changes to adopt to different memory maps. I'm confident a 48k RAM Apple II should have only a decent impact. For this I will also add external memory as Klaus did. I'lllet you know.

Regards

Peter
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

I thought of a way to speed up processing speed of at least some instructions. In your case you have to use a table with "jmp" instructions as a table with "rjmp" would not work as they don't reach far enough. However a "rjmp" table would not require the "lsl" and "adc" in the EXEC macro.

So I did the following:

- removed "lsl" and "adc" from EXEC
- replaced the "jmp" with "rjmp" in opctbl: and changed the destination to a label starting with __ (2) instead _ (1) and placed it strategically in the middle of the 6502 instruction emulation code (I use the align macro of Klaus to make sure the table starts at a 256word boundary)
- added a buch of lines with "__label: jmp _label" near the opctbl
- moved the more common instruction code near the opctbl (ADC, BEQ, BNE, CMP, JMP, JSR, LDA, LDX, LDY, STA, STX, STY, SBC, RTS) and changed the destination in the opctbl to the label with a single _
- I do not delete the added lines with the "jmp" instructions, even if they are not used, so I can easily switch back and forth just be changing the destination of "rjmp" in the opctbl

Now it would be interesting to know how you bencharked your emulator to see if this effort is worth it. Here just some excerpts of the changed code
  • align 8
    opctbl:
    rjmp __BRK_IMP ;00
    rjmp __ORA_INDX ;01
    .
    .
    .
    rjmp __STY_ABS ;8C
    rjmp _STA_ABS ;8D
    rjmp __STX_ABS ;8E
    rjmp __BBS0_REL ;8F
    rjmp __BCC_REL ;90
    rjmp _STA_INDY ;91
    rjmp _STA_IND ;92
    rjmp __INV ;93
    rjmp __STY_ZPGX ;94
    rjmp _STA_ZPGX ;95 <--- sample of abbreviation
    rjmp __STX_ZPGY ;96
    rjmp __SMB1_ZPG ;97
    rjmp __TYA_IMP ;98
    rjmp _STA_ABSY ;99 <--- sample of abbreviation
    rjmp __TXS_IMP ;9A
    rjmp __INV ;9B
    rjmp __STZ_ABS ;9C
    rjmp _STA_ABSX ;9D <--- sample of abbreviation
    rjmp __STZ_ABSX ;9E
    .
    .
    .

    rjmp __INV ;E3
    rjmp __CPX_ZPG ;E4
    rjmp __SBC_ZPG ;E5
    rjmp __INC_ZPG ;E6
    rjmp __SMB6_ZPG ;E7
    rjmp __INX_IMP ;E8
    rjmp __SBC_IMM ;E9
    rjmp __NOP_IMP ;EA
    rjmp __INV ;EB
    rjmp __CPX_ABS ;EC
    rjmp __SBC_ABS ;ED
    rjmp __INC_ABS ;EE
    rjmp __BBS6_REL ;EF
    rjmp __BEQ_REL ;F0
    rjmp __SBC_INDY ;F1
    rjmp __SBC_IND ;F2
    rjmp __INV ;F3
    rjmp __INV2 ;F4
    rjmp __SBC_ZPGX ;F5
    rjmp __INC_ZPGX ;F6
    rjmp __SMB7_ZPG ;F7
    rjmp __SED_IMP ;F8
    rjmp __SBC_ABSY ;F9
    rjmp __PLX_IMP ;FA
    rjmp __INV ;FB
    rjmp __INV3 ;FC
    rjmp __SBC_ABSX ;FD
    rjmp __INC_ABSX ;FE
    rjmp __BBS7_REL ;FF
    __INV2: jmp _INV2 ;02
    __INV: jmp _INV ;03
    __INV3: jmp _INV3 ;5C


    __BRK_IMP: jmp _BRK_IMP ;00
    __ORA_INDX: jmp _ORA_INDX ;01
    __TSB_ZPG: jmp _TSB_ZPG ;04
    __ORA_ZPG: jmp _ORA_ZPG ;05
    __ASL_ZPG: jmp _ASL_ZPG ;06
    __RMB0_ZPG: jmp _RMB0_ZPG ;07
    __PHP_IMP: jmp _PHP_IMP ;08
    __ORA_IMM: jmp _ORA_IMM ;09
    __ASL_IMP: jmp _ASL_IMP ;0A
    __TSB_ABS: jmp _TSB_ABS ;0C
    __ORA_ABS: jmp _ORA_ABS ;0D
    __ASL_ABS: jmp _ASL_ABS ;0E
    __BBR0_REL: jmp _BBR0_REL ;0F
    __BPL_REL: jmp _BPL_REL ;10
    __ORA_INDY: jmp _ORA_INDY ;11
    __ORA_IND: jmp _ORA_IND ;12
    __TRB_ZPG: jmp _TRB_ZPG ;14
    __ORA_ZPGX: jmp _ORA_ZPGX ;15
    __ASL_ZPGX: jmp _ASL_ZPGX ;16
    __RMB1_ZPG: jmp _RMB1_ZPG ;17
    __CLC_IMP: jmp _CLC_IMP ;18
    __ORA_ABSY: jmp _ORA_ABSY ;19
    __INC_IMP: jmp _INC_IMP ;1A
    __TRB_ABS: jmp _TRB_ABS ;1C
    __ORA_ABSX: jmp _ORA_ABSX ;1D
    __ASL_ABSX: jmp _ASL_ABSX ;1E
    __BBR1_REL: jmp _BBR1_REL ;1F
    __JSR_ABS: jmp _JSR_ABS ;20
For the fast Instructions you save 3 cycles: no "lsl zl" and "adc zh,adc" and a "rjmp" from opcode table instead of "jmp".

For legacy Instructions you save/lose nothing, you just replace the "lsl zl" and "adc zh,adc" with a "rjmp".

Now one could think of some "intermediate" instructions, that would be those that could be made reachable with 2 x "rjmp" instead a "rjmp" and a "jmp"

Regards

Peter

P.S.: Now added the SRAM to my hardware, I use only portc together with an address latch so I need only 9 instead of 16 pins for the address bus (the 9th is the clock of the latch), I'm currently using your emulator to run memory tests :wink:
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: AVR-based 6502 Emulator

Post by 8BIT »

cbscpe wrote:
...Now it would be interesting to know how you bencharked your emulator to see if this effort is worth it.
My benchmark was quite crude. I wrote a loop that included several type of memory access whose counter was reset just after sending a byte out the serial port. Since the emulator take differing amounts of time depending upon wether its a RAM, IO, or ROM access, how you pattern the code inside the loop will affect the calculated speed. The baud was set to 4800 and by counting how many times the loop executed before the USART was ready for the next byte, I could calculate the number of cycles executed. It works well but does take time to calculate the actual cycles used. To check this method, I ran the same code on my SBC-4 with several different system clock oscillators, and my results were pretty consistent.

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: AVR-based 6502 Emulator

Post by cbscpe »

Hi Daryl,

as I'm modifying your code (and do some beautifying for my purpose, especially usage of registers, here I want to make use of .undef to be able to reuse registers without assembler warning) i see that you set zsav and zsavh in bootload.asm and then call XModem and in xmodem-receive.asm the first thing you do is set zsav andzsavh with new values. I assume I can delte the reference to zsav and zsavh in bootload.asm, it seems to be a legacy part that is no longerused, or do you plan to reuseit.

Regards Peter
Klaus2m5
Posts: 442
Joined: 28 Jul 2012
Location: Wiesbaden, Germany

Re: AVR-based 6502 Emulator

Post by Klaus2m5 »

Peter,

you can redefine and thus have two or more names for the same register by using the assembler's pre-processor.

Code: Select all

; 0x1c
;     y                       ; operand address, (D) buffer index
#define     oplow       yl
#define     ophigh      yh
#define     opointer    y
So register 0x1c can be called yl or oplow at any time.
6502 sources on GitHub: https://github.com/Klaus2m5
Post Reply