⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vgachr 8080.v

📁 code guide to design cpu 8080
💻 V
📖 第 1 页 / 共 5 页
字号:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    12:02:03 10/22/2006 
// Design Name: 
// Module Name:    vgachr 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
// Simulation plugs exist in this code. Look for "????? SIMULATION PLUG"
//
// Debug plugs exist in this code. Look for "????? DEBUG PLUG"
//
//////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
//
// TERMINAL EMULATOR
//
// Emulates an ADM 3A dumb terminal, with a MITS serial I/O board interface.
// Two ports are emulated:
//
// 0: Control
// 1: Data
//
// The MITS serial card has all of its configuration performed by jumpers on the
// card, which means there is no programming configuration required. The data
// to the terminal is sent out of the data port, while the data from the 
// keyboard, which is not yet implemented, is read from the same data port.
// The parity is ignored on output, and set to 0 on input.
//
// The control register ignores all writes, and returns $80 if the terminal is
// busy, otherwise $00. This is the output ready to send bit. The busy bit
// reflects if the state machine is processing an operation. This is a cheat
// that only works with our emulated terminal/serial board pair, because 
// normally there is no way for the local CPU to know that the remote terminal
// is busy. This can lead to problems in the real world, and it's why Unix
// "termcap" terminal descriptions commonly have waiting periods perscribed
// time consuming operations like screen clear. This emulated terminal is
// "ideal" in that it accounts for all of this automatically, but it does not
// hurt the realisim of the emulation. An application that performs delays based
// on real terminal operations won't be incorrect because it performs a delay,
// but a stupid application that relies on this "smart" implementation might
// fail to run on the real thing.
//
// The ADM 3A terminal emulation is based on "ADM-3A Operators manual" of 1979,
// and "ADM 3A Dumb Terminal Users Reference Manual" of April, 1986, and the
// Unix termcap definition of the terminal.
//
// Several actions of terminals are typically not listed in the documentation,
// and the ADM 3A is no different. That's why termcap exists. The following
// actions were derived from the termcap definition:
//
// 1. The screen clear command also homes the cursor.
// 2. Giving the terminal a right cursor command while at the right side of the
// 3. Screen wraps the cursor around to the right, one line down. If the cursor
//    is at the 80th collumn of the 24th line, it will then scroll.
// 4. Down cursor (line feed) on the 24th line scrolls the screen.
//
// Note that rule (3) causes the terminal to be unable to ever write a character
// to the collumn 80 character of line 24, which is interesting if you are
// writing a full screen editor. The ADM 3A had a switch for this behavior, but
// the user could hardly be expected to open the side panel and flip this switch
// to be able to edit.
//
// The following actions are unknown:
//
// 1. A cursor left command given when the cursor is at the left side of the 
//    screen has unknown effect. According to termcap, it is not to go to the
//    end of the next line up. I have guessed here that it is to simply
//    refuse to move.
// 2. A cursor up command given when the cursor is at the top of the screen
//    has unknown effect. I have guessed here that is is to simply refuse to
//    move.
//
// These are terminal features there are no plans to implement:
//
// 1. ENQ or answerback mode. This appears to require operator setup, the manual
// does not specify any useful default value for the 32 byte answerback, 
// otherwise it might serve as sort of an early plug and play. If there is an
// application out there that uses this, I would put it in.
// 2. Bell (where would it go?).
// 3. Ctrl-N and Ctrl-O keyboard locking and extention port. I'm not sure 
// locking has a good use, nor is all that great an idea.
// 4. Any of the setup modes or features, as operated by the keyboard.
//
// Not implemented in this version:
//
// 1. Reduced intensity mode.
// 2. Graphics mode.
//
// The ADM 3A terminal will pretty much serve as an upward compatible version
// of the ASR-33 teletypes (Western Union Surplus) that were also commonly used
// in the time of the Altair. The ADM 3A was a common replacement for such
// units.
//
// Bugs/problems/issues:
//
// 1. The emulation was occasionally observed to hang. The CPU was still running
// and polling the keyboard, but no reply is received when keys are hit. The rdy
// signal is not coming from the low level keyboard logic.
// 2. Cursor left at left hand side does not refuse to move (see above).
// 3. moving to the 80th collum on line 24 and typing a character does not cause
// the screen to scroll.
// 4. On sign-on, the first two characters are missing the top row. I suspect
// this is due to the start of frame character preloading that is done.
// 5. \ESCGc or set attributes does not work from the keyboard unless you hit
// caps lock or hold the shift key down before and after the escape. It should
// work anytime the upper case G is hit.
//

//
// Terminal height and width
//
`define scnchrs 80 // width
`define scnlins 24 // height

//
// Terminal states
//
`define term_idle    5'h00 // idle
`define term_wrtstd2 5'h01 // write standard character #2
`define term_wrtstd3 5'h02 // write standard character #3
`define term_wrtstd4 5'h03 // write standard character #4
`define term_clear   5'h04 // clear screen and home cursor
`define term_clear2  5'h05 // clear screen and home cursor #2
`define term_clear3  5'h06 // clear screen and home cursor #3
`define term_clear4  5'h07 // clear screen and home cursor #4
`define term_fndstr  5'h08 // find start of current line
`define term_scroll  5'h09 // scroll screen
`define term_scroll1 5'h0a // scroll screen #1
`define term_scroll2 5'h0b // scroll screen #2
`define term_scroll3 5'h0c // scroll screen #3
`define term_scroll4 5'h0d // scroll screen #4
`define term_scroll5 5'h0e // scroll screen #5
`define term_scroll6 5'h0f // scroll screen #6
`define term_esc     5'h10 // escape
`define term_poscur  5'h11 // position cursor
`define term_poscur2 5'h12 // position cursor #2
`define term_attset  5'h13 // set screen attributes

//
// Terminal attribute bits
//
`define attr_blank   5'b00001 // blank
`define attr_blink   5'b00010 // blink
`define attr_reverse 5'b00100 // reverse
`define attr_under   5'b01000 // underline
`define attr_rinten  5'b10000 // reduced intensity

module terminal(addr, data, write, read, select, r, g, b, hsync_n, vsync_n,
                ps2_clk, ps2_data, reset, clock, diag);

   input        addr;     // control reg/data reg address
   inout [7:0]  data;     // CPU data
   input        write;    // CPU write
   input        read;     // CPU read
   input        select;   // controller select
   input        reset;    // CPU reset
   input        clock;    // CPU clock
   output [2:0] r, g, b;  // R,G,B color output buses
   output       hsync_n;  // horizontal sync pulse
   output       vsync_n;  // vertical sync pulse
   input        ps2_clk;  // clock from keyboard
   input        ps2_data; // data from keyboard
   output [7:0] diag;     // diagnostic 8 bit port

   // internal definitions
   reg [4:0]   state;   // terminal state machine
   reg [10:0]  cursor;  // cursor address
   reg [10:0]  tcursor; // cursor temp address
   reg [7:0]   chrdatw; // character write data
   reg         outrdy;  // output ready to send
   reg         wrtchr;  // character ready to write
   reg  [7:0]  datao;   // intermediate for data output
   reg  [7:0]  rowchr;  // row holding character
   reg  [4:0]  curatr;  // current attribute set

   // character map communication bus
   reg  [10:0] cmaddr;  // character map address to read or write
   reg         cmread;  // character map read from address
   reg         cmwrite; // character map write from address
   wire  [7:0] cmdata;  // character map data to be written/read
   wire  [4:0] cmattr;  // character map attributes to be written/read
   reg   [7:0] cmdatai; // character map data to be written
   reg         cmdatae; // character map data enable
   reg   [7:0] cmattri; // character map attribute to be written
   reg         cmattre; // character map attribute enable

   // keyboard communication
   wire   [7:0] scancode;   // key scancode
   wire         parity;     // keyboard parity
   wire         busy;       // busy scanning code
   wire         rdy;        // ready with code
   wire         error;      // scancode error
   reg          scnrdy;     // scancode 
   reg          extkey;     // is extended key
   reg          capslock;   // caps lock toggle
   reg          leftshift;  // state of left shift key
   reg          rightshift; // state of right shift key
   reg          leftctrl;   // state of left control key
   reg          rightctrl;  // state of right control key
   reg          relcod;     // release code active
   reg          extcod;     // extention code active
   wire   [7:0] asciidata;  // output of lookup rom
   wire   [7:0] asciidatau; // output of lookup rom
   reg          clrrdy;     // clear input ready

   // here we put signals out the diagnostic port if required.
   assign diag[0] = busy;
   assign diag[1] = rdy;
   assign diag[2] = scnrdy;
   assign diag[3] = ps2_clk;
   assign diag[4] = ps2_data;
   assign diag[5] = relcod;
   assign diag[6] = leftctrl;
   assign diag[7] = rightctrl;

   // instantiate memory mapped character display
   chrmemmap display(!reset, clock, r, g, b, hsync_n, vsync_n, cmaddr, cmread,
                     cmwrite, cmdata, cmattr, cursor);

   // instantiate ps/2 keyboard. Note that the keyboard decoder only generates
   // codes on release, which has to be changed, since we need both asserts and
   // deasserts.
   ps2_kbd vgai(.clk(clock), .rst(reset), .ps2_clk(ps2_clk), .ps2_data(ps2_data),
                .scancode(scancode), .parity(parity), .busy(busy), .rdy(rdy),
                .error(error));

   // instantiate keyboard scan lookup roms
   scnrom kbdtbl(scancode, asciidata); // lower case
   scnromu kbdtblu(scancode, asciidatau); // lower case

   // process keyboard input state
   always @(posedge clock)
      if (reset) begin // perform reset actions
   
         leftshift <= 0; // clear left shift key state
         rightshift <= 0; // clear right shift key state
         leftctrl <= 0; // clear left control key state
         rightctrl <= 0; // clear right control key state
         capslock <= 0; // clear caps lock state
         relcod <= 0; // clear release status
         scnrdy <= 0; // clear key ready
         extkey <= 0; // is an extended key

   end else begin

      if (rdy) begin

          // if the release code $f0 occurs, set release until the next key occurs
          if (scancode == 8'hf0) relcod <= 1;
          // if the extention code $e0 occurs, set the extention flag
          else if (scancode == 8'he0) extcod <= 1;
          else if (relcod) begin // release

             relcod <= 0; // reset release code
             // reset any extention code
             if (scancode != 8'hf0 && scancode != 8'he0) extcod <= 0;
             // if caps lock is hit, toggle caps lock status
             if (scancode == 8'h58) capslock <= !capslock;
             // process left and right shift key up
             if (scancode == 8'h12) leftshift <= 0; // left up
             if (scancode == 8'h59) rightshift <= 0; // right up
             // process control key up
             if (scancode == 8'h14) begin

                if (extcod) rightctrl <= 0; // right up
                else leftctrl <= 0; // left up

             end

          end else begin // assert

             scnrdy <= 1; // set key is ready
             extkey <= extcod; // set extended status of key
             // reset any extention code
             if (scancode != 8'hf0 && scancode != 8'he0) extcod <= 0;
             // process left and right shift key down
             if (scancode == 8'h12) leftshift <= 1; // left down
             if (scancode == 8'h59) rightshift <= 1; // right down
             // process control key down
             if (scancode == 8'h14) begin

                if (extcod) rightctrl <= 1; // right down
                else leftctrl <= 1; // left down

             end

          end

      end else if (clrrdy) scnrdy <= 0; // clear key ready

   end

   // process terminal emulation
   always @(posedge clock)
      if (reset) begin // reset

         // on reset, we set the state machine to perform a screen clear and
         // home cursor
         // ????? SIMULATION PLUG
         // Don't clear screen, this takes too long in simulation
         state <= `term_clear; // set to clear screen
         // state <= `term_idle; // continue
         cursor <= 0; // set cursor to home
         outrdy <= 0; // set not ready to send
         wrtchr <= 0; // set no character to write
         cmread <= 0; // clear read character
         cmwrite <= 0; // clear write character
         cmdatae <= 0; // no enable character map data
         cmattre <= 0; // no enable character map attributes
         clrrdy <= 0; // set clear ready off
         curatr <= 5'b0; // set no attributes active
                      
   end else begin

      if (write&select) begin // CPU write

         if (addr) begin
      
            chrdatw <= data & 8'h7f; // set character write data without parity
            wrtchr <= 1; // character ready to write
            outrdy <= 0; // remove ready to send
      
         end
      
      end else if (read&select) begin // CPU read
      
         if (addr) begin
      
            // Return decoded keyboard, with shifting. The letter keys, 'a'-'z',
            // can be shifted by the shift keys, but not by caps lock state.
            // The other keys can be shifted by either. This matches PC 
            // behavior, which lets you have cap locks on without shifting the
            // letter keys. The control codes are shifted as a block from `($60)
            // to ~($7e) down to $00. This leaves out \US and \DEL, but these
            // codes get generated by the DEL key.
            if (extkey) begin // its an extended key

               if (scancode == 8'h75) datao <= 8'h0b; // up
               else if (scancode == 8'h6b) datao <= 8'h08; // left
               else if (scancode == 8'h72) datao <= 8'h0a; // down
               else if (scancode == 8'h74) datao <= 8'h0c; // right

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -