Small 6502 systems on Lattice ice40

Topics relating to PALs, CPLDs, FPGAs, and other PLDs used for the support or creation of 65-family processors, both hardware and HDL.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Small 6502 systems on Lattice ice40

Post by BigEd »

You could probably make a byte-stream oriented interface to the flash: ignore filesystems, just treat it like a long tape (paper or cassette!) and indeed with a block-sized buffer in the FPGA, out of sight of the 6502, it really could be a stream of bytes. Maybe a FIFO would help? Maybe not. The only auxiliary state is the tape counter: if that's hidden, that's simplest. If it's exposed, you might start to make a Hobbit-type of automatic data cassette storage, with rewind and fast forward.

Acorn reused much of their cassette filing system code for their ROM filing system code, which treats banked ROMs as very lightly structured data containers. You have a sequence of named files, I think, with load addresses and execution addresses, and structured as a sequence of 256 byte blocks.
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

Right now I'm using a W25Q32 flash chip with 4MB of storage, only the first 100kB or so of which is needed. It supports a 32kB block erase so I could partition it into 128 blocks of 32kB, reserve the first 4 for the FPGA bitstream and leave 124 for arbitrary data. Code up some custom LOAD/SAVE routines that would use the documented BASIC calls to fetch a block number after the keyword and then have it just read write raw ASCII text as though it were a tape drive. Advantage of this would be that I could use host-based tools to write into the flash at known blocks for transferring programs in from external sources. Downside is that one would have to keep a list of what content was in each block, but that recreates the retro tape counter experience :)
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

I've added a PS/2 keyboard port to the up5k_basic project - it includes both the serial receiver and the scan-code to ASCII conversion logic. It doesn't yet have the ability to transmit back to the keyboard so it assumes scan type 2 (PC-AT) and doesn't light the status LEDs. I'll be studying how to add that capability over the next few days. FPGA resource use is still < 35%.

Github project is here -> https://github.com/emeb/up5k_basic
dmsc
Posts: 153
Joined: 17 Sep 2018

Re: Small 6502 systems on Lattice ice40

Post by dmsc »

Hi emeb!
emeb wrote:
Github project is here -> https://github.com/emeb/up5k_basic
You have a lot of peripherals already :)

Comparing with my own project at https://github.com/dmsc/my6502 , you implemented a few thinks differently:
- You have the video RAM separated from CPU RAM and access through the video module, I have unified RAM.
- I simply clock the RAM at twice the CPU frequency, and access through the CPU on even cycles and through the video on odd cycles.
- My internal bus is somewhat simpler, I only pass a "we" signal to peripherals, so all peripherals are read in every CPU cycle.

I also use a STM32 as programmer, using a bluepill board with "serprog" protocol, https://github.com/dmsc/stm32-vserprog and ported iceprog to use the same https://github.com/dmsc/iceprog-serprog .

I plan to port my FastBasic IDE to the board, this will provide a simple full screen environment with graphics.
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

dmsc wrote:
Comparing with my own project at https://github.com/dmsc/my6502 , you implemented a few thinks differently:
Yes - I started with a system architecture that was based strongly on the old OSI Superboard.
Quote:
- You have the video RAM separated from CPU RAM and access through the video module, I have unified RAM.
Yes - that's how the Superboard video worked so I just stuck with that partitioning. Using a separate SPRAM for video allows me to do some paging tricks without disturbing the main memory.
Quote:
- I simply clock the RAM at twice the CPU frequency, and access through the CPU on even cycles and through the video on odd cycles.
That's not a bad way to do it, but it involves a bit more effort in setting up clock domains and maintaining synchronism. It was initially easier for me to go with a single clock domain for the entire system, but then that ended up requiring arbitration logic to keep CPU and Video DMA from contending. In retrospect I might reconsider the approach you took. Since my video memory is isolated it wouldn't be hard to change, but I would need to rework the top-level clocking architecture a bit to supply the 2x clock.
Quote:
- My internal bus is somewhat simpler, I only pass a "we" signal to peripherals, so all peripherals are read in every CPU cycle.
That's not too different from my approach - I pass a WE and select line to every peripheral, but the default is to read and there's one big mux to route the correct target address back to the CPU.
Quote:
I also use a STM32 as programmer, using a bluepill board with "serprog" protocol, https://github.com/dmsc/stm32-vserprog and ported iceprog to use the same https://github.com/dmsc/iceprog-serprog .
That's neat. I made a custom STM32F042 board that handles the SPI protocol for the FPGA. I'd like to extend it to handling the Flash programming as well - for now I have to "borrow" the FTDI interface from a Lattice Devboard. I'd also like to add a USB/Serial function to my board, but that requires learning how composite USB devices work so I've put it off.
Quote:
I plan to port my FastBasic IDE to the board, this will provide a simple full screen environment with graphics.
Fun! So far I'm just coding either in ca65 which gets loaded into my "ROM", or in the old MS BASIC. I've got SPI access to the FPGA configuration flash memory working, so now I need to code up some read/write routines to tie into the exiting LOAD/SAVE hooks in the old code.
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

Latest updates:

* Removed 8kB BASIC ROM.
* added 20kB RAM in range 8000-CFFF
* added write protect option to RAM on 4kB boundaries
* Boot ROM now loads 8kB BASIC from SPI flash into protected RAM at address range A000-BFFF
* added 4-voice sound generator with 0-32kHz range, choice of waveform (saw/square/triangle/sine/noise) and volume control.

The new sound generator function is based on a Sigma-Delta modulator, so all four voices of analog are generated with a single FPGA output pin driving a simple RC lowpass filter.

I'm studying the BASIC ROM using the published Microsoft source code to figure out how to add LOAD and SAVE functions that use the
SPI Flash. I've borrowed the guts of the LIST statement within my SAVE code so that I can store untokenized ASCII text without requiring
the user to explicitly type "LIST". SAVE and LOAD will have access to more than 100 "slots" into which up to 32kB of BASIC text can be stored.
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

Some new updates to the 6502 project:

* Expanded the BASIC LOAD & SAVE commands to use SPI flash
* Modified video RAM access as dmsc described above - RAM is clocked at 2x the CPU frequency and access is interleaved between video and CPU to simplify arbitration.
* Added NTSC color generation with a 16-color LUT indexed by a separate color memory.

More here: https://github.com/emeb/up5k_basic
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

Added a new feature to the PS/2 keyboard port: host to device communication is now supported which allows the caps lock LED on the keyboard to indicate the previously hidden internal caps lock state of the PS/2 keymap to ASCII decoder. Not a huge step forward, but it was a bit of a challenge and fun to work on...
User avatar
emeb
Posts: 28
Joined: 08 Mar 2019

Re: Small 6502 systems on Lattice ice40

Post by emeb »

Hey all!

I've been quiet for a while but the Lattice iCE40 6502 project is still alive and growing. A few new things to report:

I've started a new GitHub repo which provides an 800x600 60Hz VGA output. Find it here:

https://github.com/emeb/up5k_vga

One of the side effects of the new video is that the 6502 is only running at 10MHz instead of 16MHz as in the NTSC version, primarily because I need to keep the CPU and pixel clocks at a nice ratio. On the upside I've migrated it from the original Arlet Ottens 6502 core to the hoglet 65C02 core. I really have grown to appreciate those few extra instructions.

The VGA system now supports an extra medium-res color pixel mode - 200x150 in 16 colors. It's enough resolution to do some fun stuff.

I was lazy when developing the first few systems and just borrowed someone else's open-source UART design. I found it to be a bit unreliable though - dropping characters on the receive side from time to time, so I designed my own from scratch that seems to work better and uses fewer resources. This has been back-ported to all of my projects.

The design still uses less than 75% of the resources on the UP5K FPGA and I haven't tapped all the memory, DSP and I/O resournces yet so there's room to grow. I hope to get some time to work on the sound generator - add some features and/or upgrade to fancier synthesis modes.

KiCAD hardware designs for the FPGA, I/O and programming boards are now available as well:

https://github.com/emeb/fpga_oshw

https://github.com/emeb/spi_fiend

These are more general-purpose designs that can be used for a wide variety of projects but have been conceived with a bias towards small CPU-based systems.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Small 6502 systems on Lattice ice40

Post by BigEd »

Nice one, looks like rather a fully-featured system - and thanks for the new mini-6850.
Post Reply