瀏覽代碼

abcmem: make emulated memory configuration configurable

Let the user configure emulated memories.
H. Peter Anvin 1 年之前
父節點
當前提交
439ba5bf6b
共有 21 個文件被更改,包括 136 次插入19 次删除
  1. 17 0
      common/confenum.h
  2. 5 0
      common/sysvars.vars
  3. 二進制
      esp32/output/max80.ino.bin
  4. 62 0
      esp32/www/abcmem.html
  5. 2 1
      esp32/www/head.html
  6. 3 3
      fpga/max80.qpf
  7. 二進制
      fpga/output/bypass.jic
  8. 二進制
      fpga/output/max80.fw
  9. 二進制
      fpga/output/v1.fw
  10. 二進制
      fpga/output/v1.jic
  11. 二進制
      fpga/output/v1.sof
  12. 二進制
      fpga/output/v2.fw
  13. 二進制
      fpga/output/v2.jic
  14. 二進制
      fpga/output/v2.sof
  15. 6 3
      rv32/abcdisk.c
  16. 11 2
      rv32/abcio.h
  17. 27 9
      rv32/abcmem.c
  18. 1 1
      rv32/checksum.h
  19. 1 0
      rv32/config.h
  20. 1 0
      rv32/max80.c
  21. 二進制
      rv32/roms/ufddos800.rom

+ 17 - 0
common/confenum.h

@@ -0,0 +1,17 @@
+/*
+ * Configuration values that are enumerations
+ */
+
+#ifndef CONFENUM_H
+#define CONFENUM_H
+
+/* config.abc.hosttype */
+enum abc_hosttype {
+    ABC_AUTOCONFIG,
+    ABC_ABC80,
+    ABC_ABC80_4680,
+    ABC_ABC800CM,
+    ABC_ABC802
+};
+
+#endif /* CONFENUM_H */

+ 5 - 0
common/sysvars.vars

@@ -15,6 +15,11 @@ abc.io.rtc.enable	bool true
 abc.io.rtc.devsel	uint 54
 abc.io.pun80.enable	bool true
 abc.io.pun80.devsel	uint 60
+abc.mem.abc80.nvram	bool true
+abc.mem.abc80.ufddos	bool true
+abc.mem.abc80.pun80	bool true
+abc.mem.abc80.ram	bool true
+abc.mem.abc800.ufddos	bool true
 abc.hosttype		uint 0
 abc.netserv.host	str
 abc.netserv.port	uint 4680

二進制
esp32/output/max80.ino.bin


+ 62 - 0
esp32/www/abcmem.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <link rel="stylesheet" href="max80.css" />
+    <title class="abcbus">MAX80: ABC memories</title>
+  <script src="max80.js"></script>
+  </head>
+  <body>
+    <x-inc src="head.html"></x-inc>
+    <h1 class="abcmem">Memories</h1>
+    <form id="memconfig" class="setconfig" action="sys/setconfig" method="post"
+	  onsubmit="uploadform()" data-ref="10" data-ref-url="abcmem.html">
+      <fieldset class="abc80mem">
+	<legend>Emulated memories for ABC80</legend>
+	<label class="nvram">
+	  <b>NVRAM</b>
+	  <input type="checkbox" name="abc.mem.abc80.nvram" value="1" />
+	  <span class="help">Fake NVRAM (20-22K)</span>
+	</label>
+	<label class="ufddos">
+	  <b>UFD-DOS</b>
+	  <input type="checkbox" name="abc.mem.abc80.ufddos" value="1" />
+	  <span class="help">UFD-DOS ROM for ABC80 (24-28K)</span>
+	</label>
+	<label class="pun80">
+	  <b>PUN80</b>
+	  <input type="checkbox" name="abc.mem.abc80.pun80" value="1" />
+	  <span class="help">PUN80 network ROM for ABC80 (29-30K)</span>
+	</label>
+	<label class="ram">
+	  <b>Expansion RAM</b>
+	  <input type="checkbox" name="abc.mem.abc80.ram" value="1" />
+	  <span class="help">Expand RAM to 32K (32-48K)</span>
+	</label>
+      </fieldset>
+      <fieldset class="abc800mem">
+	<legend>Emulated memories for ABC800</legend>
+	<label class="ufddos">
+	  <b>UFD-DOS</b>
+	  <input type="checkbox" name="abc.mem.abc800.ufddos" value="1" />
+	  <span class="help">UFD-DOS ROM for ABC800 (32-48K)</span>
+	</label>
+	<p class="help">ABC800 needs jumper configuration to access external ROM.</p>
+      </fieldset>
+
+      <fieldset class="reset">
+	<legend>Reset when updating configuration</legend>
+	<label class="fpga">
+	  <b>Reset MAX80</b>
+	  <input type="checkbox" name="fpga.reset" value="1" />
+	</label>
+	<label class="abc">
+	  <b>Reset ABC</b>
+	  <input type="checkbox" name="abc.reset" value="1" />
+	</label>
+      </fieldset>
+
+      <button class="submit" type="submit" disabled>Update configuration</button>
+    </form>
+    <script>loadform('memconfig','sys/getconfig');</script>
+  </body>
+</html>

+ 2 - 1
esp32/www/head.html

@@ -6,7 +6,8 @@
 
 <nav class="navbar" role="navigation">
   <a href="status.html" class="text status">Status</a>
-  <a href="abcbus.html" class="text abcbus">ABC Bus</a>
+  <a href="abcbus.html" class="text abcbus">ABC-Bus</a>
+  <a href="abcmem.html" class="text abcmem">Memories</a>
   <a href="config.html" class="text config">Configuration</a>
   <a href="update.html" class="text update">Update</a>
   <span class="pad"></span>

+ 3 - 3
fpga/max80.qpf

@@ -19,15 +19,15 @@
 #
 # Quartus Prime
 # Version 22.1std.0 Build 915 10/25/2022 SC Lite Edition
-# Date created = 21:07:40  September 05, 2023
+# Date created = 22:08:55  September 05, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "21:07:40  September 05, 2023"
+DATE = "22:08:55  September 05, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"
 PROJECT_REVISION = "bypass"

二進制
fpga/output/bypass.jic


二進制
fpga/output/max80.fw


二進制
fpga/output/v1.fw


二進制
fpga/output/v1.jic


二進制
fpga/output/v1.sof


二進制
fpga/output/v2.fw


二進制
fpga/output/v2.jic


二進制
fpga/output/v2.sof


+ 6 - 3
rv32/abcdisk.c

@@ -439,12 +439,11 @@ static const char * const disk_pfx[] = {
 
 static void init_drives(struct ctl_state *state)
 {
-    uint32_t abc_status = ABC_STATUS;
     char *p80;
     int i;
 
     /* .80/ or .800/ for the first entry */
-    p80 = abcdisk_80_800 + 10 + !!(abc_status & ABC_STATUS_800);
+    p80 = abcdisk_80_800 + 10 + is_abc800();
     p80[0] = '0';
     p80[1] = '/';
     p80[2] = '\0';
@@ -700,7 +699,7 @@ void __hot abcdisk_io_poll(void)
 
     uint32_t now = timer_count();
     bool need_sync = false;
-    uint32_t abc_status = ABC_STATUS & (ABC_STATUS_LIVE | ABC_STATUS_800);
+    uint32_t abc_status = ABC_STATUS & ABC_STATUS_LIVE;
     bool unmount_all = false;
     bool reset_all = false;
 
@@ -726,6 +725,10 @@ void __hot abcdisk_io_poll(void)
 	last_timer = now;
     }
 
+    /* Allow configuration to override */
+    if (is_abc800())
+	abc_status |= ABC_STATUS_800;
+
     abc_status_change = abc_status ^ prev_abc_status;
     if (unlikely(abc_status_change)) {
 	const char *host;

+ 11 - 2
rv32/abcio.h

@@ -1,8 +1,8 @@
 #ifndef ABCIO_H
 #define ABCIO_H
 
-#include <stddef.h>
-#include <stdint.h>
+#include "common.h"
+#include "config.h"
 
 #define DEVSEL_NONE 64		/* No device at all selected */
 
@@ -93,6 +93,15 @@ static inline void __abc_set_inp_status(struct abc_dev *dev, uint8_t val)
     ABC_INP1_DATA = dev->inp_data[1] = val;
 }
 
+static inline bool is_abc800(void)
+{
+    unsigned long int host = getvar_uint(config_abc_hosttype);
+    if (host)
+	return host >= ABC_ABC800CM;
+    else
+	return !!(ABC_STATUS & ABC_STATUS_800);
+}
+
 void abc_register(struct abc_dev *dev, unsigned int devsel);
 void abc_init(void);
 

+ 27 - 9
rv32/abcmem.c

@@ -3,18 +3,21 @@
 #include "abcio.h"
 #include "sys.h"
 #include "console.h"
+#include "config.h"
 
 /* Configure ABC memory map */
 struct abc_mem_init {
     unsigned int addr;
     uint16_t len;
     uint8_t flags;
+    enum sysvar_enum enable;
     const char *data;		/* May not be const, but... */
 };
 #define RD (ABCMEMMAP_RD >> 24)
 #define WR (ABCMEMMAP_WR >> 24)
 
 extern const char rom_ufddos80[];
+extern const char rom_ufddos800[];
 extern const char rom_print80_29[];
 
 /* Not really NV, but matches NVRAM in some expansions */
@@ -23,22 +26,37 @@ static char __dram_bss __aligned(512) abc80_nvram[2 << 10];
 /* 16K external memory to expand to 512K */
 static char __dram_bss __aligned(512) abc80_extmem[16 << 10];
 
-static const struct abc_mem_init mem_init[] = {
-    { 0x5000,  2 << 10, RD|WR, abc80_nvram },
-    { 0x6000,  4 << 10, RD,    rom_ufddos80 },
-    { 0x7400,  1 << 10, RD,    rom_print80_29 },
-    { 0x8000, 16 << 10, RD|WR, abc80_extmem },
-    { -1U, 0, 0, NULL }
+/* These MUST be sorted! */
+static const struct abc_mem_init mem_init_abc80[] = {
+    { 0x5000,  2 << 10, RD|WR, config_abc_mem_abc80_nvram,  abc80_nvram },
+    { 0x6000,  4 << 10, RD,    config_abc_mem_abc80_ufddos, rom_ufddos80 },
+    { 0x7400,  1 << 10, RD,    config_abc_mem_abc80_pun80,  rom_print80_29 },
+    { 0x8000, 16 << 10, RD|WR, config_abc_mem_abc80_ram,    abc80_extmem },
+    { -1U, 0, 0, sysvar_null, NULL }
+};
+static const struct abc_mem_init mem_init_abc800[] = {
+    { 0x6000,  4 << 10, RD,  config_abc_mem_abc800_ufddos, rom_ufddos800 },
+    { -1U, 0, 0, sysvar_null, NULL }
 };
 
+static const struct abc_mem_init *
+get_next(const struct abc_mem_init *curr, unsigned int addr)
+{
+    while (addr >= curr->addr + curr->len ||
+	   !(!curr->enable || getvar_bool(curr->enable)))
+	curr++;
+    return curr;
+}
+
 void __cold abc_init_memmap(void)
 {
     volatile uint32_t *pg = &ABCMEMMAP_PAGE(0);
-    const struct abc_mem_init *next = &mem_init[0];
+    const struct abc_mem_init *next;
+
+    next = is_abc800() ? mem_init_abc800 : mem_init_abc80;
 
     for (unsigned int addr = 0; addr < 0x10000; addr += 512) {
-	if (addr >= next->addr + next->len)
-	    next++;
+	next = get_next(next, addr);
 
 	if (addr < next->addr) {
 	    *pg++ = 0;

+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x140405d7
+#define SDRAM_SUM 0xc47b6d97
 #endif

+ 1 - 0
rv32/config.h

@@ -4,6 +4,7 @@
 #include "compiler.h"
 #include "common.h"
 #include "sysvars.h"
+#include "confenum.h"
 
 #define CONFIG_BUFSIZE 16384
 extern char config_buf[CONFIG_BUFSIZE];

+ 1 - 0
rv32/max80.c

@@ -24,6 +24,7 @@ void __hot main(void)
 
 	if (unlikely(do_update_config)) {
 	    update_config();
+	    abc_init_memmap();
 	    rtc_abc_config();
 	    abcdisk_config();
 	    pun80_config();

二進制
rv32/roms/ufddos800.rom