diff options
| author | Väinö Kauppila <vaino@vke.fi> | 2026-04-20 15:11:08 +0300 |
|---|---|---|
| committer | Väinö Kauppila <vaino@vke.fi> | 2026-04-20 15:11:08 +0300 |
| commit | b33ebdfd1087bd1de038e23fd256ad5cc6576cfd (patch) | |
| tree | 4d1118c3c7f3a2bc9d283049ea07f6726048ceda | |
| parent | 922c620bf0921a60e15e8abe627b3199e7e1e12a (diff) | |
| download | vhdl_pic-b33ebdfd1087bd1de038e23fd256ad5cc6576cfd.tar.gz vhdl_pic-b33ebdfd1087bd1de038e23fd256ad5cc6576cfd.zip | |
4K progmem
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | fw/fpga_pic.lkr | 22 | ||||
| -rw-r--r-- | fw/snake.c | 60 | ||||
| -rw-r--r-- | hex2rom.py | 4 |
4 files changed, 60 insertions, 30 deletions
@@ -13,7 +13,9 @@ $(BUILD): # -- Host-side C compilation (sdcc on host) -------------------------------------------- $(BUILD)/%.hex: fw/%.c | $(BUILD) - cd $(BUILD) && sdcc --use-non-free -mpic14 -p16f84a $(CURDIR)/fw/$*.c + cd $(BUILD) && sdcc --use-non-free -mpic14 -p16f84a \ + -Wl-s -Wl$(CURDIR)/fw/fpga_pic.lkr \ + $(CURDIR)/fw/$*.c # program.hex is what the testbench loads at runtime $(BUILD)/program.hex: $(BUILD)/$(PROG).hex diff --git a/fw/fpga_pic.lkr b/fw/fpga_pic.lkr new file mode 100644 index 0000000..3fc716f --- /dev/null +++ b/fw/fpga_pic.lkr @@ -0,0 +1,22 @@ +// Custom linker script for FPGA PIC implementation. +// Code page extended to 4K words (real 16f84a only has 1K). +// Bank 1 gprnobank left unprotected so UDL sections can be placed there. +// UART/OW registers at 0x70-0x75 are left out of gprnobank. + +LIBPATH . + +CODEPAGE NAME=page START=0x0 END=0xFFF +CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED +CODEPAGE NAME=devid START=0x2006 END=0x2006 PROTECTED +CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED +CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED + +DATABANK NAME=sfr0 START=0x0 END=0xB PROTECTED +DATABANK NAME=sfr1 START=0x80 END=0x8B PROTECTED + +SHAREBANK NAME=gprnobank START=0xC END=0x6F +SHAREBANK NAME=gprnobank START=0x8C END=0xCF + +SECTION NAME=PROG ROM=page +SECTION NAME=IDLOCS ROM=.idlocs +SECTION NAME=DEEPROM ROM=eedata @@ -8,7 +8,7 @@ __sfr __at(0x72) UART_STATUS; #define GRID_W 20 #define GRID_H 10 -#define MAX_LEN 20 +#define MAX_LEN 10 #define OVF_PER_FRAME 60 #define DIR_UP 0 @@ -16,14 +16,14 @@ __sfr __at(0x72) UART_STATUS; #define DIR_LEFT 2 #define DIR_RIGHT 3 -static uint8_t snake_x[MAX_LEN]; -static uint8_t snake_y[MAX_LEN]; -static uint8_t snake_len; -static uint8_t direction; -static uint8_t food_x; -static uint8_t food_y; -static uint8_t score; -static volatile uint8_t ovf_count; +static __near uint8_t snake_x[MAX_LEN]; +static __near uint8_t snake_y[MAX_LEN]; +static __near uint8_t snake_len; +static __near uint8_t direction; +static __near uint8_t food_x; +static __near uint8_t food_y; +static __near uint8_t score; +static volatile __near uint8_t ovf_count; void isr(void) __interrupt(0) { if (INTCON & 0x04) { @@ -65,21 +65,27 @@ static void handle_input(void) { } static void place_food(void) { - food_x = (ovf_count * 7 + 3) % GRID_W; - food_y = (ovf_count * 5 + 1) % GRID_H; + uint8_t x = ovf_count; + uint8_t y = ovf_count; + x += x; x += x; x += x; x -= ovf_count; x += 3; /* x = ovf*7 + 3 */ + y += y; y += y; y += ovf_count; y += 1; /* y = ovf*5 + 1 */ + while (x >= GRID_W) x -= GRID_W; + while (y >= GRID_H) y -= GRID_H; + food_x = x; + food_y = y; } -static void print_uint8(uint8_t v) { - uint8_t started = 0; - if (v >= 200) { uart_send('2'); v -= 200; started = 1; } - else if (v >= 100) { uart_send('1'); v -= 100; started = 1; } - { - uint8_t t = '0'; - while (v >= 10) { v -= 10; t++; } - if (started || t != '0') uart_send(t); - } - uart_send(v + '0'); -} +/* static void print_uint8(uint8_t v) { */ +/* uint8_t started = 0; */ +/* if (v >= 200) { uart_send('2'); v -= 200; started = 1; } */ +/* else if (v >= 100) { uart_send('1'); v -= 100; started = 1; } */ +/* { */ +/* uint8_t t = '0'; */ +/* while (v >= 10) { v -= 10; t++; } */ +/* if (started || t != '0') uart_send(t); */ +/* } */ +/* uart_send(v + '0'); */ +/* } */ static void render(void) { uint8_t x, y, i; @@ -115,8 +121,8 @@ static void render(void) { for (x = 0; x < GRID_W; x++) uart_send('-'); uart_puts("+\r\n"); - uart_puts("Score: "); - print_uint8(score); + /* uart_puts("Score: "); */ + /* print_uint8(score); */ uart_puts(" \r\n"); } @@ -186,9 +192,9 @@ void main(void) { } uart_puts("\x1B[2J\x1B[H"); - uart_puts("GAME OVER score: "); - print_uint8(score); - uart_puts("\r\npress any key\r\n"); + /* uart_puts("GAME OVER score: "); */ + /* print_uint8(score); */ + /* uart_puts("\r\npress any key\r\n"); */ uart_getc(); } } @@ -9,7 +9,7 @@ Usage: import sys import argparse -DEPTH = 1024 +DEPTH = 4096 INST_BITS = 14 def parse_ihex(path): @@ -63,7 +63,7 @@ def render(words): lines.append(' process(clk)') lines.append(' begin') lines.append(' if rising_edge(clk) then') - lines.append(' data <= rom(to_integer(unsigned(addr(9 downto 0))));') + lines.append(' data <= rom(to_integer(unsigned(addr(11 downto 0))));') lines.append(' end if;') lines.append(' end process;') lines.append('end architecture rtl;') |
