Browse Source

PUN80 emulation, per-channel IRQ handlers, TTY IRQ polarity control

Add PUN80 emulation. This required two changes:

1. Support separate IRQ handlers for different TTY channels;
2. Add IRQ polarity control to the USB CDC engine.
H. Peter Anvin 3 years ago
parent
commit
1db3d07425

+ 3 - 3
fpga/max80.qpf

@@ -19,14 +19,14 @@
 #
 # Quartus Prime
 # Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 20:26:44  January 09, 2022
+# Date created = 21:44:59  January 09, 2022
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "21.1"
-DATE = "20:26:44  January 09, 2022"
+DATE = "21:44:59  January 09, 2022"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"

BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof


+ 37 - 15
fpga/usb/usb_serial/src_v/usb_cdc_core.sv

@@ -57,7 +57,8 @@
 //           9 - BREAK received (sticky, W1C)
 //          10 - USB device configured
 // 3 - RW - interrupt enable register
-//           * - mask of corresponding status bits
+//        15:0 - mask of corresponding status bits
+//       31:16 - invert polarity (0 = irq on status 1, 1 = irq on status 0)
 
 module usb_cdc_channel
   #(parameter [3:0] data_ep_num = 4'd1,
@@ -67,10 +68,10 @@ module usb_cdc_channel
    input	 rst_n,
    input	 sys_clk,
    input	 cpu_valid,
-   input [1:0]	 cpu_addr,
+   input  [1:0]	 cpu_addr,
    output [31:0] cpu_rdata,
    input [31:0]  cpu_wdata,
-   input	 cpu_wstrb,
+   input  [3:0]	 cpu_wstrb,
    output	 irq,
 
    // Core FIFO interface
@@ -106,7 +107,7 @@ module usb_cdc_channel
    always @(posedge sys_clk)
      begin
 	fifo_access_q <= fifo_access;
-	fifo_read_q   <= fifo_access & ~cpu_wstrb;
+	fifo_read_q   <= fifo_access & ~cpu_wstrb[0];
      end
 
    wire		        txempty;
@@ -119,7 +120,7 @@ module usb_cdc_channel
    cdc_fifo txfifo (
 		    .wrclk   ( sys_clk ),
 		    .data    ( cpu_wdata[7:0] ),
-		    .wrreq   ( fifo_access & ~fifo_access_q & cpu_wstrb ),
+		    .wrreq   ( fifo_access & ~fifo_access_q & cpu_wstrb[0] ),
 		    .wrempty ( txempty ),
 		    .wrfull  ( txfull ),
 		    .wrusedw ( txused ),
@@ -174,7 +175,7 @@ module usb_cdc_channel
    cdc_fifo rxfifo (
 		    .rdclk   ( sys_clk ),
 		    .q       ( rdata_fifo ),
-		    .rdreq   ( fifo_access & ~fifo_access_q & ~cpu_wstrb ),
+		    .rdreq   ( fifo_access & ~fifo_access_q & ~|cpu_wstrb ),
 		    .rdempty ( rxempty ),
 		    .rdfull  ( rxfull ),
 		    .rdusedw ( rxused ),
@@ -200,6 +201,7 @@ module usb_cdc_channel
 
    wire [15:0] status_mask = 16'b0000_0111_1111_1111; // Implemented bit mask
    reg  [15:0] irq_mask;
+   reg  [15:0] irq_pol;
    wire [ 3:0] water_mask     = 4'b1111 << (4-water_bits);
    wire [15:0] water_ctl_mask = {4{water_mask}};
    reg  [15:0] water_ctl;
@@ -218,8 +220,9 @@ module usb_cdc_channel
    always @(negedge rst_n or posedge sys_clk)
      if (~rst_n)
        begin
-	  water_ctl    <= 16'hc3c3 & water_ctl_mask;
-	  irq_mask     <= 16'b0;
+	   water_ctl    <= 16'hc3c3 & water_ctl_mask;
+irq_mask     <= 16'b0;
+	  irq_pol      <= 16'b0;
 	  recv_break_q <= 1'b0;
        end
      else
@@ -227,12 +230,31 @@ module usb_cdc_channel
 	  if (recv_break_s)
 	    recv_break_q <= 1'b1;
 
-	  if (cpu_valid & cpu_wstrb)
+	  if (cpu_valid)
 	    case (cpu_addr)
-	      2'b01: water_ctl <= cpu_wdata[15:0] & water_ctl_mask;
-	      2'b10: if (cpu_wdata[9]) recv_break_q <= 1'b0;
-	      2'b11: irq_mask  <= cpu_wdata[15:0] & status_mask;
-	      default: /* do nothing */;
+	      2'b01: begin
+		   if (cpu_wstrb[0])
+		     water_ctl[7:0] <= cpu_wdata[7:0] & water_ctl_mask[7:0];
+		   if (cpu_wstrb[1])
+		     water_ctl[15:8] <= cpu_wdata[15:8] & water_ctl_mask[15:8];
+		end
+	      2'b10: begin
+		 if (cpu_wstrb[1] & cpu_wdata[9])
+		   recv_break_q <= 1'b0;
+	      end
+	      2'b11: begin
+		 if (cpu_wstrb[0])
+		   irq_mask[7:0]  <= cpu_wdata[7:0] & status_mask[7:0];
+		 if (cpu_wstrb[1])
+		   irq_mask[15:8] <= cpu_wdata[15:8] & status_mask[15:8];
+		 if (cpu_wstrb[2])
+		   irq_pol[7:0] <= cpu_wdata[23:16] & status_mask[7:0];
+		 if (cpu_wstrb[3])
+		   irq_pol[15:8] <= cpu_wdata[31:24] & status_mask[15:8];
+	      end
+	      default: begin
+		 /* do nothing */
+	      end
 	    endcase // case (cpu_addr)
        end // else: !if(~rst_n)
 
@@ -253,14 +275,14 @@ module usb_cdc_channel
    assign status[9]    = recv_break_q;
    assign status[10]   = usb_configured;
 
-   assign irq = |(status & irq_mask);
+   assign irq = |((status ^ irq_pol) & irq_mask);
 
    always @(*)
      case (cpu_addr)
        2'b00:   cpu_rdata = { 24'b0, rdata_fifo };
        2'b01:   cpu_rdata = { 16'b0, water_ctl };
        2'b10:   cpu_rdata = { 16'b0, status };
-       2'b11:   cpu_rdata = { 16'b0, irq_mask };
+       2'b11:   cpu_rdata = { irq_pol, irq_mask };
        default: cpu_rdata = 32'bx;
      endcase // case (cpu_addr)
 

+ 1 - 0
rv32/.gitignore

@@ -6,6 +6,7 @@
 *.bin
 *.ver
 *.hex
+*.map
 *.build/
 tools/gnu/
 iodevs.h

+ 2 - 2
rv32/Makefile

@@ -47,7 +47,7 @@ max80.elf: head.o dummy.o die.o main.o system.o \
 	  irqasm.o irqtable.o spurious_irq.o sbrk.o \
 	  console.o rtc.o romcopy.o \
 	  sdcard.o diskcache.o \
-	  abcmem.o abcio.o abcdisk.o abcrtc.o \
+	  abcmem.o abcio.o abcdisk.o abcrtc.o abcpun80.o \
 	  memset.o memcpy.o \
 	  runtest.o start_test.o \
 	  $(ROMOBJS) \
@@ -58,7 +58,7 @@ testimg.elf: head.o dummy.o die.o test/main.o test/system.o \
 	  irqasm.o irqtable.o spurious_irq.o sbrk.o \
 	  console.o rtc.o romcopy.o \
 	  sdcard.o diskcache.o \
-	  abcmem.o abcio.o abcdisk.o abcrtc.o \
+	  abcmem.o abcio.o abcdisk.o abcrtc.o abcpun80.o \
 	  memset.o memcpy.o \
 	  testdata.o $(ROMOBJS) \
 	  fatfs.a

+ 1 - 1
rv32/abcio.c

@@ -42,7 +42,7 @@ void abc_select(struct abc_dev *dev)
     refresh_dev(dev);
 }
 
-IRQHANDLER(abc)
+IRQHANDLER(abc,0)
 {
     unsigned int what = ABC_BUSY_STATUS;
     struct abc_dev *dev = selected_dev;

+ 100 - 0
rv32/abcpun80.c

@@ -0,0 +1,100 @@
+/*
+ * abcpun80.c
+ *
+ * Emulate a PUN80 network card
+ */
+
+#include "compiler.h"
+#include "fw.h"
+#include "io.h"
+#include "abcio.h"
+
+#define PUN_IOSEL	60
+
+#define PUN_TTY_CHAN	1
+#if PUN_TTY_CHAN >= TTY_CHANNELS
+# error "PUN_TTY_CHAN out of range"
+#endif
+
+#define PUN_DATA	TTY_DATA(PUN_TTY_CHAN)
+#define PUN_WATERCTL	TTY_WATERCTL(PUN_TTY_CHAN)
+#define PUN_STATUS	TTY_STATUS(PUN_TTY_CHAN)
+#define PUN_IRQEN	TTY_IRQEN(PUN_TTY_CHAN)
+#define PUN_IRQPOL	TTY_IRQPOL(PUN_TTY_CHAN)
+#define PUN_IRQ		TTY_NIRQ(PUN_TTY_CHAN)
+
+#define PUN_IRQ_MASK	(TTY_STATUS_TX_FULL|TTY_STATUS_RX_EMPTY|\
+			 TTY_STATUS_USB_CONFIG)
+
+static struct abc_dev pun80_iodev;
+static __hot void pun80_refresh_input(bool advance);
+
+IRQHANDLER(tty,PUN_TTY_CHAN)
+{
+    pun80_refresh_input(false);
+}
+
+/*
+ * Convert to FT232H-compatible status codes, and advance
+ * the receive FIFO if applicable.
+ */
+static __hot void pun80_refresh_input(bool advance)
+{
+    static bool data_loaded;
+    unsigned int status;
+    unsigned int pun80_status;
+
+    status = PUN_STATUS;
+
+    if (!data_loaded || advance) {
+	data_loaded = !(status & TTY_STATUS_RX_EMPTY);
+	if (data_loaded) {
+	    abc_set_inp_default(&pun80_iodev, PUN_DATA);
+	    status = PUN_STATUS;
+	}
+    }
+
+    pun80_status = ~15;
+
+    if (status & TTY_STATUS_USB_CONFIG)
+	pun80_status |= 8;
+    if (!(status & TTY_STATUS_TX_FULL))
+	pun80_status |= 2;
+    if (data_loaded)
+	pun80_status |= 1;
+
+    abc_set_inp_status(&pun80_iodev, pun80_status);
+
+    PUN_IRQPOL = status;
+}
+
+ABC_CALLBACK(pun80_callback_out)
+{
+    PUN_DATA = data;
+    pun80_refresh_input(false);
+}
+
+ABC_CALLBACK(pun80_callback_inp)
+{
+    pun80_refresh_input(true);
+}
+
+/* The "flush" command in FT232H (C1#) is not needed with our USB stack */
+static struct abc_dev pun80_iodev = {
+    .callback_mask		= (1 << 0)|(1 << 8),
+    .inp_en			= 3,
+    .status_first_out_mask	= ~0,
+    .status_first_inp_mask	= ~0,
+    .callback_out[0]		= pun80_callback_out,
+    .callback_inp[0]		= pun80_callback_inp
+};
+
+void pun80_init(void)
+{
+    mask_irq(PUN_IRQ);
+    PUN_IRQEN = PUN_IRQ_MASK;
+    pun80_refresh_input(false);
+
+    abc_register(&pun80_iodev, PUN_IOSEL);
+    unmask_irq(PUN_IRQ);
+}

+ 262 - 205
rv32/boot.mif

@@ -54,7 +54,7 @@ CONTENT BEGIN
 002F : 5900006F;
 0030 : 3EE0006F;
 0031 : 4B60006F;
-0032 : 4B20006F;
+0032 : 2B40106F;
 0033 : 4AE0006F;
 0034 : 4AA0006F;
 0035 : 51C0006F;
@@ -63,10 +63,10 @@ CONTENT BEGIN
 0038 : 49A0006F;
 0039 : 4960006F;
 003A : 00000000;
-003B : 4101CEB0;
+003B : 4101D0B0;
 003C : FFFFFFFF;
 003D : FFFFFFFF;
-003E : 000014B4;
+003E : 00001598;
 003F : 00000040;
 0040 : 00000000;
 0041 : 00000000;
@@ -196,13 +196,13 @@ CONTENT BEGIN
 00BD : 86631860;
 00BE : 70970002;
 00BF : 80E74000;
-00C0 : 547DB580;
+00C0 : 547DB980;
 00C1 : 0680008B;
 00C2 : 0810878B;
 00C3 : 18704303;
 00C4 : 00030663;
 00C5 : 40001097;
-00C6 : 1BE080E7;
+00C6 : 1C2080E7;
 00C7 : B7DD2DD1;
 00C8 : 00000697;
 00C9 : D7C68693;
@@ -259,8 +259,8 @@ CONTENT BEGIN
 00FC : C452C64E;
 00FD : 2A73892A;
 00FE : 65053430;
-00FF : 3B050493;
-0100 : 3B050513;
+00FF : 45050493;
+0100 : 45050513;
 0101 : 00158413;
 0102 : 854A2A51;
 0103 : 98792A41;
@@ -299,10 +299,10 @@ CONTENT BEGIN
 0124 : 81002623;
 0125 : 6505BFF5;
 0126 : 05131141;
-0127 : C6063D65;
+0127 : C6064765;
 0128 : 65053799;
 0129 : 05131141;
-012A : C6063E15;
+012A : C6064815;
 012B : 02933F2D;
 012C : A7831040;
 012D : 83130002;
@@ -325,25 +325,25 @@ CONTENT BEGIN
 013E : 400075B7;
 013F : 03934401;
 0140 : 82930005;
-0141 : EF636005;
+0141 : EF636405;
 0142 : 76370453;
 0143 : 05134000;
-0144 : 2069F696;
+0144 : 2069FA96;
 0145 : 3D698522;
 0146 : 28854529;
 0147 : 400076B7;
 0148 : 40013837;
 0149 : 87934701;
-014A : 0F936006;
-014B : E063EB08;
+014A : 0F936406;
+014B : E0630B08;
 014C : C71105F7;
 014D : 400078B7;
-014E : F7F88513;
+014E : FBF88513;
 014F : 04132085;
 0150 : 4E198080;
 0151 : 20236E85;
 0152 : 851301C4;
-0153 : 20B93F5E;
+0153 : 20B9495E;
 0154 : 20234F15;
 0155 : 442201E4;
 0156 : 014140B2;
@@ -397,16 +397,16 @@ CONTENT BEGIN
 0186 : 73374000;
 0187 : 06134000;
 0188 : 03930005;
-0189 : 86336003;
+0189 : 86336403;
 018A : 458140C3;
 018B : 00050513;
 018C : 7837B761;
 018D : 3E374000;
 018E : 08934001;
-018F : 0E936008;
-0190 : 85B3EB0E;
+018F : 0E936408;
+0190 : 85B30B0E;
 0191 : 0513411E;
-0192 : BF496008;
+0192 : BF496408;
 0193 : CE061101;
 0194 : CC22CA26;
 0195 : C64EC84A;
@@ -654,11 +654,11 @@ CONTENT BEGIN
 0287 : 00597493;
 0288 : 29628D63;
 0289 : 43836305;
-028A : 0B934403;
+028A : 0B934E03;
 028B : F4130F00;
 028C : C0710013;
 028D : 40001097;
-028E : 27C080E7;
+028E : 280080E7;
 028F : 00157893;
 0290 : 00088563;
 0291 : 4A014A85;
@@ -669,45 +669,45 @@ CONTENT BEGIN
 0296 : 6C134001;
 0297 : A023002A;
 0298 : 4605018A;
-0299 : ED5C8593;
-029A : C60D0513;
+0299 : F15C8593;
+029A : E60D0513;
 029B : 40004097;
-029C : 0CA080E7;
+029C : 10A080E7;
 029D : 77B7C105;
 029E : 85134000;
-029F : 00972D07;
+029F : 00973107;
 02A0 : 80E74000;
-02A1 : A9837780;
+02A1 : A98377C0;
 02A2 : F293000A;
 02A3 : A023FFD9;
 02A4 : BF4D005A;
 02A5 : 100C0850;
-02A6 : ED5C8513;
+02A6 : F15C8513;
 02A7 : 02010023;
 02A8 : 5097CA02;
 02A9 : 80E74000;
-02AA : 4652F1A0;
+02AA : 4652F5A0;
 02AB : 40007DB7;
 02AC : 8513100C;
-02AD : 00972E9D;
+02AD : 0097329D;
 02AE : 80E74000;
-02AF : 08707400;
+02AF : 08707440;
 02B0 : 8513082C;
-02B1 : CC02ED5C;
+02B1 : CC02F15C;
 02B2 : 40005097;
-02B3 : D8C080E7;
+02B3 : DCC080E7;
 02B4 : 45E24E72;
 02B5 : 40007FB7;
 02B6 : 00AE5E83;
 02B7 : 01CE2F03;
-02B8 : 317F8513;
+02B8 : 357F8513;
 02B9 : 009E9693;
 02BA : FFEF0613;
 02BB : 40000097;
-02BC : 70A080E7;
+02BC : 70E080E7;
 02BD : 1097BF81;
 02BE : 80E74000;
-02BF : 89051680;
+02BF : 890516C0;
 02C0 : 0613F131;
 02C1 : 42181700;
 02C2 : 083346FD;
@@ -730,15 +730,15 @@ CONTENT BEGIN
 02D3 : 783700A6;
 02D4 : A0234000;
 02D5 : 051300E3;
-02D6 : 79133498;
+02D6 : 79133898;
 02D7 : 3C3D0049;
 02D8 : 16090063;
 02D9 : 400078B7;
-02DA : 2AC88513;
+02DA : 2EC88513;
 02DB : 4A923C05;
 02DC : 140A9D63;
 02DD : 40007A37;
-02DE : 2C4A0513;
+02DE : 304A0513;
 02DF : 009BC4B3;
 02E0 : 0024DC93;
 02E1 : 3C194D05;
@@ -746,11 +746,11 @@ CONTENT BEGIN
 02E3 : 4A05C06A;
 02E4 : CDB76E85;
 02E5 : 6E054000;
-02E6 : 514E8F13;
-02E7 : E00D8D13;
+02E6 : 5F8E8F13;
+02E7 : 000D8D13;
 02E8 : 4B014B81;
-02E9 : E00D8493;
-02EA : 440E0C13;
+02E9 : 000D8493;
+02EA : 4E0E0C13;
 02EB : 4F83C47A;
 02EC : 816304ED;
 02ED : 8163120A;
@@ -764,7 +764,7 @@ CONTENT BEGIN
 02F5 : 000F1863;
 02F6 : 05040513;
 02F7 : 40005097;
-02F8 : 8DE080E7;
+02F8 : 91E080E7;
 02F9 : 2AE44F83;
 02FA : FFEFF793;
 02FB : 2AF40723;
@@ -782,7 +782,7 @@ CONTENT BEGIN
 0307 : 4502040D;
 0308 : 856AC511;
 0309 : 40002097;
-030A : AC0080E7;
+030A : AC4080E7;
 030B : 49814592;
 030C : 5CDDCD8D;
 030D : 070B4821;
@@ -798,7 +798,7 @@ CONTENT BEGIN
 0317 : 22068963;
 0318 : 2097856A;
 0319 : 80E74000;
-031A : 4603A820;
+031A : 4603A860;
 031B : 1B6304ED;
 031C : 68894606;
 031D : B9088E13;
@@ -821,17 +821,17 @@ CONTENT BEGIN
 032E : 4A81B379;
 032F : B5854A01;
 0330 : 400076B7;
-0331 : 2B368513;
+0331 : 2F368513;
 0332 : 7C37B555;
 0333 : 05134000;
-0334 : B56D2B9C;
+0334 : B56D2F9C;
 0335 : F40F95E3;
 0336 : 000C4783;
 0337 : 0017F993;
 0338 : F2099FE3;
 0339 : 88002283;
 033A : 04136305;
-033B : F09351F3;
+033B : F0936033;
 033C : 95630042;
 033D : 43A20000;
 033E : 00A38413;
@@ -847,20 +847,20 @@ CONTENT BEGIN
 0348 : 874A4000;
 0349 : 00860693;
 034A : 06134591;
-034B : 85223588;
+034B : 85223988;
 034C : 40005097;
-034D : 576080E7;
+034D : 5B6080E7;
 034E : 40007737;
 034F : DA840D93;
-0350 : 45470993;
+0350 : 49470993;
 0351 : 0009A683;
 0352 : 12068463;
 0353 : 400078B7;
 0354 : 86138722;
-0355 : 05933608;
+0355 : 05933A08;
 0356 : 10080400;
 0357 : 40005097;
-0358 : 54A080E7;
+0358 : 58A080E7;
 0359 : 2AECC683;
 035A : 0016FE13;
 035B : 020E0963;
@@ -869,7 +869,7 @@ CONTENT BEGIN
 035E : 000F1763;
 035F : 4097856E;
 0360 : 80E74000;
-0361 : CF8373C0;
+0361 : CF8377C0;
 0362 : F7932AEC;
 0363 : 8723FFEF;
 0364 : 42832AFC;
@@ -886,7 +886,7 @@ CONTENT BEGIN
 036F : 856E100C;
 0370 : 4097C632;
 0371 : 80E74000;
-0372 : 4629DD40;
+0372 : 4629E140;
 0373 : 2AECC583;
 0374 : 00C51963;
 0375 : 77134832;
@@ -900,9 +900,9 @@ CONTENT BEGIN
 037D : 080E0B63;
 037E : 400079B7;
 037F : 85A21010;
-0380 : 36598513;
+0380 : 3A598513;
 0381 : 40000097;
-0382 : 3F2080E7;
+0382 : 3F6080E7;
 0383 : 02200E93;
 0384 : 00840F13;
 0385 : 2BDCA823;
@@ -910,12 +910,12 @@ CONTENT BEGIN
 0387 : 567D55FD;
 0388 : 4097856E;
 0389 : 80E74000;
-038A : C9116BA0;
+038A : C9116FA0;
 038B : 40007DB7;
 038C : 851385A2;
-038D : 0097379D;
+038D : 00973B9D;
 038E : 80E74000;
-038F : 23033C00;
+038F : 23033C40;
 0390 : AF83044D;
 0391 : A283064C;
 0392 : 5383060C;
@@ -977,7 +977,7 @@ CONTENT BEGIN
 03CA : B3813AE1;
 03CB : 1097856A;
 03CC : 80E74000;
-03CD : E90174A0;
+03CD : E90174E0;
 03CE : 02100313;
 03CF : 046D06A3;
 03D0 : 02100593;
@@ -992,11 +992,11 @@ CONTENT BEGIN
 03D9 : 856A01ED;
 03DA : 01F48933;
 03DB : 40001097;
-03DC : 6DA080E7;
+03DC : 6DE080E7;
 03DD : 00851593;
 03DE : 854A4601;
 03DF : 40004097;
-03E0 : 560080E7;
+03E0 : 5A0080E7;
 03E1 : 40A1C511;
 03E2 : 041D06A3;
 03E3 : BFB945A1;
@@ -1004,7 +1004,7 @@ CONTENT BEGIN
 03E5 : 85A21000;
 03E6 : 4097854A;
 03E7 : 80E74000;
-03E8 : F175F2C0;
+03E8 : F175F6C0;
 03E9 : 02935782;
 03EA : 9EE31000;
 03EB : B799FC57;
@@ -1043,7 +1043,7 @@ CONTENT BEGIN
 040C : 00FDFF93;
 040D : 05FD0423;
 040E : 40001097;
-040F : 678080E7;
+040F : 67C080E7;
 0410 : F793B12D;
 0411 : CB81002F;
 0412 : 04000E13;
@@ -1051,7 +1051,7 @@ CONTENT BEGIN
 0414 : 04000593;
 0415 : 856AB7C9;
 0416 : 40001097;
-0417 : 620080E7;
+0417 : 624080E7;
 0418 : 0893E901;
 0419 : 06A30210;
 041A : 0593051D;
@@ -1065,11 +1065,11 @@ CONTENT BEGIN
 0422 : 856A0062;
 0423 : 00C48CB3;
 0424 : 40001097;
-0425 : 5B6080E7;
+0425 : 5BA080E7;
 0426 : 00851593;
 0427 : 85664601;
 0428 : 40004097;
-0429 : 43C080E7;
+0429 : 47C080E7;
 042A : 0713C901;
 042B : 06A30200;
 042C : 059304ED;
@@ -1081,7 +1081,7 @@ CONTENT BEGIN
 0432 : 85662ABD;
 0433 : 409785A2;
 0434 : 80E74000;
-0435 : F971FE60;
+0435 : F9710260;
 0436 : 08135402;
 0437 : 16E31000;
 0438 : BF35FD04;
@@ -1094,7 +1094,7 @@ CONTENT BEGIN
 043F : CD890085;
 0440 : 05040513;
 0441 : 40004097;
-0442 : 1FE080E7;
+0442 : 23E080E7;
 0443 : 2AE44803;
 0444 : FF787713;
 0445 : 2AE40723;
@@ -1211,136 +1211,136 @@ CONTENT BEGIN
 04B4 : F06F6145;
 04B5 : 50B2E2EF;
 04B6 : 61455422;
-04B7 : C25D8082;
-04B8 : 0FF5F713;
-04B9 : 01071793;
-04BA : 00E7E2B3;
-04BB : 00829313;
-04BC : 00157693;
-04BD : 005363B3;
-04BE : EAC987AA;
-04BF : 71634805;
-04C0 : F89308C8;
-04C1 : 9F630027;
-04C2 : 4EFD0808;
-04C3 : 08CEF663;
-04C4 : FE060F13;
-04C5 : FE0F7F93;
-04C6 : 02078F13;
-04C7 : 01EF8733;
-04C8 : 0F13A019;
-04C9 : A023020F;
-04CA : A2230077;
-04CB : A4230077;
-04CC : A6230077;
-04CD : A8230077;
-04CE : AA230077;
-04CF : AC230077;
-04D0 : AE230077;
-04D1 : 86FA0077;
-04D2 : 1CE387FA;
-04D3 : 8A7DFDE7;
-04D4 : F363428D;
-04D5 : 031302C2;
-04D6 : 7893FFC6;
-04D7 : 8E93FFC3;
-04D8 : 8E330047;
-04D9 : A01101D8;
-04DA : A0230E91;
-04DB : 87F60076;
-04DC : 9BE386F6;
-04DD : 8A0DFFCE;
-04DE : 00267393;
-04DF : 02039063;
-04E0 : E2118A05;
-04E1 : 80238082;
-04E2 : 808200B7;
-04E3 : 00150793;
-04E4 : 00750023;
-04E5 : B79D167D;
-04E6 : BF5D86BE;
-04E7 : 00B79023;
-04E8 : BFF90789;
-04E9 : 00779023;
-04EA : 07891679;
-04EB : 0000BFB9;
-04EC : 4F525245;
-04ED : 00203A52;
-04EE : 20746120;
-04EF : 20007830;
-04F0 : 00783028;
-04F1 : 61420A29;
-04F2 : 64612064;
-04F3 : 73657264;
-04F4 : 30203A73;
-04F5 : 696D0078;
-04F6 : 696C6173;
-04F7 : 64656E67;
-04F8 : 766E6900;
-04F9 : 64696C61;
-04FA : 736E6920;
-04FB : 63757274;
-04FC : 6E6F6974;
-04FD : 2A0A0A00;
-04FE : 48202A2A;
-04FF : 6F6C6C65;
-0500 : 6F57202C;
-0501 : 21646C72;
-0502 : 2A2A2A20;
-0503 : 58414D0A;
-0504 : 66203038;
-0505 : 776D7269;
-0506 : 20657261;
-0507 : 706D6F63;
-0508 : 64656C69;
-0509 : 3A6E6F20;
-050A : 6E614A20;
-050B : 20392020;
-050C : 32323032;
-050D : 3A303220;
-050E : 353A3432;
-050F : 00000A33;
-0510 : 00000101;
-0511 : 00000000;
-0512 : 00000000;
-0513 : 00000000;
-0514 : 00000000;
-0515 : 00000000;
-0516 : 00000000;
-0517 : 00000000;
-0518 : 00000000;
-0519 : 00000000;
-051A : 00000000;
-051B : 00000000;
-051C : 00000000;
-051D : 00000000;
-051E : 00000000;
-051F : 00000000;
-0520 : 00000105;
-0521 : 00007FBF;
-0522 : 00000000;
-0523 : D3030300;
-0524 : 00001124;
-0525 : 00000000;
-0526 : 00001148;
-0527 : 00000000;
-0528 : 00000000;
-0529 : 00000000;
-052A : 00001136;
-052B : 00000000;
-052C : 00000000;
-052D : 00000000;
-052E : 00000000;
-052F : 00000000;
-0530 : 00000000;
-0531 : 00000000;
-0532 : 00000000;
-0533 : 00000000;
-0534 : 00000000;
-0535 : 00000000;
-0536 : 00000000;
-0537 : 00000000;
-0538 : 00000000;
+04B7 : 11418082;
+04B8 : C422C606;
+04B9 : C04AC226;
+04BA : 99805783;
+04BB : 19904703;
+04BC : 01079093;
+04BD : 0100D293;
+04BE : 04938416;
+04BF : 69051990;
+04C0 : C50DC311;
+04C1 : 0102F313;
+04C2 : 00133393;
+04C3 : 00748023;
+04C4 : 00031E63;
+04C5 : 99004583;
+04C6 : 55490513;
+04C7 : E40FF0EF;
+04C8 : 99805403;
+04C9 : 01041513;
+04CA : 01055413;
+04CB : 40047613;
+04CC : C21155C1;
+04CD : 769355E1;
+04CE : E2990084;
+04CF : 0025E593;
+04D0 : 0004C803;
+04D1 : 00080463;
+04D2 : 0015E593;
+04D3 : 55490513;
+04D4 : 0FF5F593;
+04D5 : E38FF0EF;
+04D6 : 01041893;
+04D7 : 0108DE13;
+04D8 : 99C01F23;
+04D9 : 442240B2;
+04DA : 49024492;
+04DB : 80820141;
+04DC : 98B00823;
+04DD : B7A54501;
+04DE : B7954505;
+04DF : B7854501;
+04E0 : F713C25D;
+04E1 : 17930FF5;
+04E2 : E2B30107;
+04E3 : 931300E7;
+04E4 : 76930082;
+04E5 : 63B30015;
+04E6 : 87AA0053;
+04E7 : 4805EAC9;
+04E8 : 08C87163;
+04E9 : 0027F893;
+04EA : 08089F63;
+04EB : F6634EFD;
+04EC : 0F1308CE;
+04ED : 7F93FE06;
+04EE : 8F13FE0F;
+04EF : 87330207;
+04F0 : A01901EF;
+04F1 : 020F0F13;
+04F2 : 0077A023;
+04F3 : 0077A223;
+04F4 : 0077A423;
+04F5 : 0077A623;
+04F6 : 0077A823;
+04F7 : 0077AA23;
+04F8 : 0077AC23;
+04F9 : 0077AE23;
+04FA : 87FA86FA;
+04FB : FDE71CE3;
+04FC : 428D8A7D;
+04FD : 02C2F363;
+04FE : FFC60313;
+04FF : FFC37893;
+0500 : 00478E93;
+0501 : 01D88E33;
+0502 : 0E91A011;
+0503 : 0076A023;
+0504 : 86F687F6;
+0505 : FFCE9BE3;
+0506 : 73938A0D;
+0507 : 90630026;
+0508 : 8A050203;
+0509 : 8082E211;
+050A : 00B78023;
+050B : 07938082;
+050C : 00230015;
+050D : 167D0075;
+050E : 86BEB79D;
+050F : 9023BF5D;
+0510 : 078900B7;
+0511 : 9023BFF9;
+0512 : 16790077;
+0513 : BFB90789;
+0514 : 4F525245;
+0515 : 00203A52;
+0516 : 20746120;
+0517 : 20007830;
+0518 : 00783028;
+0519 : 61420A29;
+051A : 64612064;
+051B : 73657264;
+051C : 30203A73;
+051D : 696D0078;
+051E : 696C6173;
+051F : 64656E67;
+0520 : 766E6900;
+0521 : 64696C61;
+0522 : 736E6920;
+0523 : 63757274;
+0524 : 6E6F6974;
+0525 : 2A0A0A00;
+0526 : 48202A2A;
+0527 : 6F6C6C65;
+0528 : 6F57202C;
+0529 : 21646C72;
+052A : 2A2A2A20;
+052B : 58414D0A;
+052C : 66203038;
+052D : 776D7269;
+052E : 20657261;
+052F : 706D6F63;
+0530 : 64656C69;
+0531 : 3A6E6F20;
+0532 : 6E614A20;
+0533 : 20392020;
+0534 : 32323032;
+0535 : 3A313220;
+0536 : 313A3233;
+0537 : 00000A32;
+0538 : 00000101;
 0539 : 00000000;
 053A : 00000000;
 053B : 00000000;
@@ -1353,9 +1353,66 @@ CONTENT BEGIN
 0542 : 00000000;
 0543 : 00000000;
 0544 : 00000000;
-0545 : 6362612F;
-0546 : 6B736964;
-0547 : 3030382E;
-0548 : 002F;
-[0549..1FFF] : 00;
+0545 : 00000000;
+0546 : 00000000;
+0547 : 00000000;
+0548 : 00000105;
+0549 : 00007FBF;
+054A : 00000000;
+054B : D3030300;
+054C : 00001124;
+054D : 00000000;
+054E : 00001148;
+054F : 00000000;
+0550 : 00000000;
+0551 : 00000000;
+0552 : 00001136;
+0553 : 00000000;
+0554 : 00000000;
+0555 : 00000000;
+0556 : 00000000;
+0557 : 00000000;
+0558 : 00000000;
+0559 : 00000101;
+055A : 0000FFFF;
+055B : 00000000;
+055C : 00030000;
+055D : 00001370;
+055E : 00000000;
+055F : 00000000;
+0560 : 00000000;
+0561 : 00000000;
+0562 : 00000000;
+0563 : 00001378;
+0564 : 00000000;
+0565 : 00000000;
+0566 : 00000000;
+0567 : 00000000;
+0568 : 00000000;
+0569 : 00000000;
+056A : 00000000;
+056B : 00000000;
+056C : 00000000;
+056D : 00000000;
+056E : 00000000;
+056F : 00000000;
+0570 : 00000000;
+0571 : 00000000;
+0572 : 00000000;
+0573 : 00000000;
+0574 : 00000000;
+0575 : 00000000;
+0576 : 00000000;
+0577 : 00000000;
+0578 : 00000000;
+0579 : 00000000;
+057A : 00000000;
+057B : 00000000;
+057C : 00000000;
+057D : 00000000;
+057E : 6362612F;
+057F : 6B736964;
+0580 : 3030382E;
+0581 : 002F;
+[0582..1FFF] : 00;
 END;

+ 2 - 0
rv32/fw.h

@@ -38,6 +38,8 @@ extern void rtc_abc_init(void);
 extern void rtc_abc_io_poll(void);
 extern void disk_cache_init(void);
 
+extern void pun80_init(void);
+
 extern uint32_t romcopy_time[2];
 extern void romcopy_download(void *, size_t, size_t);
 extern void romcopy_bzero(void *, size_t);

+ 4 - 3
rv32/ioregs.h

@@ -80,13 +80,12 @@
 #define ROMCOPY_STATUS_DONE	1
 
 #define TTY_DATA(n)		IODEVB(TTY,0+((n) << 2))
-#define TTY_WATERCTL(n)		IODEVL(TTY,1+((n) << 2))
+#define TTY_WATERCTL(n)		IODEVH0(TTY,1+((n) << 2))
 #define TTY_WATERCTL_TX_LOW(x)	((x) << 0)
 #define TTY_WATERCTL_TX_HIGH(x)	((x) << 4)
 #define TTY_WATERCTL_RX_LOW(x)	((x) << 8)
 #define TTY_WATERCTL_RX_HIGH(x)	((x) << 12)
-#define TTY_STATUS(n)		IODEVL(TTY,2+((n) << 2))
-#define TTY_IRQEN(n)		IODEVL(TTY,3+((n) << 2))
+#define TTY_STATUS(n)		IODEVH0(TTY,2+((n) << 2))
 #define TTY_STATUS_TX_EMPTY	0x0001
 #define TTY_STATUS_TX_LOW	0x0002
 #define TTY_STATUS_TX_HIGH	0x0004
@@ -98,6 +97,8 @@
 #define TTY_STATUS_RX_STALE	0x0100
 #define TTY_STATUS_RX_BREAK	0x0200
 #define TTY_STATUS_USB_CONFIG	0x0400
+#define TTY_IRQEN(n)		IODEVH0(TTY,3+((n) << 2))
+#define TTY_IRQPOL(n)		IODEVH1(TTY,3+((n) << 2))
 
 #define TTY_CHANNEL_MASK	((1U << TTY_CHANNELS) - 1)
 #define TTY_IRQ_MASK		(TTY_CHANNEL_MASK << TTY_IRQ)

+ 7 - 6
rv32/irq.h

@@ -7,12 +7,13 @@
 typedef void (*irqhandler_t)(unsigned int vector, size_t pc);
 extern irqhandler_t __irq_handler_table[];
 
-#define IRQHANDLER_DECL(x)						\
-    void irqhandler_ ##x (unsigned int vector __unused,			\
-			  size_t pc __unused)
-#define IRQHANDLER(x)				\
-    IRQHANDLER_DECL(x);				\
-    __hot __text_hot IRQHANDLER_DECL(x)
+#define IRQHANDLER_DECL(x,n)						\
+    void irqhandler_##x##_##n (unsigned int vector __unused,		\
+			       size_t pc __unused)
+
+#define IRQHANDLER(x,n)				\
+    IRQHANDLER_DECL(x,n);			\
+    __hot __text_hot IRQHANDLER_DECL(x,n)
 
 typedef unsigned int irqmask_t;
 

+ 2 - 2
rv32/irqasm.S

@@ -17,10 +17,10 @@ _irq:
 	// s10 contains the IRQ return address, s11 the mask of
 	// IRQs to be handled.
 
-	// Priority for ABC-bus I/O
+	// Fast dispatch for the ABC-bus interrupt handler
 	andi s0,s11,1 << ABC_IRQ
 	beqz s0,1f
-	jal irqhandler_abc
+	jal irqhandler_abc_0
 	sub s11,s11,s0
 	beqz s11,.L_done
 1:

+ 2 - 2
rv32/irqtable.S

@@ -8,8 +8,8 @@
 	.globl	__irq_handler_table
 __irq_handler_table:
 
-#define IRQENTRY(name,irqn,irqbase,irqcount)	\
-	j	irqhandler_ ## name
+#define IRQENTRY(name,irqbase,irqn,irqcount)	\
+	j	irqhandler_ ## name ## _ ## irqn
 
 #include "irqtable.h"
 

+ 1 - 1
rv32/romcopy.c

@@ -62,7 +62,7 @@ void __hot romcopy_bzero(void *dst, size_t len)
 }
 
 uint32_t __sbss romcopy_time[2];
-IRQHANDLER(romcopy)
+IRQHANDLER(romcopy,0)
 {
     static __sbss unsigned int romcopy_state;
     size_t len;

+ 4 - 4
rv32/spurious_irq.c

@@ -4,13 +4,13 @@
 #include "irq.h"
 
 /* Spurious interrupt; just mask it */
-IRQHANDLER(spurious)
+IRQHANDLER(spurious,0)
 {
     mask_irq(vector);
 }
 
-#define IRQENTRIES(name,irqbase,irqcount)			\
-    IRQHANDLER_DECL(name)					\
-	__attribute__((weak,alias("irqhandler_spurious")));
+#define IRQENTRY(name,irqbase,irqn,irqcount)			\
+    IRQHANDLER_DECL(name,irqn)					\
+	__attribute__((weak,alias("irqhandler_spurious_0")));
 
 #include "irqtable.h"

+ 7 - 4
rv32/system.c

@@ -54,18 +54,18 @@ static void __hot __text_hot killed(const char *how, size_t pc)
     reset(SYS_RESET_SOFT);
 }
 
-IRQHANDLER(buserr)
+IRQHANDLER(buserr,0)
 {
     killed(hotstr("misaligned"), pc);
 }
 
-IRQHANDLER(ebreak)
+IRQHANDLER(ebreak,0)
 {
     killed(hotstr("invalid instruction"), pc);
 }
 
 volatile __sbss uint32_t timer_irq_count;
-IRQHANDLER(sysclock)
+IRQHANDLER(sysclock,0)
 {
     uint32_t count = timer_irq_count;
     count++;
@@ -193,10 +193,13 @@ static void __cold __noinline late_init(void)
 
     set_leds(2);
 
-    abc_init();
+    pun80_init();
 
     set_leds(1);
 
+
+    abc_init();
+
     /* Release WAIT# if asserted */
     ABC_BUSCTL = 0;