6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Sep 20, 2024 9:49 am

All times are UTC




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: ESP32 Emulator
PostPosted: Mon Apr 15, 2019 4:41 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
A non-6502 project I've been helping on has recently switched to ESP32 based micro-controllers programmed with the Arduino libraries primarily to access the on board WiFi and Bluetooth Low Energy. These little modules pack a lot of punch for very little money -- 512K of RAM, 4MB of flash, dual core 240Mhz processor, 2.4GHz Wifi, BLE, SPI, I2C, UARTs, Hall sensor, ...

For example:

https://www.ebay.co.uk/itm/ESP32-ESP-32S-NodeMCU-Dev-Board-2-4G-WiFi-Bluetooth-CP2102-UK/152656339743?hash=item238b06e31f:g:9x4AAOSwI79Zis~v&frcectupt=true

So, I thought why not port my emulator and well ... it lives.
Code:
EM-65C816-ESP32 [19.04]
Copyright (C)2019 Andrew John Jacobs.

>> Booting
>> Building memory description:
000000-00efff: RAM (Allocated)
00f000-00ffff: ROM (Contiguous)
010000-01ffff: RAM (Contiguous)
020000-03ffff: RAM (Allocated)
040000-07ffff: ROM (Contiguous)
>> Remaining Heap: 120364
>> Starting execution
00:f000 78          SEI {00:0000,00:0000} E=1 P=..MX.I.. A=00[00] X=00[00] Y=00[00] DP=0000 SP=01[00] { fe fe fe fe } DBR=00 CYC=2
00:f001 d8          CLD {00:0000,00:0000} E=1 P=..MX.I.. A=00[00] X=00[00] Y=00[00] DP=0000 SP=01[00] { fe fe fe fe } DBR=00 CYC=2
00:f002 18          CLC {00:0000,00:0000} E=1 P=..MX.I.. A=00[00] X=00[00] Y=00[00] DP=0000 SP=01[00] { fe fe fe fe } DBR=00 CYC=2
00:f003 fb          XCE {00:0000,00:0000} E=1 P=..MX.I.. A=00[00] X=00[00] Y=00[00] DP=0000 SP=01[00] { fe fe fe fe } DBR=00 CYC=2
00:f004 e2 30       SEP {00:f005,00:0000} E=0 P=..MX.I.C A=00[00] X=00[00] Y=00[00] DP=0000 SP=[0100] { fe fe fe fe } DBR=00 CYC=3
00:f006 c2 30       REP {00:f007,00:0000} E=0 P=..MX.I.C A=00[00] X=00[00] Y=00[00] DP=0000 SP=[0100] { fe fe fe fe } DBR=00 CYC=3

I've rewritten the emulator fairly extensively to fix some memory access edge cases, like reading 16-bit words across page and bank boundaries. The cycle counting needs a little correction here and there too. It is mostly right.

Despite the ESP having 512K of RAM its seems to be fairly fragmented at startup and you can only have a few big contiguous blocks. I had to allocate most of it in 4K blocks to get the 252K in the current configuration. I'm not sure how fast the emulator goes at the moment -- there is too much debugging/trace code in it to tell.

When I get a reasonable build running I've open up the Github repository and post the details here.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Mon Apr 15, 2019 6:34 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Sounds good, Andrew!

BitWise wrote:
I've rewritten the emulator fairly extensively to fix some memory access edge cases, like reading 16-bit words across page and bank boundaries.

I ran in to this pretty much immediately. I've been uplifting my 6502 simulator to a 65816. It's remarkably different now.

Before, I simply had an Int as the address, and things worked great.

Now I have an Address class to deal with it all, with methods like incPageWrap, and incBankWrap.

In my code every time I would see "address + 1", I had to dive down to understand what address, who was asking and and why to figure out what "+1" really means. Honestly it was a bit exhausting.

You combine the address math shenanigans on top of the 8 vs 16 bit access modes and, boy, the head swims a bit.

I felt like I've been walking on eggs every place I went as I hit each interaction. And I know in some places I just went hands up, stomped the eggs flat, "I'll fix it later" to make progress.

I still have, I dunno, 15-20 instructions to implement, including the big one "XCE".

One routine I have is "setFlagsNZ(value)", I have that everywhere. Ya know what? That doesn't work anymore, as it has to be 16b sensitive...sometimes. Now I have that and setFlagsNZ16(value), setFlagsNZAcc(value), setFlagsNZIndex(value) to handle the use cases.

I just realized I have to go and update my overflow logic too. Whee!

Sometime I think it would have been better to start it over from scratch, but I'm grinding through it.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Mon Apr 15, 2019 8:41 pm 
Offline
User avatar

Joined: Wed Mar 01, 2017 8:54 pm
Posts: 660
Location: North-Germany
Reading this it came to my mind that writing five quasi separate emulators might be easier: one for native with A=8 and XY=8, one for A=8, XY=16, one for A=16, XY=8, one for A=XY=16, and one for emulation mode. The transitions between modes are well defined AFAIK. Might still be clumsy.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Mon Apr 15, 2019 10:17 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
GaBuZoMeu wrote:
Reading this it came to my mind that writing five quasi separate emulators might be easier: one for native with A=8 and XY=8, one for A=8, XY=16, one for A=16, XY=8, one for A=XY=16, and one for emulation mode. The transitions between modes are well defined AFAIK. Might still be clumsy.


Absolutely, I considered it. That would certainly make it "faster", since theres no decision logic within the individual instructions. Each time you tweak the meta-mode, you swap out the pointers that implement the instructions.

But raw performance isn't a real drive. Hard enough to get one set of instructions to work, much less 5 :).


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 5:17 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
I think you'd write the program using lots of macros - put the complexity into compile time instead of runtime. lib6502 is very macro-heavy and I think lib65816 might do this very thing.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 10:43 am 
Offline
User avatar

Joined: Wed Mar 01, 2017 8:54 pm
Posts: 660
Location: North-Germany
Getting faster is a side effect I overlooked :)
My thoughts were about clearer case decisions which easily starts to suffer when too many details have to be considered.

BigEd's idea of using macros can be very helpful to keep things readable. Of course they can ruin understanding and slimness of the program when the macro itself becomes fat and ugly, So it is a question of balancing.

Starting with one mode and evolve the emulation code then copy that to the second mode and tweak the differences might work and would then show where macros really assist readability and perhaps shrink the overall code size without sacrificing much speed.

(All this are assumptions - I never started to write an emulator. Only some cross disassemblers I have hacked together ;) )


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 12:11 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
I've opted for C++'s inline functions rather than lots of macros. In a previous version I did try lots of macros but it makes the code rather hard to follow. My current code base has a test inside each opcode function for applicable modifiers (e.g e || p.m, etc.).
Code:
inline uint16_t Emulator::op_deca (uint32_t l, uint32_t h)
{
    if (trace) dump ("DEC", l, h);

    if (e || p.m)
        setnz_b (--c.l);
    else
        setnz_w (--c.w);

    return (2);
}

I use a big switch statement to get to the code for each instruction. The C++ compiler should convert this into an efficient jump table.
Code:
    if (trace) Serial.printf ("%.2x:%.4x %.2x ", pbr.b, pc.w, mem.getByte (pbr.a | pc.w));

    switch (mem.getByte (pbr.a | pc.w++)) {
    case 0x00:  return (am_immb (&Emulator::op_brk));       // BRK #
    case 0x01:  return (am_dpix (&Emulator::op_ora));       // ORA (dpg,X)
    case 0x02:  return (am_immb (&Emulator::op_cop));       // COP #
    case 0x03:  return (am_srel (&Emulator::op_ora));       // ORA off,S
    case 0x04:  return (am_dpag (&Emulator::op_tsb));       // TSB dpg
    case 0x05:  return (am_dpag (&Emulator::op_ora));       // ORA dpg

The code uses pointer to (inline) member functions but optimiser should able to remove that as its being called within another inline function that decodes the addressing mode.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 5:02 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
BigEd wrote:
I think you'd write the program using lots of macros - put the complexity into compile time instead of runtime. lib6502 is very macro-heavy and I think lib65816 might do this very thing.

Macros aren't really appropriate as the decision making needs to be done at runtime, based on the context of the CPU when the instruction is executed. The 65816 has 2, mutually exclusive states: the accumulate state and the index state. Each state affects only a portion of the instruction set. So, one way to look at it is to have two sets of Accumulator based instructions, and two sets of Index based instructions. Then you enable/disable the individual instructions sets based on the state, resulting in 4 combinations of a total instruction set.

Then you have emulation mode which, as far as I can tell so far, is 8 bit Accumulator and Index, a 0's in the Program and Data bank registers, and SP as an 8 Bit value.

So, the emulation mode is almost, but not quite, a 5th state. I have not done any work on the emulation mode yet on my system.

You can naively see how having 5 lists of instruction implementations would be the fastest, since there's essentially no dispatch -- just picking which instruction list to execute based on the mode switches. You'd have to have something like ADC8 and ADC16 routines.

I'm just doing ifs in my instructions. Get those running first.

For my system I have an OpCode class that combines the method for the logic, and the method for the addressing mode. I use the addressing mode method to calculate the address, and then hand it of to the op code logic.

I was working on it last night and realized all of my accumulator work is wrong. I have not been accounting for B. So, I have make a run through the whole thing and clean all that up.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 5:08 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
Oh, I should clarify: you use the macros to construct the five models of the machine, and you link all of those into the emulator, which switches modes when it must, running one or other of the five models for each instruction. Usually mode changes are rare, so testing for mode changes when they change could be an improvement over testing mode bits for each instruction.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 8:16 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
BigEd wrote:
Oh, I should clarify: you use the macros to construct the five models of the machine, and you link all of those into the emulator, which switches modes when it must, running one or other of the five models for each instruction.

Yea, that might work. Java doesn't have macros, so I'm a bit out of luck there.

BigEd wrote:
Usually mode changes are rare, so testing for mode changes when they change could be an improvement over testing mode bits for each instruction.

My ADC instruction has 5 separate tests for the accumulator size (scattered across the main logic and utility functions and the decimal mode).

When I make the sweep through for the B register, I'm sure I'll add another.

So, for sure, there could be performance improvements. For the moment, having all the code in one place lowers the cognitive load on me. I think. I want the darn thing to work first.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Tue Apr 16, 2019 8:21 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
whartung wrote:
I want the darn thing to work first.

A very pragmatic approach!


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Fri Apr 19, 2019 11:20 pm 
Offline

Joined: Sun Oct 14, 2012 7:30 pm
Posts: 107
Someone already wrote a 6502 emulator (with BASIC and such) for the ESP8266. It should just compile for the ESP32. Check the actual Arduino forums for info on it.


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Sat Apr 20, 2019 7:04 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
There might even be a couple. One family is based on Mike Chambers' fake6502 and then there's Alun Jones' which might or might not be related.
https://github.com/ericek111/ESP8266-6502duino
viewtopic.php?f=2&t=2052


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Sat Apr 20, 2019 6:53 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
JimDrew wrote:
Someone already wrote a 6502 emulator (with BASIC and such) for the ESP8266. It should just compile for the ESP32. Check the actual Arduino forums for info on it.

6502 is easy. Getting the 65C816s emulation/native mode and 8/16 size changes correct and working efficiently is more of a challenge.

The first cut of my emulator was far too slow so I'm rewriting it. It doesn't help that the default optimisation setting for the Arduino code framework is for 'space' (-Os) rather than 'speed' (-O3).

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject: Re: ESP32 Emulator
PostPosted: Sat Apr 20, 2019 9:57 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
BitWise wrote:
6502 is easy. Getting the 65C816s emulation/native mode and 8/16 size changes correct and working efficiently is more of a challenge.

The first cut of my emulator was far too slow so I'm rewriting it. It doesn't help that the default optimisation setting for the Arduino code framework is for 'space' (-Os) rather than 'speed' (-O3).

How was it far too slow? What kind of changes are you doing to make it faster?

I'm not concerned with raw performance right now, but I'm just curious.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 26 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: