Don't forget that a PRoGram file has a two-byte, little-endian header that tells the kernel where to load the file. In the case of a PRG file that is a BASIC program, the header is normally ignored by loading with LOAD "0:<filename>",8 (assuming the floppy disk is device 8) and the program text is loaded to wherever in memory the start of BASIC has been defined for the target machine, e.g., $0801 in a Commodore 64. A non-relocating load is effected with LOAD "0:<filename>",8,1, which uses the header to define the address to which the file will be loaded.
Raspberry Pi Pico 6502 emulator
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Raspberry Pi Pico 6502 emulator
jfoucher wrote:
Thanks for all the great info. Hopefully I can at least get load and save of prg files working
Don't forget that a PRoGram file has a two-byte, little-endian header that tells the kernel where to load the file. In the case of a PRG file that is a BASIC program, the header is normally ignored by loading with LOAD "0:<filename>",8 (assuming the floppy disk is device 8) and the program text is loaded to wherever in memory the start of BASIC has been defined for the target machine, e.g., $0801 in a Commodore 64. A non-relocating load is effected with LOAD "0:<filename>",8,1, which uses the header to define the address to which the file will be loaded.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Raspberry Pi Pico 6502 emulator
What a fantastic project! Love it!
Re: Raspberry Pi Pico 6502 emulator
jfoucher wrote:
I recently received a few raspberry pi picos!
My original idea was to use one of them as a VGA output for my 6502 computer, but that did not really work out.
So I took a different tack about what to do with them and decided to run a 6502 emulator. The I/O is very simple and goes through the Pico's USB to serial capability.
For the emulation code, I started out with this and added support for 65C02 instructions to be able to run Taliforth on it. You can also choose to run it in 6502 mode by changing one #define statement.
It passes all of Klaus Dorman's 65C02 test suite.
I then added 6522 support from this repository.
Hi
And putting it on a breadboard, we get some blinkenlights !
While running the tests, I get about 3.1 MHz of emulated speed if I overclock the Pico to 280 Mhz. That seems fairly slow, so I've been looking at Daryl's code for an ARM assembly 6502 emulator. I have absolutely no experience in ARM assembly though, so it will be a while before I can try and rewrite the emulator in ARM assembly that is compatible with the RP2040 microcontroller... If we go by Daryl's result (ARM: 900 MHz -> 6502: 97MHz) I should be able get more than 25 MHz 6502 emulated speed out of the Pico!
Here is the github repo if anyone is interested : https://github.com/jfoucher/pico-6502
My original idea was to use one of them as a VGA output for my 6502 computer, but that did not really work out.
So I took a different tack about what to do with them and decided to run a 6502 emulator. The I/O is very simple and goes through the Pico's USB to serial capability.
For the emulation code, I started out with this and added support for 65C02 instructions to be able to run Taliforth on it. You can also choose to run it in 6502 mode by changing one #define statement.
It passes all of Klaus Dorman's 65C02 test suite.
I then added 6522 support from this repository.
Hi
And putting it on a breadboard, we get some blinkenlights !
While running the tests, I get about 3.1 MHz of emulated speed if I overclock the Pico to 280 Mhz. That seems fairly slow, so I've been looking at Daryl's code for an ARM assembly 6502 emulator. I have absolutely no experience in ARM assembly though, so it will be a while before I can try and rewrite the emulator in ARM assembly that is compatible with the RP2040 microcontroller... If we go by Daryl's result (ARM: 900 MHz -> 6502: 97MHz) I should be able get more than 25 MHz 6502 emulated speed out of the Pico!
Here is the github repo if anyone is interested : https://github.com/jfoucher/pico-6502
To light up any LED I tried writing #$FF to $FF90 - $FF94 but no luck, then tried $#FF to all memory locations below $F000, which is where Krusader starts, but again no luck.
Thanks
Re: Raspberry Pi Pico 6502 emulator
I was able to get output to work fine, it was just that in main, line
was in place, while needing to be replaced by its comment
Looking now to get external input to work.
Thanks
Code: Select all
gpio_dirs = 0;Code: Select all
gpio_dirs = GPIO_PORTB_MASK | GPIO_PORTA_MASK;Thanks
Re: Raspberry Pi Pico 6502 emulator
* This post has been updated after further work on this code*
External input/output is now working. To accomplish this, I heavily modified the read6502 routine within 6502emu.c. It may ultimately end up that this was not necessary, I still ponder if there was some small issue causing external input to not work as expected, however the below describes what works for me at present.
I connected up a 1602A display (not i2c), and executed a 6502 assembly Hello World program which printed to the screen as expected, with a small exception in that I had to delay in my assembly program after setting the data direction register.
Next I ensured I could read correct values when pulling GPIO's high or low from an external source and proceeded with testing spi from PORTA which was successful as well. For this I connected an SD card to PORTA and ran George Foot's full initialization, sending several commands then reads the first sector, printing the last byte back to the LCD, which on a FAT32 card was reported back correctly as 55AA. His example is at https://github.com/gfoot/sdcard6502/tree/master
From that same repo, I then staged the SUBFOLDR/DEEPFILE.TXT file and executed the test_dumpfile.s program, which successfully found the directory, the file and printed it's contents to the LCD.
I did not have to delay in assembly when setting the data direction registers for spi, but I did have to delay in any code setting the ddr which supported a 1602A display.
With this I have confidence that those changes (though they can be improved) are at least working.
There is more work to be done. Known ones are:
I have one additional global (I know) variable defined:
Then a modified read6502 as:
jfoucher > I forked the repo and will sync my changes tomorrow. Let me know if you would be interested in pull request back to your repo ?
I'm curious if Fake6502 is open source, as well as the work you've done with 6502emu.c, etc?
Thanks
External input/output is now working. To accomplish this, I heavily modified the read6502 routine within 6502emu.c. It may ultimately end up that this was not necessary, I still ponder if there was some small issue causing external input to not work as expected, however the below describes what works for me at present.
I connected up a 1602A display (not i2c), and executed a 6502 assembly Hello World program which printed to the screen as expected, with a small exception in that I had to delay in my assembly program after setting the data direction register.
Next I ensured I could read correct values when pulling GPIO's high or low from an external source and proceeded with testing spi from PORTA which was successful as well. For this I connected an SD card to PORTA and ran George Foot's full initialization, sending several commands then reads the first sector, printing the last byte back to the LCD, which on a FAT32 card was reported back correctly as 55AA. His example is at https://github.com/gfoot/sdcard6502/tree/master
From that same repo, I then staged the SUBFOLDR/DEEPFILE.TXT file and executed the test_dumpfile.s program, which successfully found the directory, the file and printed it's contents to the LCD.
I did not have to delay in assembly when setting the data direction registers for spi, but I did have to delay in any code setting the ddr which supported a 1602A display.
With this I have confidence that those changes (though they can be improved) are at least working.
There is more work to be done. Known ones are:
- As mentioned above with a 1602A display, when setting it's associated data direction register, in the 65c02 assembly I find it must have a delay afterward, else the display will miss the first few characters. This is odd because if the port is instead to speak with a SD card interface over SPI, no delay is needed. The shortest delay that worked was to simply set x to #128, decrement and loop till zero. Another option to solve this was to set a 2ms sleep in the C code when it sets the data direction register, however this is wasteful and slows things down too much while it is more efficient to code a small assembly delay for any port ddr used with a 1602A display.
Memory can be inspected for the via ports A and B, I "think" this may have worked in the original version and I will re-visit that code, however for now I have returned them in a custom way. I do need to make sure these are all returning correctly.
I have one additional global (I know) variable defined:
Code: Select all
uint8_t via_latch = 0;Code: Select all
uint8_t read6502(uint16_t address)
{
#ifndef TESTING
// if (address == 0xf004) { // Don, update to work easily with Krusader
if (address == 0xe004)
{
int16_t ch = getchar_timeout_us(100);
if (ch == PICO_ERROR_TIMEOUT)
{
return 0;
}
return (uint8_t)ch & 0xFF;
#ifdef VIA_BASE_ADDRESS
}
// else if ((address & 0xFF00) == VIA_BASE_ADDRESS)
else if ((address & 0xFFF0) == VIA_BASE_ADDRESS)
{
// MODIFICATION PORTA
if (address == VIA_BASE_ADDRESS + 0x01) // PORTA
// MODIFICATION PORTA
{
uint8_t pin_0_value, pin_1_value, pin_2_value, pin_3_value, pin_4_value, pin_5_value, pin_6_value, pin_7_value;
uint8_t pins[] = {PIN_0, PIN_1, PIN_2, PIN_3, PIN_4, PIN_5, PIN_6, PIN_7};
via_latch = (gpio_get(PIN_7) << 7) | (gpio_get(PIN_6) << 6) | (gpio_get(PIN_5) << 5) | (gpio_get(PIN_4) << 4) | (gpio_get(PIN_3) << 3) | (gpio_get(PIN_2) << 2) | (gpio_get(PIN_1) << 1) | gpio_get(PIN_0);
}
// MODIFICATION PORTB
if (address == VIA_BASE_ADDRESS) // PORTB
{
uint8_t pin_8_value, pin_9_value, pin_10_value, pin_11_value, pin_12_value, pin_13_value, pin_14_value, pin_15_value;
uint8_t pins[] = {PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15};
via_latch = (pin_8_value << 7) | (pin_9_value << 6) | (pin_10_value << 5) | (pin_11_value << 4) | (pin_12_value << 3) | (pin_13_value << 2) | (pin_14_value << 1) | pin_15_value;
}
if (address == VIA_BASE_ADDRESS + 2) // PORTB DDRB
{
// Access the value stored at M6522_REG_DDRB
via_latch = via.pb.ddr;
}
if (address == VIA_BASE_ADDRESS + 3) // PORTA DDRA
{
// Access the value stored at M6522_REG_DDRA
via_latch = via.pa.ddr;
}
if (address == VIA_BASE_ADDRESS + 4) // T1C-L
{
via_latch = via.t1.counter & 0xff;
}
if (address == VIA_BASE_ADDRESS + 5) // T1C-H
{
via_latch = via.t1.counter >> 8;
}
if (address == VIA_BASE_ADDRESS + 6) // T1L-L
{
via_latch = via.t1.latch & 0xff;
}
if (address == VIA_BASE_ADDRESS + 7) // T1L-H
{
via_latch = via.t1.latch >> 8;
}
if (address == VIA_BASE_ADDRESS + 8) // T2C-L
{
via_latch = (uint8_t) (via.t2.counter & 0xff);
}
if (address == VIA_BASE_ADDRESS + 9) // T2C-H
{
via_latch = (uint8_t) (via.t2.counter >> 8);
}
//if (address == VIA_BASE_ADDRESS + 0xa) // SR
// {
// via_latch = via.sr); // FIX ME
// }
if (address == VIA_BASE_ADDRESS + 0xb) // ACR
{
via_latch = via.acr;
}
if (address == VIA_BASE_ADDRESS + 0xc) // PCR
{
via_latch = via.pcr;
}
if (address == VIA_BASE_ADDRESS + 0xd) // IFR
{
via_latch = via.intr.ifr;
}
if (address == VIA_BASE_ADDRESS + 0xe) // IER
{
via_latch = via.intr.ier;
}
if (address == VIA_BASE_ADDRESS + 0xf) // ORA/IRA Reg 1 but No handshake
{
via_latch = (gpio_get(PIN_7) << 7) | (gpio_get(PIN_6) << 6) | (gpio_get(PIN_5) << 5) | (gpio_get(PIN_4) << 4) | (gpio_get(PIN_3) << 3) | (gpio_get(PIN_2) << 2) | (gpio_get(PIN_1) << 1) | gpio_get(PIN_0);
}
// And in any case
//if ((address == VIA_BASE_ADDRESS + 0x01) || (address == VIA_BASE_ADDRESS))
// {
via_pins &= ~(M6522_RS_PINS | M6522_CS2); // clear RS pins - set CS2 low
// Set via RW high set selected set RS pins
via_pins |= (M6522_RW | M6522_CS1 | ((uint16_t)M6522_RS_PINS & address));
via_pins = m6522_tick(&via, via_pins);
// MODIFICATION VDATA
// Via trigrred IRQ
// uint8_t vdata = M6522_GET_DATA(via_pins);
uint8_t vdata = via_latch;
// printf("reading from VIA: %04X %02X \n", address, vdata);
// }
via_update();
// old_ticks > 0 ? old_ticks-- : 0;
return vdata;
//}
#endif
}
#endif
return mem[address];
}I'm curious if Fake6502 is open source, as well as the work you've done with 6502emu.c, etc?
Thanks
Re: Raspberry Pi Pico 6502 emulator
Hi,
I modified pico-6502 to emulate Apple1 (Replica1).
It worked with original binary of Wozmon, krusader, and 8K basic, which located at $E000-$FFFF.
I forked noneya's dev branch and create new branch.
https://github.com/kuwatay/pico-6502-apple1/tree/apple1
Thank you for your useful code.
-Yoshi
I modified pico-6502 to emulate Apple1 (Replica1).
It worked with original binary of Wozmon, krusader, and 8K basic, which located at $E000-$FFFF.
I forked noneya's dev branch and create new branch.
https://github.com/kuwatay/pico-6502-apple1/tree/apple1
Thank you for your useful code.
-Yoshi
Re: Raspberry Pi Pico 6502 emulator
Welcome - and congratulations, and thanks for sharing!
Re: Raspberry Pi Pico 6502 emulator
Hi kuwatay - That is awesome and thanks for sharing!
You also beat me to it !
I am putting the finishing touches on one which will have Taliforth 2, Krusader, Wozmon, and EHBasic. EHBasic will load from an sd card to RAM at $5000. This will actually (purposely) be 2 PICO's, one serving as the CPU, ACIA, RAM and ROM and the other serving as a disk controller for the sd card with future plans to incorporate PICOVGA on that one as well.
I have it all working well tonight with the only exception being I need to finish a little routine to allow for the saving of the basic code, I just finished load before checking the forum. I should finish up save and get this posted in the next few days.
I also used 2 PICO's purposely because I wanted to simulate a setup with a pico connected to a real via., i.e. such that the code written would pretty much be ready to move over to a setup with a real 6502 processor, etc.
kuwatay thanks, I look forward to downloading and playing with your contribution as well!
PS: Would you consider posting the assembly source for the 8KBasic_Monitor.h ? I was just working with apple 1 basic for my homebrew yesterday, I got it to run but everything I enter ends with SYNTAX ERROR. I am pretty sure it relates to the high bit handling but didn't solve it so moved on to other things. If I could review your source it may help me with mine.
You also beat me to it !
I have it all working well tonight with the only exception being I need to finish a little routine to allow for the saving of the basic code, I just finished load before checking the forum. I should finish up save and get this posted in the next few days.
I also used 2 PICO's purposely because I wanted to simulate a setup with a pico connected to a real via., i.e. such that the code written would pretty much be ready to move over to a setup with a real 6502 processor, etc.
kuwatay thanks, I look forward to downloading and playing with your contribution as well!
PS: Would you consider posting the assembly source for the 8KBasic_Monitor.h ? I was just working with apple 1 basic for my homebrew yesterday, I got it to run but everything I enter ends with SYNTAX ERROR. I am pretty sure it relates to the high bit handling but didn't solve it so moved on to other things. If I could review your source it may help me with mine.
Re: Raspberry Pi Pico 6502 emulator
BigEd-san
Thank you for your worm welcome. I'll enjoy the forum with lots of 6502 experts.
Thank you for your worm welcome. I'll enjoy the forum with lots of 6502 experts.
Re: Raspberry Pi Pico 6502 emulator
Hi, noneya
Your project sounds very interesting. I'm looking forward to see it.
Actually, I didn't write any 6502 code for pico-6502-apple1, just wrote a1 PIA emulator in C code.
The binary in 8KBasic_Monitor.h came from RC6502 replica 1 project.
https://github.com/tebl/RC6502-Apple-1- ... e/firmware
Anyway, if you need a1basic source code, here the link of asm source code by Eric Smith.
https://github.com/brouhaha/a1basic/blo ... 1basic.asm
Hope this helps.
-Yoshi
Your project sounds very interesting. I'm looking forward to see it.
Actually, I didn't write any 6502 code for pico-6502-apple1, just wrote a1 PIA emulator in C code.
The binary in 8KBasic_Monitor.h came from RC6502 replica 1 project.
https://github.com/tebl/RC6502-Apple-1- ... e/firmware
Anyway, if you need a1basic source code, here the link of asm source code by Eric Smith.
https://github.com/brouhaha/a1basic/blo ... 1basic.asm
Hope this helps.
-Yoshi
Re: Raspberry Pi Pico 6502 emulator
noneya wrote:
jfoucher > I forked the repo and will sync my changes tomorrow. Let me know if you would be interested in pull request back to your repo ?
I'm curious if Fake6502 is open source, as well as the work you've done with 6502emu.c, etc?
Thanks
I'm curious if Fake6502 is open source, as well as the work you've done with 6502emu.c, etc?
Thanks
Re: Raspberry Pi Pico 6502 emulator
kuwatay wrote:
Hi,
I modified pico-6502 to emulate Apple1 (Replica1).
It worked with original binary of Wozmon, krusader, and 8K basic, which located at $E000-$FFFF.
I forked noneya's dev branch and create new branch.
https://github.com/kuwatay/pico-6502-apple1/tree/apple1
Thank you for your useful code.
-Yoshi
I modified pico-6502 to emulate Apple1 (Replica1).
It worked with original binary of Wozmon, krusader, and 8K basic, which located at $E000-$FFFF.
I forked noneya's dev branch and create new branch.
https://github.com/kuwatay/pico-6502-apple1/tree/apple1
Thank you for your useful code.
-Yoshi
Re: Raspberry Pi Pico 6502 emulator
jfoucher wrote:
noneya wrote:
jfoucher > I forked the repo and will sync my changes tomorrow. Let me know if you would be interested in pull request back to your repo ?
I'm curious if Fake6502 is open source, as well as the work you've done with 6502emu.c, etc?
Thanks
I'm curious if Fake6502 is open source, as well as the work you've done with 6502emu.c, etc?
Thanks
Thanks much. This is a neat project, though there are great emulators out there, this approach provides a way to mimic the interaction with the via in a real world way. As mentioned earlier I've connected up to a LCD, interfaced with an SD card over SPi / parallel, etc. This provides a quick and easy platform to develop against prior to burning roms, and overall a great way to share back with others in our hobby.
Thanks for sharing!
Re: Raspberry Pi Pico 6502 emulator
kuwatay wrote:
Hi, noneya
Your project sounds very interesting. I'm looking forward to see it.
Actually, I didn't write any 6502 code for pico-6502-apple1, just wrote a1 PIA emulator in C code.
The binary in 8KBasic_Monitor.h came from RC6502 replica 1 project.
https://github.com/tebl/RC6502-Apple-1- ... e/firmware
Anyway, if you need a1basic source code, here the link of asm source code by Eric Smith.
https://github.com/brouhaha/a1basic/blo ... 1basic.asm
Hope this helps.
-Yoshi
Your project sounds very interesting. I'm looking forward to see it.
Actually, I didn't write any 6502 code for pico-6502-apple1, just wrote a1 PIA emulator in C code.
The binary in 8KBasic_Monitor.h came from RC6502 replica 1 project.
https://github.com/tebl/RC6502-Apple-1- ... e/firmware
Anyway, if you need a1basic source code, here the link of asm source code by Eric Smith.
https://github.com/brouhaha/a1basic/blo ... 1basic.asm
Hope this helps.
-Yoshi
Thanks,
Re: Raspberry Pi Pico 6502 emulator
Hi looking forward to this topic. Look also at Oscar V's KIM-UNO also has apple integer basic. Re the syntax error is it as simple as needing all CAPS?