Terminal: Add support for reading characters.
authorJoshua Wise <joshua@rebirth.joshuawise.com>
Sat, 24 Jan 2009 05:40:32 +0000 (00:40 -0500)
committerJoshua Wise <joshua@rebirth.joshuawise.com>
Sat, 24 Jan 2009 05:40:32 +0000 (00:40 -0500)
Terminal.v
testbench.cpp

index 89b19d5..dd041d0 100644 (file)
@@ -12,6 +12,8 @@ module Terminal(
        /* Terminal pretends to be cp5. */
        reg towrite = 0;
        reg [7:0] data = 0;
+       reg [8:0] indata = 0;   /* High bit is if data is present. */
+       reg didread = 0;
        
        always @(*)
        begin
@@ -19,16 +21,25 @@ module Terminal(
                data = 8'hxx;
                cp_ack = 0;
                cp_busy = 0;
+               cp_read = 0;
+               didread = 0;
                if (cp_req && (cp_rnw == 0) && (cp_insn[27:24] == 4'b1110) && (cp_insn[19:16] == 4'b0000) && (cp_insn[11:8] == 4'h5))
                begin
                        towrite = 1;
                        data = cp_write[7:0];
                        cp_ack = 1;
+               end else if (cp_req && (cp_rnw == 1) && (cp_insn[27:24] == 4'b1110) && (cp_insn[19:16] == 4'b0001) && (cp_insn[11:8] == 4'h5))
+               begin
+                       cp_read = {23'h0, indata[8:0]};
+                       cp_ack = 1;
+                       didread = cp_insn[7:5] == 1;
                end
        end
 `ifdef verilator       
        always @(posedge clk)
                if (towrite)
                        $c("{extern void term_output(unsigned char d); term_output(",data,");}");
+               else if (didread || !indata[8])
+                       indata = $c("({extern unsigned int term_input(); term_input();})");
 `endif
 endmodule
index 53be841..e89de38 100644 (file)
@@ -3,26 +3,51 @@
 #define _XOPEN_SOURCE
 #include <stdlib.h>
 #include <fcntl.h>
+#include <termios.h>
 
 Vsystem *top;
 
+int ptyfd = -1;
+
+void openpty()
+{
+       int fd = posix_openpt(O_RDWR);
+       char b[128];
+       struct termios kbdios;
+       
+       grantpt(fd);  
+       fcntl(fd, F_SETFD, 0);  /* clear close-on-exec */
+       tcgetattr(fd, &kbdios);
+       kbdios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+       tcsetattr(fd, TCSANOW, &kbdios);
+       sprintf(b, "rxvt -pty-fd %d -bg black -fg white -title \"Output terminal\" &", fd);
+       system(b);
+       unlockpt(fd);
+       ptyfd = open(ptsname(fd), O_RDWR | O_NONBLOCK);
+       close(fd);
+}
+
+unsigned int term_input()
+{
+       int rv;
+       unsigned char c;
+       if (ptyfd == -1)
+               openpty();
+       rv = read(ptyfd, &c, 1);
+       if (rv < 0)
+               return 0;
+       return 0x100 | c;
+}
+
 void term_output(unsigned char d)
 {
        int fd = posix_openpt(O_RDWR);
        static int fd2 = -1;
        char b[128];
 
-       if (fd2 == -1)
-       {
-               grantpt(fd);  
-               fcntl(fd, F_SETFD, 0);  /* clear close-on-exec */
-               sprintf(b, "rxvt -pty-fd %d -bg black -fg white -title \"Output terminal\" &", fd);
-               system(b);
-               unlockpt(fd);
-               fd2 = open(ptsname(fd), O_RDWR);
-               close(fd);
-       }
-       write(fd2, &d, 1);
+       if (ptyfd == -1)
+               openpty();
+       write(ptyfd, &d, 1);
 }
 
 unsigned int main_time = 0;
This page took 0.0215959999999999 seconds and 4 git commands to generate.