SuperCPU for the Vic-20
Moderator: Moderators
Re: SuperCPU for the Vic-20
Small update:
After some rigorous testing, I found that the internal silicon oscillator of the MachXO3 is too unstable to be useable. I tested the board at several temperatures, which showed that the internal counters would have to take temperature into account (which would be too complicated).
Fortunately I had planned to include an external oscillator for the VGA, so it looks like I will base all internal action on this. I did some testing with a 133MHz one, but this gave me headache after a while (no wonder), so decided to go for a 16.384MHz one instead. Internally this goes through a PLL to generate a 524MHz clock that becomes the source for all other clocks. The reason for the 16.384 is that its a fairly common value and that it gives a 65.5MHz clock that is good for XVGA at 60Hz.
Once I get and test the new oscillator, the final pcb goes into production.
After some rigorous testing, I found that the internal silicon oscillator of the MachXO3 is too unstable to be useable. I tested the board at several temperatures, which showed that the internal counters would have to take temperature into account (which would be too complicated).
Fortunately I had planned to include an external oscillator for the VGA, so it looks like I will base all internal action on this. I did some testing with a 133MHz one, but this gave me headache after a while (no wonder), so decided to go for a 16.384MHz one instead. Internally this goes through a PLL to generate a 524MHz clock that becomes the source for all other clocks. The reason for the 16.384 is that its a fairly common value and that it gives a 65.5MHz clock that is good for XVGA at 60Hz.
Once I get and test the new oscillator, the final pcb goes into production.
Re: SuperCPU for the Vic-20
Well, I finally got some Ecliptek Oscillators at 16.384MHz. After some troubleshooting I got the VGA working again and its very stable compared to using the internal silicon oscillator. The rightmost edge is not oscillating anymore:
The 65.5MHz clock is 0.7% higher which gives a mismatch between the monitor and the signal. This is not what causes the pixel bleeding here, but the fact that this monitor has more pixels than the signal resolution of 1024 pixels in width (this particular monitor has 1440 pixels horizontal resolution). Anyway, the picture is very sharp compared to a CRT which was the whole point.
A few bugs surfaced during the testing. I will use this external oscillator for all internal timings and debug it for the first release version.
The 65.5MHz clock is 0.7% higher which gives a mismatch between the monitor and the signal. This is not what causes the pixel bleeding here, but the fact that this monitor has more pixels than the signal resolution of 1024 pixels in width (this particular monitor has 1440 pixels horizontal resolution). Anyway, the picture is very sharp compared to a CRT which was the whole point.
A few bugs surfaced during the testing. I will use this external oscillator for all internal timings and debug it for the first release version.
Re: SuperCPU for the Vic-20
After alot of debugging, the SD Card code has been improved with error correction. The card is now driven from the external clock so that it has a more stable frequency of 24.966MHz. Previous attempts at driving the SPI bus that fast did not work very well.
Still, some read errors were seen once in a while, so an implementation of both CRC7 and CRC16 checks were done. The routines are still driven by the 6502 of the Vic-20, but will eventually be run on the 65C02 side. (The CRC16 calculation takes about 15880 cycles) Save will be implemented later.
In the meantime I have also implemented double char height mode for the VGA and fixed some bugs in that code. There is still an issue with the graphics byte grabbing in some instances, but its on my fix list. I want all games (without raster effects) to work on VGA.
A few notes on the SPI bus:
A special register $97ff is used to control the bus.
Memory $9800-$9Bff is used as a buffer with DMA access.
It takes 164us to fill the buffer with a 514 byte block (512 bytes + CRC16).
I would like to add a second SPI bus for the expansion port. There are many peripherals that can be controlled with this bus, so it will allow anyone to connect things like AMOLED displays, E-ink paper, Cameras... and so on. Due to a change in the Vic-20 interface, I will have to move the A13 address line input to IO3 to do this. Shouldn't be a problem since the A13 isn't needed anyway.
The last thing on the plan before release 1 is to get SRAM to BLK5 mapping working. All of BLK0 can be used for the VGA display, even the RAM1/2/3 gap. BLK1/2/3 can be used for running both 6502 (internal) and 65C02 (external) programs. In fact, they can run at the same time on the same memory. The 1MiB SRAM is only visible through BLK5 though (for the 6502), while the 65C02 can use the full 1MiB SRAM through a MMU register. This is not ready yet, but I may make it compatible with the C128 MMU.
Still, some read errors were seen once in a while, so an implementation of both CRC7 and CRC16 checks were done. The routines are still driven by the 6502 of the Vic-20, but will eventually be run on the 65C02 side. (The CRC16 calculation takes about 15880 cycles) Save will be implemented later.
In the meantime I have also implemented double char height mode for the VGA and fixed some bugs in that code. There is still an issue with the graphics byte grabbing in some instances, but its on my fix list. I want all games (without raster effects) to work on VGA.
A few notes on the SPI bus:
A special register $97ff is used to control the bus.
Memory $9800-$9Bff is used as a buffer with DMA access.
It takes 164us to fill the buffer with a 514 byte block (512 bytes + CRC16).
I would like to add a second SPI bus for the expansion port. There are many peripherals that can be controlled with this bus, so it will allow anyone to connect things like AMOLED displays, E-ink paper, Cameras... and so on. Due to a change in the Vic-20 interface, I will have to move the A13 address line input to IO3 to do this. Shouldn't be a problem since the A13 isn't needed anyway.
The last thing on the plan before release 1 is to get SRAM to BLK5 mapping working. All of BLK0 can be used for the VGA display, even the RAM1/2/3 gap. BLK1/2/3 can be used for running both 6502 (internal) and 65C02 (external) programs. In fact, they can run at the same time on the same memory. The 1MiB SRAM is only visible through BLK5 though (for the 6502), while the 65C02 can use the full 1MiB SRAM through a MMU register. This is not ready yet, but I may make it compatible with the C128 MMU.
Re: SuperCPU for the Vic-20
Another update:
The Vic-6560 emulation now seems to work as it should. I had to rewrite the clock logic completely as it was screwing up when screen map and character map was sharing the same space. Dual char height and column register now works as expected. Still have to implement left border adjustment, but even full screen graphics works (character map at 4096, screen map at 7168). Support for raster effects have not been implemented yet, so more experimental resolutions will have to wait.
External SRAM is now working. It is currently mapped to BLK5 or BLK3, but I plan to make it dynamic so that you can map any BLK to it. The difference between the external SRAM and the internal one is that the latter can run both 6502 and 65C02 code at the same time (in the same location!). It opens for some interesting interactions. The external SRAM is currently not multiplexed, so only one cpu at a time there.
Here is a crude memory map
Looks quite complicated, but it isn't. From the Vic-20 side, everything looks the same except that BLK1-3 and BLK5 has extra RAM, like a 32KiB expansion. BLK0 (or RAM0 to RAM7) is the same as always, but with 3KiB expansion memory in the RAM1-3 area. The memory can be configured through the startup menu if you want, so you can even run it as an unexpanded Vic-20.
On the SuperVixen side, there are two things: 1) The VGA output and 2) the 65C02 processor. Both require RAM:
During normal Vic-20 usage, all memory in the lower part (RAM0-RAM7, or BLK0 if you want to call it that) is copied to the SuperVixen side. The reason for this is that the VGA output gets its data from the normal Vic-20 internal memory. So most programs run as normal and are displayed on both your normal video screen and on the VGA monitor (if you connect it). As simple as that.
The 65C02 is a faster version of the 6502 cpu. It currently runs at 25MHz and can run within its own RAM (External SRAM) or within the Vic-20 expansion RAM (Shared SRAM). The exception is that the 65C02 can not run within the internal RAM of the Vic-20 (RAM0 and RAM4-RAM7). The 65C02 is controlled by the Vic-20 and can be started or stopped by storing (POKE) to a certain register.
It is a possibility to run the Kernal and Basic within the 65C02. The SuperVixen currently lack the implementation of VIA registers, but I hope to do something with this in the future. Running CBM Basic at 25+ times the speed would certainly be a blast!
The Vic-6560 emulation now seems to work as it should. I had to rewrite the clock logic completely as it was screwing up when screen map and character map was sharing the same space. Dual char height and column register now works as expected. Still have to implement left border adjustment, but even full screen graphics works (character map at 4096, screen map at 7168). Support for raster effects have not been implemented yet, so more experimental resolutions will have to wait.
External SRAM is now working. It is currently mapped to BLK5 or BLK3, but I plan to make it dynamic so that you can map any BLK to it. The difference between the external SRAM and the internal one is that the latter can run both 6502 and 65C02 code at the same time (in the same location!). It opens for some interesting interactions. The external SRAM is currently not multiplexed, so only one cpu at a time there.
Here is a crude memory map
Code: Select all
Block Address range 6502 (Vic-20) 65C02 (SuperVixen)
RAM0 $0000-$03FF Internal Vic-20 Copy of Vic-20 RAM or External SRAM
RAM1/2/3 $0400-$0FFF Shared Exclusive or External SRAM
RAM4/5/6/7 $1000-$1FFF Internal Vic-20 Copy of Vic-20 RAM
BLK1/2/3 $2000-$7FFF Shared or External SRAM Shared or External SRAM
BLK4 $8000-$9FFF Character ROM & registers Character RAM, copy of Color RAM and IO2/3 RAM
BLK5 $A000-$BFFF Shared or External SRAM Shared or External SRAM
BLK6 $C000-$DFFF Basic ROM External SRAM
BLK7 $E000-$FFFF Kernal ROM External SRAM
On the SuperVixen side, there are two things: 1) The VGA output and 2) the 65C02 processor. Both require RAM:
During normal Vic-20 usage, all memory in the lower part (RAM0-RAM7, or BLK0 if you want to call it that) is copied to the SuperVixen side. The reason for this is that the VGA output gets its data from the normal Vic-20 internal memory. So most programs run as normal and are displayed on both your normal video screen and on the VGA monitor (if you connect it). As simple as that.
The 65C02 is a faster version of the 6502 cpu. It currently runs at 25MHz and can run within its own RAM (External SRAM) or within the Vic-20 expansion RAM (Shared SRAM). The exception is that the 65C02 can not run within the internal RAM of the Vic-20 (RAM0 and RAM4-RAM7). The 65C02 is controlled by the Vic-20 and can be started or stopped by storing (POKE) to a certain register.
It is a possibility to run the Kernal and Basic within the 65C02. The SuperVixen currently lack the implementation of VIA registers, but I hope to do something with this in the future. Running CBM Basic at 25+ times the speed would certainly be a blast!
Re: SuperCPU for the Vic-20
I just made a group about Vic-20 on MeWe that will give updates on the SuperVixen:
https://mewe.com/join/Vic-20
https://mewe.com/join/Vic-20
Re: SuperCPU for the Vic-20
I hope you will post updates here too as I'm not willing to register on any social media site...
Re: SuperCPU for the Vic-20
+1Schlowski wrote:I hope you will post updates here too as I'm not willing to register on any social media site...
Re: SuperCPU for the Vic-20
The latest update is basically about how to access the 1MiB external SRAM, e.g. a 6502MMU. Here is some example code:
There is no need to go into details, but its all about using codes from the "illegal opcodes" that doesn't do anything else. The MMU sees these codes and reads the $ADDR field to switch bank in the $A000-$AFFF area. There are other methods of bank switching as well, but the above is more efficient. I am currently debugging the IRQ/BRK handling, so alot remains.
Code: Select all
defm MMJ ; addr MMJ=Memory Management Jump
byte $DC
byte >/1
byte </1
endm
defm MMF ; addr MMF=Memory Management Fetch
byte $FC
byte >/1
byte </1
endm
defm LDAX ; highaddr ($ffff), addr ($fff)
byte $FC
byte >/1
byte </1
LDA /2+$A000,X
endm
defm STAX ; highaddr ($ffff), addr ($fff)
byte $FC
byte >/1
byte </1
STA /2+$A000,X
endm
defm JUMP ; highaddr ($ffff), addr ($fff)
byte $DC
byte >/1
byte </1
JMP /2+$A000
endm
defm JSUB ; highaddr ($ffff), addr ($fff)
byte $DC
byte >/1
byte </1
JSR /2+$A000
endm
*=$a000
LDX #0
loop
MMF $0000 ; Make sure its zero
LDA $a100,X
STAX $11,$200 ; Store in $11200,X
INX
CPX #40
BNE loop
JSUB $11,$200 ; JSR $11200
RTS
*=$a100
LDX #0
loop2
TXA
STAX $10,$300 ; Store in $10300,X
INX
BNE loop2
loop3
LDAX $10,$300 ; LoAD from $10300,X
STA $1000,X ; Show on screen
LDA #0
STA $9400,X
INX
BNE loop3
RTS
Re: SuperCPU for the Vic-20
Looking very promising!
If I understand your code right, you are copying a subroutine to $11200 (which copies the content of $10300... to the screen and color ram) and then call this subroutine at $11200.
Some questions arise (at least for me): When executing the subroutine at $11200, what is the value of the instruction pointer? As far as i understand, the 6502 has it's original memory layout, otherwise you couldn't access screen and color ram. But how on earth can you connect the rts from this subroutine back to the original position where you come from?
And thank you for updating us here at Denial
If I understand your code right, you are copying a subroutine to $11200 (which copies the content of $10300... to the screen and color ram) and then call this subroutine at $11200.
Some questions arise (at least for me): When executing the subroutine at $11200, what is the value of the instruction pointer? As far as i understand, the 6502 has it's original memory layout, otherwise you couldn't access screen and color ram. But how on earth can you connect the rts from this subroutine back to the original position where you come from?
And thank you for updating us here at Denial

Re: SuperCPU for the Vic-20
The MMU stores the current bank number during execution of a JSR in the $Axxx area. Basically the MMU contains an internal "stack" with space to 128 memory bank pointers (as the JSR uses the stack of the 6502 to store up to 128 return addresses), so that it goes back to the previous bank upon executing a RTS.Schlowski wrote:Some questions arise (at least for me): When executing the subroutine at $11200, what is the value of the instruction pointer? As far as i understand, the 6502 has it's original memory layout, otherwise you couldn't access screen and color ram. But how on earth can you connect the rts from this subroutine back to the original position where you come from?
Re: SuperCPU for the Vic-20
Thanks for the clarification tht's a really nice solution!
As I reread your previous post I recognized I skipped over one important bit of information
As I reread your previous post I recognized I skipped over one important bit of information
That caused my irritation as I simply didn't get where the subroutine code resides.to switch bank in the $A000-$AFFF area
Re: SuperCPU for the Vic-20
Time for another short update:
I have debugged the MMU implementation for the last weeks. It is now fairly stable and IRQ is now handled as it should. Still, there are some situations with NMI and IRQ that I willl need to test (especially if they happen at the same time). Interrupt routines can now be put anywere in memory (including the 1MiB external SRAM).
I forgot to mention a random number generator that generates a fairly random bitstream. It should mainly be used for generating seeds (for pseudorandom generators), or you can use it directly if you dont care about distribution, normalization and such things.
I have debugged the MMU implementation for the last weeks. It is now fairly stable and IRQ is now handled as it should. Still, there are some situations with NMI and IRQ that I willl need to test (especially if they happen at the same time). Interrupt routines can now be put anywere in memory (including the 1MiB external SRAM).
I forgot to mention a random number generator that generates a fairly random bitstream. It should mainly be used for generating seeds (for pseudorandom generators), or you can use it directly if you dont care about distribution, normalization and such things.
Re: SuperCPU for the Vic-20
I finally got the last ugly bug out of the MMU. Here is a short video of the following code (I start the video with a Wozmon disassembly of the code before I run it):
Basically the "NOP $0022,X" precode is the new MMF $0022 bank select opcode. Using that before an access to $A000 results in an actual memory access of $22000. This works for all opcodes that can access the $A000-$AFFF memory area (but not for other memory areas).
The program starts by storing 256 zeros into $22000 to $220FF.
It then increases the memory location $22000 to $220FF by 1 using INC.
Third, the program copies the content of location $22000-$220FF onto the screen.
Last, the program copies the content of the screen back into location $22000-$220FF before it jumps back to the increase loop.
Everything here runs with IRQ enabled. The interrupt handling has taken some time to get going, but now seems to work. MMF opcodes are stored if an interrupt occur straight after, and is executed at the correct location once the isr returns to the program (through an RTI). And if you wonder: the program runs on the internal NMOS 6502.
Code: Select all
1FA4 78 SEI
1FA5 A2 00 LDX #$00
1FA7 A9 00 LDA #$00
1FA9 FC 22 00 NOP $0022,X
1FAC 9D 00 A0 STA $A000,X
1FAF E8 INX
1FB0 D0 F7 BNE loop1
1FB2 A2 00 rerun LDX #$00
1FB4 FC 22 00 loop3 NOP $0022,X
1FB7 FE 00 A0 INC $A000,X
1FBA E8 INX
1FBB D0 F7 BNE loop3
1FBD A2 00 LDX #$00
1FBF FC 22 00 loop4 NOP $0022,X
1FC2 BD 00 A0 LDA $A000,X
1FC5 9D 00 10 STA $1000,X
1FC8 A9 00 LDA #$00
1FCA 9D 00 94 STA $9400,X
1FCD E8 INX
1FCE D0 EF BNE loop4
1FD0 A2 00 LDX #$00
1FD2 BD 00 10 loop5 LDA $1000,X
1FD5 FC 22 00 NOP $0022,X
1FD8 9D 00 A0 STA $A000,X
1FDB E8 INX
1FDC D0 F4 BNE loop5
1FDE 4C B2 1F JMP rerun
The program starts by storing 256 zeros into $22000 to $220FF.
It then increases the memory location $22000 to $220FF by 1 using INC.
Third, the program copies the content of location $22000-$220FF onto the screen.
Last, the program copies the content of the screen back into location $22000-$220FF before it jumps back to the increase loop.
Everything here runs with IRQ enabled. The interrupt handling has taken some time to get going, but now seems to work. MMF opcodes are stored if an interrupt occur straight after, and is executed at the correct location once the isr returns to the program (through an RTI). And if you wonder: the program runs on the internal NMOS 6502.
- eslapion
- ultimate expander
- Posts: 5037
- Joined: Fri Jun 23, 2006 7:50 pm
- Location: Canada
- Occupation: 8bit addict
Re: SuperCPU for the Vic-20
Somehow, I suspect we're going to have a considerably faster version of Sargon II before long.
Be normal.
Re: SuperCPU for the Vic-20
Uh oh.. ready for higher levels then?eslapion wrote:Somehow, I suspect we're going to have a considerably faster version of Sargon II before long.
