Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intel 8080 emulator #48

Open
ivop opened this issue May 30, 2023 · 2 comments
Open

Intel 8080 emulator #48

ivop opened this issue May 30, 2023 · 2 comments

Comments

@ivop
Copy link
Contributor

ivop commented May 30, 2023

Hi,

Th last few days I have been working on this. Eventually I plan to run it on top of CP/M-65 to provide BIOS and possibly BDOS functionality. That would need some copying between 8080 and 6502 memory, for example for writestring if the string crosses a memory bank border. What do you think? I'm pretty excited about it. Something I'd wanted to do for years, emulating the 8080 on a 6502.

https://github.com/ivop/atari8080

Not sure how difficult it would be to port it to other systems, too. C64 REU is slow, but apparently there's also a 256kB banked memory upgrade. Master 128 sideways RAM has some limitations I believe, so that might not work or have less than 64kB for the 8080 environment. Apple 2e seems to have 48kB banks, so that'll probably work. You can even do the same BIT trick (see instruction fetcher in 8080.s) if you only use the lower 32kB of the bank and use two banks.

Regards,
Ivo

Edit: I added a pre-assembled binary. Run with atari800 -xe 8080.xex.

@davidgiven
Copy link
Owner

Very nice --- what's the performance like? (I'm guessing, not great...)

Regarding memory access: it'd be nice to have something cross-platform. Traditionally CP/M does extended memory access via a ramdisk. Reading and writing blocks is pretty cheap, although much slower than access via banking, of course. I wonder if some kind of virtual memory would be feasible?

Thinking out loud:

  • take the top byte of the address, and with 0xc0, shift right four times.
  • this is the offset into an array of 32 pointers in zero page, each of which points at a 2kB local block of memory.
  • if the pointer is non-zero, that block is mapped in. Get the pointer, add the address, dereference, return.
  • if it is zero, that block's not mapped in, so we follow a slow path to allocate a block and load it from a 64kB swapfile. This may involve evicting another block and writing it back to disk.

That would be something like...

lda vaddr+1
and #0xc0
lsr a
lsr a
tax
lda mappings+1
beq no_mapping
clc
lda vaddr+0
adc mappings+0, x
sta paddr+0
lda vaddr+1
and #0x3f
adc mappings+1, x
sta paddr+1
<derefence paddr here>

That's.. not that bad? It's more work than your current code but it's portable. Coming up with a cache eviction strategy would be tricky. LRU would require overhead for every memory access, but apparently some ARM chips would just evict a block at random and that was considered good enough...

@ivop
Copy link
Contributor Author

ivop commented Jun 4, 2023

I'm afraid that will slow things down by at least a factor of two, not counting the load and save times to ramdisk. Most optimizations that I use can't be used, like the msb_to_bank and msb_to_adjusted tables, and checking for end of bank with the BIT instruction. Checks and adjustments that have to be done for almost each memory read or write (end-of-bank only during the optimized instruction fetcher).

But I see your point. It would be nice to have a cross-platform 8080.COM but IIUIC that would offload the bankswitching to a platform dependent ramdisk driver. IMHO it's better to keep the platform dependent code as close to the emulation as possible. It's slow enough as it is. Although it's faster than I had expected, I do not have a number yet. I need a proper benchmark program that I can run on a 2MHz or 4MHz 8080 and on the emulator to see how it performs. Do you know about such program?

I think I'll keep the bankswitching in for now. Later, if there's multiple drives and ramdisk support we can always change it or make it optional.

Regards,
Ivo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants