├── .gitignore
├── .jshintrc
├── .vscode
└── settings.json
├── README.md
├── al_ip
├── charattr_row.ipc
├── charattr_row.v
├── charattr_row_sim.v
├── clock.ipc
├── clock.v
├── clock_sim.v
├── cursor_ram.ipc
├── cursor_ram.v
├── cursor_ram_sim.v
├── font_ram.ipc
├── font_ram.v
├── font_ram_sim.v
├── pixels.ipc
├── pixels.v
└── pixels_sim.v
├── cursor
├── Makefile
├── cursor-cell.png
├── cursor-cell.xcf
├── cursor-crosshair.png
├── cursor-crosshair.xcf
├── cursor-default.png
├── cursor-default.xcf
├── cursor-grab.png
├── cursor-grab.xcf
├── cursor-move.png
├── cursor-move.xcf
├── cursor-not-allowed.png
├── cursor-not-allowed.xcf
├── cursor-pointer.png
├── cursor-pointer.xcf
├── cursor-wait.png
├── cursor-wait.xcf
├── cursors.mif
└── png_to_mif.py
├── demo
├── a.out
├── binary_display.py
├── binary_display.raw
├── c
│ ├── Makefile
│ ├── demo-myterminal
│ ├── demo-myterminal.c
│ ├── error_message.c
│ ├── error_message.h
│ ├── myt
│ │ ├── Makefile
│ │ ├── mytbutton.c
│ │ ├── mytbutton.h
│ │ ├── mytcheckbox.c
│ │ ├── mytcheckbox.h
│ │ ├── mytcodes.h
│ │ ├── mytframe.c
│ │ ├── mytframe.h
│ │ ├── mytprogress.c
│ │ ├── mytprogress.h
│ │ ├── mytwidget.c
│ │ └── mytwidget.h
│ ├── serial.c
│ └── serial.h
├── cat-marta-simon-pixabay-disjoint.png
├── cat-marta-simon-pixabay-disjoint.raw
├── cat-marta-simon-pixabay.png
├── cat-marta-simon-pixabay.raw
├── colors.txt
├── diagonal.py
├── init_tty.sh
├── jigsaw.py
├── js
│ ├── charpage0.png
│ ├── charpage1.png
│ ├── charpage2.png
│ ├── charpage3.png
│ ├── charpage4.png
│ ├── charpages.svg
│ ├── compile-stream.js
│ ├── demo-age-pyramid.js
│ ├── demo-colors.js
│ ├── demo-frames.js
│ ├── demo-gauges.js
│ ├── demo-hires.js
│ ├── demo-load-rawfile.js
│ ├── editor.html
│ ├── hires-image.js
│ ├── myterminal-editor.js
│ ├── myterminal-memory.js
│ ├── myterminal.js
│ ├── webserial.html
│ └── zigazou.html
├── mosaic-image.py
├── mosaic.py
├── myterminal-colors.raw
├── myterminal.png
├── panda-clker-free-vector-images-pixabay.png
├── panda-clker-free-vector-images-pixabay.raw
├── readme_size.txt
└── test_gfx.c
├── doc
├── character_attributes.png
├── character_attributes.svg
├── dawnbringer-16.gpl
├── fpga-pins.txt
├── gen_palette.py
├── layout.png
├── layout.svg
├── myterminal.png
├── myterminal.svg
├── pattern00.png
├── pattern01.png
├── pattern02.png
├── pattern03.png
├── pattern04.png
├── pattern05.png
├── pattern06.png
├── pattern07.png
├── pattern08.png
├── pattern09.png
├── pattern10.png
├── pattern11.png
├── pattern12.png
├── pattern13.png
├── pattern14.png
└── testcurses.py
├── emulator
├── Makefile
├── automaton.c
├── bitmap.c
├── bitmap.h
├── character_cell.c
├── character_cell.h
├── emulator.c
├── image_generator.c
├── image_generator.h
├── myterminal.h
├── myterminal_font.c
├── myterminal_font.h
├── png_to_c.py
├── video_memory.c
└── video_memory.h
├── falsepath.rpt
├── falsepath.tsm
├── font
├── Makefile
├── charpage-0.pdf
├── charpage-0.svg
├── charpage-1.pdf
├── charpage-2.pdf
├── charpage-3.pdf
├── charpage-4.pdf
├── charpage.pdf
├── extended_videotex.mif
├── extended_videotex.png
├── extended_videotex.svg
├── font_sim.v
├── png_to_mif.py
└── png_to_sim.py
├── myterminal.al
├── myterminal.bit
├── myterminal_devicesetting.cfg
├── myterminal_place.area
├── src
├── constant.v
├── embedded_sdram.v
├── font.v
├── four_byte.v
├── muxer.v
├── myterminal.adc
├── myterminal.sdc
├── myterminal.v
├── ps2_ascii_codes.v
├── ps2_keyboard_ascii.v
├── ps2_keyboard_state.v
├── ps2_mouse_ascii.v
├── ps2_mouse_receiver.v
├── ps2_mouse_state2.v
├── ps2_receiver.v
├── ps2_scan_code_set2_fr.v
├── register_muxer.v
├── sequence_to_bytes.v
├── serial_in.v
├── serial_out.v
├── simple_fifo.v
├── terminal_stream.v
├── terminal_stream
│ ├── attributes.v
│ └── escape_codes.v
├── test
│ ├── Makefile
│ ├── charattr_row_sim.v
│ ├── font_sim.v
│ ├── pixels_sim.v
│ ├── pua_test.py
│ ├── screen_capture.png
│ └── video_controller_tb.v
├── ts_cursor.v
├── ts_cursor.vh
├── utf8_decode.v
├── video_controller.v
├── video_controller
│ ├── ansi_palette.v
│ ├── apply_pattern.v
│ ├── cursor_ids.v
│ ├── cursor_offset.v
│ ├── gen_palette.py
│ ├── generate_pattern.v
│ ├── horizontal_resize.v
│ ├── registers.v
│ ├── ubuntu_palette.v
│ └── vertical_resize.v
├── vp_bitmap_to_pixels.v
├── vp_bitmap_to_pixels_tb.v
├── vp_gfx_bitmap.v
├── vp_gfx_bitmap_tb.v
├── vp_gfx_delay.v
├── vp_merge_bitmaps.v
├── vp_pipeline.v
├── vp_pipeline_tb.v
├── vp_text_delay.v
├── vp_text_or_gfx.v
├── vp_text_pattern.v
└── vp_text_resize.v
└── terminfo
├── Makefile
├── README.md
├── analyse_stream.py
├── bug_scroll_up.myt
├── compile_stream.py
├── dircolors
├── hello-world.myt
├── hello-world.raw
├── iso-8859-15.js
├── mouse_enable.myt
├── myterminal.ti
├── myterminal_agetty
└── myterminal_inputrc
/.gitignore:
--------------------------------------------------------------------------------
1 | myterminal_gate.area
2 | myterminal_gate.db
3 | myterminal_inst.bid
4 | myterminal_phy.area
5 | myterminal_phy.timing
6 | myterminal_phy.tsm
7 | myterminal_pr.db
8 | myterminal_rtl.area
9 | myterminal_rtl.db
10 | .myterminal.al.bak
11 | td_*.log
12 | .vscode/settings.json
13 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esversion": 9,
3 | "asi": true,
4 | "unused": true
5 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "python.pythonPath": "/usr/bin/python3"
3 | }
--------------------------------------------------------------------------------
/al_ip/charattr_row.ipc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | EG_LOGIC_BRAM
5 | EG4S20BG256
6 | false
7 | charattr_row
8 | NO
9 | NO
10 | none
11 |
12 |
13 | 9k
14 |
15 |
16 | PDPW
17 |
18 |
19 | NORMAL
20 | 128
21 | 32
22 | None
23 | enable
24 |
25 |
26 | NORMAL
27 | 128
28 | 32
29 | None
30 | disable
31 |
32 |
33 | NONE
34 |
35 |
36 |
--------------------------------------------------------------------------------
/al_ip/charattr_row.v:
--------------------------------------------------------------------------------
1 | /************************************************************\
2 | ** Copyright (c) 2011-2021 Anlogic, Inc.
3 | ** All Right Reserved.
4 | \************************************************************/
5 | /************************************************************\
6 | ** Log : This file is generated by Anlogic IP Generator.
7 | ** File : /home/fred/Documents/dev/FPGA/myterminal-5.0.5/al_ip/charattr_row.v
8 | ** Date : 2021 11 18
9 | ** TD version : 5.0.38657
10 | \************************************************************/
11 |
12 | `timescale 1ns / 1ps
13 |
14 | module charattr_row (
15 | dia, addra, cea, clka,
16 | dob, addrb, clkb
17 | );
18 |
19 |
20 | parameter DATA_WIDTH_A = 32;
21 | parameter ADDR_WIDTH_A = 7;
22 | parameter DATA_DEPTH_A = 128;
23 | parameter DATA_WIDTH_B = 32;
24 | parameter ADDR_WIDTH_B = 7;
25 | parameter DATA_DEPTH_B = 128;
26 | parameter REGMODE_A = "NOREG";
27 | parameter REGMODE_B = "NOREG";
28 | parameter WRITEMODE_A = "NORMAL";
29 | parameter WRITEMODE_B = "NORMAL";
30 |
31 | output [DATA_WIDTH_B-1:0] dob;
32 |
33 |
34 | input [DATA_WIDTH_A-1:0] dia;
35 | input [ADDR_WIDTH_A-1:0] addra;
36 | input [ADDR_WIDTH_B-1:0] addrb;
37 | input cea;
38 | input clka;
39 | input clkb;
40 |
41 |
42 |
43 | EG_LOGIC_BRAM #( .DATA_WIDTH_A(DATA_WIDTH_A),
44 | .DATA_WIDTH_B(DATA_WIDTH_B),
45 | .ADDR_WIDTH_A(ADDR_WIDTH_A),
46 | .ADDR_WIDTH_B(ADDR_WIDTH_B),
47 | .DATA_DEPTH_A(DATA_DEPTH_A),
48 | .DATA_DEPTH_B(DATA_DEPTH_B),
49 | .MODE("PDPW"),
50 | .REGMODE_A(REGMODE_A),
51 | .REGMODE_B(REGMODE_B),
52 | .WRITEMODE_A(WRITEMODE_A),
53 | .WRITEMODE_B(WRITEMODE_B),
54 | .RESETMODE("SYNC"),
55 | .IMPLEMENT("9K"),
56 | .INIT_FILE("NONE"),
57 | .FILL_ALL("NONE"))
58 | inst(
59 | .dia(dia),
60 | .dib({32{1'b0}}),
61 | .addra(addra),
62 | .addrb(addrb),
63 | .cea(cea),
64 | .ceb(1'b1),
65 | .ocea(1'b0),
66 | .oceb(1'b0),
67 | .clka(clka),
68 | .clkb(clkb),
69 | .wea(1'b1),
70 | .web(1'b0),
71 | .bea(1'b0),
72 | .beb(1'b0),
73 | .rsta(1'b0),
74 | .rstb(1'b0),
75 | .doa(),
76 | .dob(dob));
77 |
78 |
79 | endmodule
--------------------------------------------------------------------------------
/al_ip/charattr_row_sim.v:
--------------------------------------------------------------------------------
1 | // Verilog netlist created by TD v5.0.38657
2 | // Thu Nov 18 08:27:14 2021
3 |
4 | `timescale 1ns / 1ps
5 | module charattr_row // charattr_row.v(14)
6 | (
7 | addra,
8 | addrb,
9 | cea,
10 | clka,
11 | clkb,
12 | dia,
13 | dob
14 | );
15 |
16 | input [6:0] addra; // charattr_row.v(35)
17 | input [6:0] addrb; // charattr_row.v(36)
18 | input cea; // charattr_row.v(37)
19 | input clka; // charattr_row.v(38)
20 | input clkb; // charattr_row.v(39)
21 | input [31:0] dia; // charattr_row.v(34)
22 | output [31:0] dob; // charattr_row.v(31)
23 |
24 | parameter ADDR_WIDTH_A = 7;
25 | parameter ADDR_WIDTH_B = 7;
26 | parameter DATA_DEPTH_A = 128;
27 | parameter DATA_DEPTH_B = 128;
28 | parameter DATA_WIDTH_A = 32;
29 | parameter DATA_WIDTH_B = 32;
30 | parameter REGMODE_A = "NOREG";
31 | parameter REGMODE_B = "NOREG";
32 | parameter WRITEMODE_A = "NORMAL";
33 | parameter WRITEMODE_B = "NORMAL";
34 |
35 | EG_PHY_CONFIG #(
36 | .DONE_PERSISTN("ENABLE"),
37 | .INIT_PERSISTN("ENABLE"),
38 | .JTAG_PERSISTN("DISABLE"),
39 | .PROGRAMN_PERSISTN("DISABLE"))
40 | config_inst ();
41 | // address_offset=0;data_offset=0;depth=128;width=18;num_section=1;width_per_section=18;section_size=32;working_depth=512;working_width=18;working_numbyte=1;mode_ecc=0;address_step=1;bytes_in_per_section=1;
42 | EG_PHY_BRAM #(
43 | .CEAMUX("1"),
44 | .CEBMUX("1"),
45 | .CSA0("1"),
46 | .CSA1("1"),
47 | .CSA2("SIG"),
48 | .CSB0("1"),
49 | .CSB1("1"),
50 | .CSB2("1"),
51 | .DATA_WIDTH_A("18"),
52 | .DATA_WIDTH_B("18"),
53 | .MODE("PDPW8K"),
54 | .OCEAMUX("0"),
55 | .OCEBMUX("0"),
56 | .REGMODE_A("NOREG"),
57 | .REGMODE_B("NOREG"),
58 | .RESETMODE("SYNC"),
59 | .RSTAMUX("0"),
60 | .RSTBMUX("0"),
61 | .WEAMUX("1"),
62 | .WEBMUX("0"),
63 | .WRITEMODE_A("NORMAL"),
64 | .WRITEMODE_B("NORMAL"))
65 | inst_128x32_sub_000000_000 (
66 | .addra({2'b00,addra,4'b1111}),
67 | .addrb({2'b00,addrb,4'b1111}),
68 | .clka(clka),
69 | .clkb(clkb),
70 | .csa({cea,open_n49,open_n50}),
71 | .dia(dia[8:0]),
72 | .dib(dia[17:9]),
73 | .doa(dob[8:0]),
74 | .dob(dob[17:9]));
75 | // address_offset=0;data_offset=18;depth=128;width=14;num_section=1;width_per_section=14;section_size=32;working_depth=512;working_width=18;working_numbyte=1;mode_ecc=0;address_step=1;bytes_in_per_section=1;
76 | EG_PHY_BRAM #(
77 | .CEAMUX("1"),
78 | .CEBMUX("1"),
79 | .CSA0("1"),
80 | .CSA1("1"),
81 | .CSA2("SIG"),
82 | .CSB0("1"),
83 | .CSB1("1"),
84 | .CSB2("1"),
85 | .DATA_WIDTH_A("18"),
86 | .DATA_WIDTH_B("18"),
87 | .MODE("PDPW8K"),
88 | .OCEAMUX("0"),
89 | .OCEBMUX("0"),
90 | .REGMODE_A("NOREG"),
91 | .REGMODE_B("NOREG"),
92 | .RESETMODE("SYNC"),
93 | .RSTAMUX("0"),
94 | .RSTBMUX("0"),
95 | .WEAMUX("1"),
96 | .WEBMUX("0"),
97 | .WRITEMODE_A("NORMAL"),
98 | .WRITEMODE_B("NORMAL"))
99 | inst_128x32_sub_000000_018 (
100 | .addra({2'b00,addra,4'b1111}),
101 | .addrb({2'b00,addrb,4'b1111}),
102 | .clka(clka),
103 | .clkb(clkb),
104 | .csa({cea,open_n62,open_n63}),
105 | .dia(dia[26:18]),
106 | .dib({open_n67,open_n68,open_n69,open_n70,dia[31:27]}),
107 | .doa(dob[26:18]),
108 | .dob({open_n77,open_n78,open_n79,open_n80,dob[31:27]}));
109 |
110 | endmodule
111 |
112 |
--------------------------------------------------------------------------------
/al_ip/clock.ipc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PLL
5 | EG4S20BG256
6 | false
7 |
8 |
9 | Any
10 | 24.0000000000000000Mhz
11 | Normal
12 | CLKC0
13 | ENABLE
14 | ENABLE
15 |
16 |
17 | High
18 |
19 |
20 | frequncy_setting
21 | 9
22 | 2
23 |
24 |
25 | 0
26 | 9
27 | 108.0000000000000000Mhz
28 | 0.0000000000000000deg
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/al_ip/clock.v:
--------------------------------------------------------------------------------
1 | /************************************************************\
2 | ** Copyright (c) 2011-2021 Anlogic, Inc.
3 | ** All Right Reserved.
4 | \************************************************************/
5 | /************************************************************\
6 | ** Log : This file is generated by Anlogic IP Generator.
7 | ** File : /home/fred/Documents/dev/FPGA/myterminal-5.0.5/al_ip/clock.v
8 | ** Date : 2021 11 07
9 | ** TD version : 5.0.38657
10 | \************************************************************/
11 |
12 | ///////////////////////////////////////////////////////////////////////////////
13 | // Input frequency: 24.000Mhz
14 | // Clock multiplication factor: 9
15 | // Clock division factor: 2
16 | // Clock information:
17 | // Clock name | Frequency | Phase shift
18 | // C0 | 108.000000MHZ | 0 DEG
19 | ///////////////////////////////////////////////////////////////////////////////
20 | `timescale 1 ns / 100 fs
21 |
22 | module clock(refclk,
23 | reset,
24 | clk0_out);
25 |
26 | input refclk;
27 | input reset;
28 | output clk0_out;
29 |
30 | wire clk0_buf;
31 |
32 | EG_LOGIC_BUFG bufg_feedback( .i(clk0_buf), .o(clk0_out) );
33 |
34 | EG_PHY_PLL #(.DPHASE_SOURCE("DISABLE"),
35 | .DYNCFG("DISABLE"),
36 | .FIN("24.000"),
37 | .FEEDBK_MODE("NORMAL"),
38 | .FEEDBK_PATH("CLKC0_EXT"),
39 | .STDBY_ENABLE("DISABLE"),
40 | .PLLRST_ENA("ENABLE"),
41 | .SYNC_ENABLE("DISABLE"),
42 | .DERIVE_PLL_CLOCKS("ENABLE"),
43 | .GEN_BASIC_CLOCK("DISABLE"),
44 | .GMC_GAIN(0),
45 | .ICP_CURRENT(24),
46 | .KVCO(2),
47 | .LPF_CAPACITOR(2),
48 | .LPF_RESISTOR(4),
49 | .REFCLK_DIV(2),
50 | .FBCLK_DIV(9),
51 | .CLKC0_ENABLE("ENABLE"),
52 | .CLKC0_DIV(9),
53 | .CLKC0_CPHASE(8),
54 | .CLKC0_FPHASE(0) )
55 | pll_inst (.refclk(refclk),
56 | .reset(reset),
57 | .stdby(1'b0),
58 | .extlock(open),
59 | .load_reg(1'b0),
60 | .psclk(1'b0),
61 | .psdown(1'b0),
62 | .psstep(1'b0),
63 | .psclksel(3'b000),
64 | .psdone(open),
65 | .dclk(1'b0),
66 | .dcs(1'b0),
67 | .dwe(1'b0),
68 | .di(8'b00000000),
69 | .daddr(6'b000000),
70 | .do({open, open, open, open, open, open, open, open}),
71 | .fbclk(clk0_out),
72 | .clkc({open, open, open, open, clk0_buf}));
73 |
74 | endmodule
75 |
--------------------------------------------------------------------------------
/al_ip/clock_sim.v:
--------------------------------------------------------------------------------
1 | // Verilog netlist created by TD v5.0.38657
2 | // Sun Nov 7 10:42:46 2021
3 |
4 | `timescale 1ns / 1ps
5 | module clock // clock.v(22)
6 | (
7 | refclk,
8 | reset,
9 | clk0_out
10 | );
11 |
12 | input refclk; // clock.v(26)
13 | input reset; // clock.v(27)
14 | output clk0_out; // clock.v(28)
15 |
16 | wire clk0_buf; // clock.v(30)
17 |
18 | EG_PHY_GCLK bufg_feedback (
19 | .clki(clk0_buf),
20 | .clko(clk0_out)); // clock.v(32)
21 | EG_PHY_CONFIG #(
22 | .DONE_PERSISTN("ENABLE"),
23 | .INIT_PERSISTN("ENABLE"),
24 | .JTAG_PERSISTN("DISABLE"),
25 | .PROGRAMN_PERSISTN("DISABLE"))
26 | config_inst ();
27 | EG_PHY_PLL #(
28 | .CLKC0_CPHASE(8),
29 | .CLKC0_DIV(9),
30 | .CLKC0_DIV2_ENABLE("DISABLE"),
31 | .CLKC0_ENABLE("ENABLE"),
32 | .CLKC0_FPHASE(0),
33 | .CLKC1_CPHASE(1),
34 | .CLKC1_DIV(1),
35 | .CLKC1_DIV2_ENABLE("DISABLE"),
36 | .CLKC1_ENABLE("DISABLE"),
37 | .CLKC1_FPHASE(0),
38 | .CLKC2_CPHASE(1),
39 | .CLKC2_DIV(1),
40 | .CLKC2_DIV2_ENABLE("DISABLE"),
41 | .CLKC2_ENABLE("DISABLE"),
42 | .CLKC2_FPHASE(0),
43 | .CLKC3_CPHASE(1),
44 | .CLKC3_DIV(1),
45 | .CLKC3_DIV2_ENABLE("DISABLE"),
46 | .CLKC3_ENABLE("DISABLE"),
47 | .CLKC3_FPHASE(0),
48 | .CLKC4_CPHASE(1),
49 | .CLKC4_DIV(1),
50 | .CLKC4_DIV2_ENABLE("DISABLE"),
51 | .CLKC4_ENABLE("DISABLE"),
52 | .CLKC4_FPHASE(0),
53 | .DERIVE_PLL_CLOCKS("ENABLE"),
54 | .DPHASE_SOURCE("DISABLE"),
55 | .DYNCFG("DISABLE"),
56 | .FBCLK_DIV(9),
57 | .FEEDBK_MODE("NORMAL"),
58 | .FEEDBK_PATH("CLKC0_EXT"),
59 | .FIN("24.000"),
60 | .FREQ_LOCK_ACCURACY(2),
61 | .GEN_BASIC_CLOCK("DISABLE"),
62 | .GMC_GAIN(0),
63 | .GMC_TEST(14),
64 | .ICP_CURRENT(24),
65 | .IF_ESCLKSTSW("DISABLE"),
66 | .INTFB_WAKE("DISABLE"),
67 | .KVCO(2),
68 | .LPF_CAPACITOR(2),
69 | .LPF_RESISTOR(4),
70 | .NORESET("DISABLE"),
71 | .ODIV_MUXC0("DIV"),
72 | .ODIV_MUXC1("DIV"),
73 | .ODIV_MUXC2("DIV"),
74 | .ODIV_MUXC3("DIV"),
75 | .ODIV_MUXC4("DIV"),
76 | .PLLC2RST_ENA("DISABLE"),
77 | .PLLC34RST_ENA("DISABLE"),
78 | .PLLMRST_ENA("DISABLE"),
79 | .PLLRST_ENA("ENABLE"),
80 | .PLL_LOCK_MODE(0),
81 | .PREDIV_MUXC0("VCO"),
82 | .PREDIV_MUXC1("VCO"),
83 | .PREDIV_MUXC2("VCO"),
84 | .PREDIV_MUXC3("VCO"),
85 | .PREDIV_MUXC4("VCO"),
86 | .REFCLK_DIV(2),
87 | .REFCLK_SEL("INTERNAL"),
88 | .STDBY_ENABLE("DISABLE"),
89 | .STDBY_VCO_ENA("DISABLE"),
90 | .SYNC_ENABLE("DISABLE"),
91 | .VCO_NORESET("DISABLE"))
92 | pll_inst (
93 | .daddr(6'b000000),
94 | .dclk(1'b0),
95 | .dcs(1'b0),
96 | .di(8'b00000000),
97 | .dwe(1'b0),
98 | .fbclk(clk0_out),
99 | .load_reg(1'b0),
100 | .psclk(1'b0),
101 | .psclksel(3'b000),
102 | .psdown(1'b0),
103 | .psstep(1'b0),
104 | .refclk(refclk),
105 | .reset(reset),
106 | .stdby(1'b0),
107 | .clkc({open_n47,open_n48,open_n49,open_n50,clk0_buf})); // clock.v(55)
108 |
109 | endmodule
110 |
111 |
--------------------------------------------------------------------------------
/al_ip/cursor_ram.ipc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ROM
5 | EG4S20BG256
6 | false
7 | cursor_ram
8 | false
9 | true
10 |
11 |
12 | 9k
13 |
14 |
15 | SP
16 |
17 |
18 | 384
19 | 16
20 | None
21 |
22 |
23 | true
24 | ../cursor/cursors.mif
25 |
26 |
27 | NONE
28 |
29 |
30 |
--------------------------------------------------------------------------------
/al_ip/cursor_ram.v:
--------------------------------------------------------------------------------
1 | /************************************************************\
2 | ** Copyright (c) 2011-2021 Anlogic, Inc.
3 | ** All Right Reserved.
4 | \************************************************************/
5 | /************************************************************\
6 | ** Log : This file is generated by Anlogic IP Generator.
7 | ** File : /home/fred/Documents/dev/FPGA/myterminal-backport/al_ip/cursor_ram.v
8 | ** Date : 2021 05 31
9 | ** TD version : 4.6.25304
10 | \************************************************************/
11 |
12 | `timescale 1ns / 1ps
13 |
14 | module cursor_ram ( doa, addra, clka, rsta );
15 |
16 | output [15:0] doa;
17 |
18 | input [8:0] addra;
19 | input clka;
20 | input rsta;
21 |
22 |
23 |
24 |
25 | EG_LOGIC_BRAM #( .DATA_WIDTH_A(16),
26 | .ADDR_WIDTH_A(9),
27 | .DATA_DEPTH_A(384),
28 | .DATA_WIDTH_B(16),
29 | .ADDR_WIDTH_B(9),
30 | .DATA_DEPTH_B(384),
31 | .MODE("SP"),
32 | .REGMODE_A("NOREG"),
33 | .RESETMODE("SYNC"),
34 | .IMPLEMENT("9K"),
35 | .DEBUGGABLE("NO"),
36 | .PACKABLE("YES"),
37 | .INIT_FILE("../cursor/cursors.mif"),
38 | .FILL_ALL("NONE"))
39 | inst(
40 | .dia({16{1'b0}}),
41 | .dib({16{1'b0}}),
42 | .addra(addra),
43 | .addrb({9{1'b0}}),
44 | .cea(1'b1),
45 | .ceb(1'b0),
46 | .ocea(1'b0),
47 | .oceb(1'b0),
48 | .clka(clka),
49 | .clkb(1'b0),
50 | .wea(1'b0),
51 | .web(1'b0),
52 | .bea(1'b0),
53 | .beb(1'b0),
54 | .rsta(rsta),
55 | .rstb(1'b0),
56 | .doa(doa),
57 | .dob());
58 |
59 |
60 | endmodule
--------------------------------------------------------------------------------
/al_ip/cursor_ram_sim.v:
--------------------------------------------------------------------------------
1 | // Verilog netlist created by TD v4.6.25304
2 | // Mon May 31 15:09:41 2021
3 |
4 | `timescale 1ns / 1ps
5 | module cursor_ram // al_ip/cursor_ram.v(14)
6 | (
7 | addra,
8 | clka,
9 | rsta,
10 | doa
11 | );
12 |
13 | input [8:0] addra; // al_ip/cursor_ram.v(18)
14 | input clka; // al_ip/cursor_ram.v(19)
15 | input rsta; // al_ip/cursor_ram.v(20)
16 | output [15:0] doa; // al_ip/cursor_ram.v(16)
17 |
18 |
19 | EG_PHY_CONFIG #(
20 | .DONE_PERSISTN("ENABLE"),
21 | .INIT_PERSISTN("ENABLE"),
22 | .JTAG_PERSISTN("DISABLE"),
23 | .PROGRAMN_PERSISTN("DISABLE"))
24 | config_inst ();
25 | // address_offset=0;data_offset=0;depth=384;width=16;num_section=1;width_per_section=16;section_size=16;working_depth=512;working_width=18;address_step=1;bytes_in_per_section=1;
26 | EG_PHY_BRAM #(
27 | .CEAMUX("0"),
28 | .CEBMUX("1"),
29 | .CSA0("1"),
30 | .CSA1("1"),
31 | .CSA2("1"),
32 | .CSB0("1"),
33 | .CSB1("1"),
34 | .CSB2("1"),
35 | .DATA_WIDTH_A("18"),
36 | .DATA_WIDTH_B("18"),
37 | .INITP_00(256'h0555555555555550000005000000011511111110044000100400400000001000),
38 | .INITP_01(256'h0000011400000000040114004110400000555554010000011444444500000000),
39 | .INITP_02(256'h0000000000000500005000000000000000000005050000000000000000000500),
40 | .INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
41 | .INIT_00(256'h000075AB000075AC000075B0000075C000007500000076000000780000006000),
42 | .INIT_01(256'h600075AA5FFC75AA55B075AA55C075AA550075AA560075AA580075AA600075AA),
43 | .INIT_02(256'h1E000000750000007500000056006003560078035800760E5800750E600075FA),
44 | .INIT_03(256'h000001AC000001AC000001AC000001AC000001AC000001AC000001AC000000F0),
45 | .INIT_04(256'h55AB1DAA55AB75AA55AB75AA55AB75AA55AB75AA5DEB75AE5DEC1DAE673007AF),
46 | .INIT_05(256'h00000000000000000000000000000000000000007FFC07FF55AC07AA55AB1DAA),
47 | .INIT_06(256'h2A7F7E552A7F7E557FFF7FFF7FFC1FFF7FFC1FFF7FF007FF7FC001FF7E00003F),
48 | .INIT_07(256'h7E00003F7FC001FF7FF007FF7FFC1FFF7FFC1FFF7FFF7FFF2A7F7E552A7F7E55),
49 | .INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000),
50 | .INIT_09(256'h2E00066A55001DAA55001DAA55001DAA55001DAA55001DAA55001DAA7FC07FFF),
51 | .INIT_0A(256'h560007A6580001AA600000EA0000003B0000000C00000037600000D538000155),
52 | .INIT_0B(256'h00000000000000007FC07FFF2B001A552B001A552B001A552D001C5535001D55),
53 | .INIT_0C(256'h5FAC1DFE58F0070E58C0010E5800000E5F0000FE5600003A5800000E60000003),
54 | .INIT_0D(256'h5600003A5F0000FE5800000E58C0010E58F0070E5FAC1DFE55AB75AA55AB75AA),
55 | .INIT_0E(256'h000000000000000000000000000000000000000000000000600000035800000E),
56 | .INIT_0F(256'h55AB1DAA55AB75AA55AB75AA55AB75AA55AB75AA5DEB75AE5DEC1DAE673006F3),
57 | .INIT_10(256'h00000000000000000000000000000000000000007FFC07FF55AC07AA55AB1DAA),
58 | .INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000),
59 | .INIT_12(256'h1DAC75B007F01FC0000000036000000E6000000E6000000E6000000E00000003),
60 | .INIT_13(256'h00000000000000036000000E6000000E6000000E6000000E0000000307F01FC0),
61 | .INIT_14(256'h0000000000000000000000000000000000000000000000000000000000000000),
62 | .INIT_15(256'h55AB75AA55AB75AA57FC1FFA5600003A5600003A5600003A5600003A7800000F),
63 | .INIT_16(256'h7800000F5600003A5600003A5600003A5600003A57FC1FFA55AB75AA55AB75AA),
64 | .INIT_17(256'h0000000000000000000000000000000000000000000000000000000000000000),
65 | .INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000),
66 | .INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000),
67 | .INIT_1A(256'h0000000000000000000000000000000000000000000000000000000000000000),
68 | .INIT_1B(256'h0000000000000000000000000000000000000000000000000000000000000000),
69 | .INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000),
70 | .INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000),
71 | .INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000),
72 | .INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000),
73 | .MODE("PDPW8K"),
74 | .OCEAMUX("0"),
75 | .OCEBMUX("0"),
76 | .REGMODE_A("NOREG"),
77 | .REGMODE_B("NOREG"),
78 | .RESETMODE("SYNC"),
79 | .WEAMUX("1"),
80 | .WEBMUX("0"),
81 | .WRITEMODE_A("NORMAL"),
82 | .WRITEMODE_B("NORMAL"))
83 | inst_384x16_sub_000000_000 (
84 | .addra({addra,4'b1111}),
85 | .addrb({addra,4'b1111}),
86 | .clka(clka),
87 | .clkb(clka),
88 | .dia(9'b000000000),
89 | .dib({open_n55,open_n56,7'b0000000}),
90 | .rsta(rsta),
91 | .rstb(rsta),
92 | .doa(doa[8:0]),
93 | .dob({open_n61,open_n62,doa[15:9]}));
94 |
95 | endmodule
96 |
97 |
--------------------------------------------------------------------------------
/al_ip/font_ram.ipc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | EG_LOGIC_BRAM
5 | EG4S20BG256
6 | false
7 | font_ram
8 | NO
9 | NO
10 | none
11 |
12 |
13 | 32k
14 |
15 |
16 | SP
17 |
18 |
19 | NORMAL
20 | 20480
21 | 16
22 | RegWithoutOre
23 | disable
24 |
25 |
26 | ../font/extended_videotex.mif
27 |
28 |
29 | NONE
30 |
31 |
32 |
--------------------------------------------------------------------------------
/al_ip/font_ram.v:
--------------------------------------------------------------------------------
1 | /************************************************************\
2 | ** Copyright (c) 2011-2021 Anlogic, Inc.
3 | ** All Right Reserved.
4 | \************************************************************/
5 | /************************************************************\
6 | ** Log : This file is generated by Anlogic IP Generator.
7 | ** File : /home/fred/Documents/dev/FPGA/myterminal-5.0.5/al_ip/font_ram.v
8 | ** Date : 2021 11 16
9 | ** TD version : 5.0.38657
10 | \************************************************************/
11 |
12 | `timescale 1ns / 1ps
13 |
14 | module font_ram ( doa, dia, addra, clka, wea, rsta );
15 |
16 |
17 | parameter DATA_WIDTH_A = 16;
18 | parameter ADDR_WIDTH_A = 15;
19 | parameter DATA_DEPTH_A = 20480;
20 | parameter DATA_WIDTH_B = 16;
21 | parameter ADDR_WIDTH_B = 15;
22 | parameter DATA_DEPTH_B = 20480;
23 | parameter REGMODE_A = "OUTREG";
24 | parameter WRITEMODE_A = "NORMAL";
25 |
26 | output [DATA_WIDTH_A-1:0] doa;
27 |
28 | input [DATA_WIDTH_A-1:0] dia;
29 | input [ADDR_WIDTH_A-1:0] addra;
30 | input wea;
31 | input clka;
32 | input rsta;
33 |
34 |
35 |
36 |
37 | EG_LOGIC_BRAM #( .DATA_WIDTH_A(DATA_WIDTH_A),
38 | .ADDR_WIDTH_A(ADDR_WIDTH_A),
39 | .DATA_DEPTH_A(DATA_DEPTH_A),
40 | .DATA_WIDTH_B(DATA_WIDTH_B),
41 | .ADDR_WIDTH_B(ADDR_WIDTH_B),
42 | .DATA_DEPTH_B(DATA_DEPTH_B),
43 | .MODE("SP"),
44 | .REGMODE_A(REGMODE_A),
45 | .WRITEMODE_A(WRITEMODE_A),
46 | .RESETMODE("SYNC"),
47 | .IMPLEMENT("32K"),
48 | .DEBUGGABLE("NO"),
49 | .PACKABLE("NO"),
50 | .INIT_FILE("../font/extended_videotex.mif"),
51 | .FILL_ALL("NONE"))
52 | inst(
53 | .dia(dia),
54 | .dib({16{1'b0}}),
55 | .addra(addra),
56 | .addrb({15{1'b0}}),
57 | .cea(1'b1),
58 | .ceb(1'b0),
59 | .ocea(1'b1),
60 | .oceb(1'b0),
61 | .clka(clka),
62 | .clkb(1'b0),
63 | .wea(wea),
64 | .web(1'b0),
65 | .bea(1'b0),
66 | .beb(1'b0),
67 | .rsta(rsta),
68 | .rstb(1'b0),
69 | .doa(doa),
70 | .dob());
71 |
72 |
73 | endmodule
--------------------------------------------------------------------------------
/al_ip/pixels.ipc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | EG_LOGIC_BRAM
5 | EG4S20BG256
6 | false
7 | pixels
8 | NO
9 | NO
10 | none
11 |
12 |
13 | 9k
14 |
15 |
16 | PDPW
17 |
18 |
19 | NORMAL
20 | 128
21 | 64
22 | None
23 | enable
24 |
25 |
26 | NORMAL
27 | 2048
28 | 4
29 | None
30 | disable
31 |
32 |
33 | NONE
34 |
35 |
36 |
--------------------------------------------------------------------------------
/al_ip/pixels.v:
--------------------------------------------------------------------------------
1 | /************************************************************\
2 | ** Copyright (c) 2011-2021 Anlogic, Inc.
3 | ** All Right Reserved.
4 | \************************************************************/
5 | /************************************************************\
6 | ** Log : This file is generated by Anlogic IP Generator.
7 | ** File : /home/fred/Documents/dev/FPGA/myterminal-5.0.5/al_ip/pixels.v
8 | ** Date : 2021 11 18
9 | ** TD version : 5.0.38657
10 | \************************************************************/
11 |
12 | `timescale 1ns / 1ps
13 |
14 | module pixels (
15 | dia, addra, cea, clka,
16 | dob, addrb, clkb
17 | );
18 |
19 |
20 | parameter DATA_WIDTH_A = 64;
21 | parameter ADDR_WIDTH_A = 7;
22 | parameter DATA_DEPTH_A = 128;
23 | parameter DATA_WIDTH_B = 4;
24 | parameter ADDR_WIDTH_B = 11;
25 | parameter DATA_DEPTH_B = 2048;
26 | parameter REGMODE_A = "NOREG";
27 | parameter REGMODE_B = "NOREG";
28 | parameter WRITEMODE_A = "NORMAL";
29 | parameter WRITEMODE_B = "NORMAL";
30 |
31 | output [DATA_WIDTH_B-1:0] dob;
32 |
33 |
34 | input [DATA_WIDTH_A-1:0] dia;
35 | input [ADDR_WIDTH_A-1:0] addra;
36 | input [ADDR_WIDTH_B-1:0] addrb;
37 | input cea;
38 | input clka;
39 | input clkb;
40 |
41 |
42 |
43 | EG_LOGIC_BRAM #( .DATA_WIDTH_A(DATA_WIDTH_A),
44 | .DATA_WIDTH_B(DATA_WIDTH_B),
45 | .ADDR_WIDTH_A(ADDR_WIDTH_A),
46 | .ADDR_WIDTH_B(ADDR_WIDTH_B),
47 | .DATA_DEPTH_A(DATA_DEPTH_A),
48 | .DATA_DEPTH_B(DATA_DEPTH_B),
49 | .MODE("PDPW"),
50 | .REGMODE_A(REGMODE_A),
51 | .REGMODE_B(REGMODE_B),
52 | .WRITEMODE_A(WRITEMODE_A),
53 | .WRITEMODE_B(WRITEMODE_B),
54 | .RESETMODE("SYNC"),
55 | .IMPLEMENT("9K"),
56 | .INIT_FILE("NONE"),
57 | .FILL_ALL("NONE"))
58 | inst(
59 | .dia(dia),
60 | .dib({4{1'b0}}),
61 | .addra(addra),
62 | .addrb(addrb),
63 | .cea(cea),
64 | .ceb(1'b1),
65 | .ocea(1'b0),
66 | .oceb(1'b0),
67 | .clka(clka),
68 | .clkb(clkb),
69 | .wea(1'b1),
70 | .web(1'b0),
71 | .bea(1'b0),
72 | .beb(1'b0),
73 | .rsta(1'b0),
74 | .rstb(1'b0),
75 | .doa(),
76 | .dob(dob));
77 |
78 |
79 | endmodule
--------------------------------------------------------------------------------
/cursor/Makefile:
--------------------------------------------------------------------------------
1 | cursor.mif: cursor-default.png cursor-pointer.png cursor-not-allowed.png cursor-wait.png cursor-move.png cursor-grab.png cursor-crosshair.png cursor-cell.png
2 | python3 png_to_mif.py
3 |
4 | clean:
5 | rm -f cursor.mif
6 |
--------------------------------------------------------------------------------
/cursor/cursor-cell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-cell.png
--------------------------------------------------------------------------------
/cursor/cursor-cell.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-cell.xcf
--------------------------------------------------------------------------------
/cursor/cursor-crosshair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-crosshair.png
--------------------------------------------------------------------------------
/cursor/cursor-crosshair.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-crosshair.xcf
--------------------------------------------------------------------------------
/cursor/cursor-default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-default.png
--------------------------------------------------------------------------------
/cursor/cursor-default.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-default.xcf
--------------------------------------------------------------------------------
/cursor/cursor-grab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-grab.png
--------------------------------------------------------------------------------
/cursor/cursor-grab.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-grab.xcf
--------------------------------------------------------------------------------
/cursor/cursor-move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-move.png
--------------------------------------------------------------------------------
/cursor/cursor-move.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-move.xcf
--------------------------------------------------------------------------------
/cursor/cursor-not-allowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-not-allowed.png
--------------------------------------------------------------------------------
/cursor/cursor-not-allowed.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-not-allowed.xcf
--------------------------------------------------------------------------------
/cursor/cursor-pointer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-pointer.png
--------------------------------------------------------------------------------
/cursor/cursor-pointer.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-pointer.xcf
--------------------------------------------------------------------------------
/cursor/cursor-wait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-wait.png
--------------------------------------------------------------------------------
/cursor/cursor-wait.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/cursor/cursor-wait.xcf
--------------------------------------------------------------------------------
/cursor/png_to_mif.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from PIL import Image
3 |
4 | # Generate a MIF file containing the cursors ROM.
5 | # The MIF file can then be used as an initialization file for FPGA project.
6 |
7 | # Cursor dimensions
8 | CURSOR_HEIGHT = 24
9 | CURSOR_WIDTH = 16
10 |
11 | CURSOR_COUNT = 8
12 |
13 | # Bitmap dimension
14 | GRID_WIDTH = 16
15 | GRID_HEIGHT = 384
16 |
17 | def getvalue(rgbs, x, y):
18 | r, _, _, a = rgbs.getpixel((x, y))
19 | if a == 0:
20 | return (0, 0)
21 | elif r == 0:
22 | return (0, 1)
23 | elif r == 0x80:
24 | return (1, 0)
25 | else:
26 | return (1, 1)
27 |
28 | def getcharwords(rgbs):
29 | words = []
30 |
31 | for y in range(CURSOR_HEIGHT):
32 | word = 0
33 | for i in range(0, CURSOR_WIDTH // 2):
34 | x = i
35 | word += getvalue(rgbs, x, y)[0] << (CURSOR_WIDTH - 2 - (i * 2))
36 | word += getvalue(rgbs, x, y)[1] << (CURSOR_WIDTH - 1 - (i * 2))
37 |
38 | words.append(word)
39 |
40 | word = 0
41 | for i in range(0, CURSOR_WIDTH // 2):
42 | x = CURSOR_WIDTH // 2 + i
43 | word += getvalue(rgbs, x, y)[0] << (CURSOR_WIDTH - 2 - (i * 2))
44 | word += getvalue(rgbs, x, y)[1] << (CURSOR_WIDTH - 1 - (i * 2))
45 |
46 | words.append(word)
47 |
48 | return words
49 |
50 | # Load the image
51 |
52 | cursor_files = [
53 | "cursor-default.png",
54 | "cursor-pointer.png",
55 | "cursor-not-allowed.png",
56 | "cursor-wait.png",
57 | "cursor-move.png",
58 | "cursor-grab.png",
59 | "cursor-crosshair.png",
60 | "cursor-cell.png",
61 | ]
62 |
63 | with open('cursors.mif', 'w') as f:
64 | f.write("DEPTH = {};\n".format(CURSOR_HEIGHT * CURSOR_COUNT * 2))
65 | f.write("WIDTH = {};\n\n".format(CURSOR_WIDTH))
66 |
67 | f.write("ADDRESS_RADIX = HEX;\n")
68 | f.write("DATA_RADIX = BIN;\n\n")
69 |
70 | f.write("CONTENT\n")
71 | f.write("BEGIN\n")
72 |
73 | offset = 0
74 | for cursor_file in cursor_files:
75 | cursor = Image.open(cursor_file)
76 |
77 | # Convert the image to RGB
78 | rgbs = cursor.convert('RGBA')
79 |
80 | allwords = []
81 | for word in getcharwords(rgbs):
82 | allwords.append(word)
83 |
84 | f.write("-- Cursor {}\n".format(cursor_file))
85 | for word in allwords:
86 | f.write("{}: {};\n".format(
87 | hex(offset)[2:].rjust(6, "0"),
88 | bin(word)[2:].rjust(CURSOR_WIDTH, "0")
89 | ))
90 |
91 | offset += 1
92 |
93 | f.write("END;\n")
94 |
--------------------------------------------------------------------------------
/demo/a.out:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/a.out
--------------------------------------------------------------------------------
/demo/binary_display.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import random
3 | import sys
4 | from time import sleep
5 |
6 | def myt_print(string):
7 | if type(string) is bytes:
8 | sys.stdout.buffer.write(string)
9 | elif type(string) is list:
10 | sys.stdout.buffer.write(bytes(string))
11 | elif type(string) is str:
12 | sys.stdout.buffer.write(string.encode(MYT))
13 |
14 | MYT = 'ISO-8859-15'
15 | CHARPAGES = [ b'\x13', b'\x14', b'\x15', b'\x16', b'\x17' ]
16 |
17 | def cls():
18 | myt_print([ 0x01, 0x21 ])
19 |
20 | def set_foreground(color):
21 | myt_print([ 0x02, 0x40 + color ])
22 |
23 | def set_background(color):
24 | myt_print([ 0x02, 0x50 + color ])
25 |
26 | def locate(x, y):
27 | myt_print([ 0x04, 0x30 + y, 0x30 + x ])
28 |
29 | UNDERLINE_ON = "U"
30 | UNDERLINE_OFF = "u"
31 | BLINK_ON = "B"
32 | BLINK_OFF = "b"
33 | REVERSE_ON = "R"
34 | REVERSE_OFF = "r"
35 | SIZE_NORMAL = "0"
36 | SIZE_DBLWIDTH = "1"
37 | SIZE_DBLHEIGHT = "2"
38 | SIZE_DOUBLE = "3"
39 | def attribute(value):
40 | myt_print(chr(0x05) + value)
41 |
42 | def titlebar(title):
43 | set_foreground(0)
44 | set_background(15)
45 |
46 | myt_print(
47 | b'\x174\x13' +
48 | (title + " | MyTerminal").ljust(78).encode(MYT) +
49 | b'\x171\x13'
50 | )
51 |
52 | set_foreground(15)
53 | set_background(0)
54 |
55 | def binary(number, length):
56 | images = {
57 | '00': 0xA4,
58 | '01': 0xA5,
59 | '10': 0xA6,
60 | '11': 0xA7,
61 | '0': 0xAA,
62 | '1': 0xAB
63 | }
64 |
65 | number = number & (2 ** length - 1)
66 | bits_string = bin(number)[2:].rjust(length, '0')
67 | myt_print(b'\x14')
68 | myt_print([ images[bits_string[i:i+2]] for i in range(0, length, 2) ])
69 | myt_print(b'\x13')
70 |
71 | cls()
72 | titlebar("Démo : nombres binaires")
73 | locate(1, 2)
74 |
75 | attribute(SIZE_DOUBLE)
76 | myt_print("Liste des nombres sur 8 bits : ")
77 | attribute(SIZE_NORMAL)
78 |
79 | for number in range(256):
80 | locate(1 + 10 * (number // 32), 5 + number % 32)
81 | set_foreground(14)
82 | myt_print(str(number).rjust(3) + ":")
83 | set_foreground(13)
84 | binary(number, 8)
85 |
86 | locate(0, 40)
87 | sys.stdout.flush()
88 |
--------------------------------------------------------------------------------
/demo/binary_display.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/binary_display.raw
--------------------------------------------------------------------------------
/demo/c/Makefile:
--------------------------------------------------------------------------------
1 | CC=gcc
2 | CFLAGS=-Wall -Os -std=gnu99 -s -fno-stack-protector -ffunction-sections -fdata-sections -Wl,--gc-sections -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-math-errno -fno-ident -fmerge-all-constants -ffast-math -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none
3 | LDFLAGS=
4 | EXEC=demo-myterminal
5 |
6 | ALL: $(EXEC)
7 |
8 | %.o: %.c %.h
9 | $(CC) $(CFLAGS) -o $@ -c $<
10 |
11 | error_message.o:
12 | serial.o: error_message.o
13 |
14 | demo-myterminal: demo-myterminal.c error_message.o serial.o myt/mytbutton.o myt/mytwidget.o myt/mytcodes.h myt/mytcheckbox.o myt/mytframe.o myt/mytprogress.o
15 | $(CC) $(CFLAGS) -o $@ $^
16 | strip $(EXEC)
17 |
18 | clean:
19 | rm -f *.o core
20 |
21 | mrproper: clean
22 | rm -f $(EXEC)
23 |
--------------------------------------------------------------------------------
/demo/c/demo-myterminal:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/c/demo-myterminal
--------------------------------------------------------------------------------
/demo/c/error_message.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void error_message(const char *format, ...) {
6 | va_list args;
7 | va_start(args, format);
8 |
9 | vfprintf(stderr, format, args);
10 |
11 | va_end(args);
12 |
13 | fprintf(stderr, "\n");
14 | }
15 |
--------------------------------------------------------------------------------
/demo/c/error_message.h:
--------------------------------------------------------------------------------
1 | #ifndef _ERROR_MESSAGE_H
2 | #define _ERROR_MESSAGE_H
3 |
4 | void error_message(const char *format, ...);
5 |
6 | #endif
--------------------------------------------------------------------------------
/demo/c/myt/Makefile:
--------------------------------------------------------------------------------
1 | CC=gcc
2 | CFLAGS=-Wall -Os -std=gnu99 -s -fno-stack-protector -ffunction-sections -fdata-sections -Wl,--gc-sections -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-math-errno -fno-ident -fmerge-all-constants -ffast-math -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none
3 | LDFLAGS=
4 |
5 | %.o: %.c %.h
6 | $(CC) $(CFLAGS) -o $@ -c $<
7 |
8 | mytwidget.o:
9 | mytframe.o: mytcodes.h mytwidget.o
10 | mytbutton.o: mytcodes.h mytwidget.o
11 | mytcheckbox.o: mytcodes.h mytwidget.o
12 | mytprogress.o: mytcodes.h mytwidget.o
13 |
14 | clean:
15 | rm -f *.o
16 |
--------------------------------------------------------------------------------
/demo/c/myt/mytbutton.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "mytbutton.h"
7 | #include "mytcodes.h"
8 |
9 | MytButton *new_button(MytWidget *parent, char *label, unsigned char x,
10 | unsigned char y, unsigned char width) {
11 | MytButton *button = (MytButton *)malloc(sizeof(MytButton));
12 |
13 | init_widget((MytWidget *)button);
14 | add_child(parent, (MytWidget *)button);
15 | button->common.parent = parent;
16 | button->common.draw = (DrawCallback)&draw_button;
17 |
18 | button->common.x = x;
19 | button->common.y = y;
20 |
21 | if (parent != NULL) {
22 | button->common.x += parent->x;
23 | button->common.y += parent->y;
24 | button->common.foreground = parent->foreground;
25 | button->common.background = parent->background;
26 | }
27 |
28 | button->common.width = width;
29 | button->common.height = 2;
30 |
31 | button->label = label;
32 | button->length = mytstrlen((unsigned char *)label, 1);
33 | button->state = BUTTON_IDLE;
34 |
35 | return button;
36 | }
37 |
38 | void draw_button(int fd, MytButton *button) {
39 | int left = (button->common.width - 3 - button->length) / 2;
40 | int right = button->common.width - 3 - left - button->length;
41 |
42 | dprintf(fd,
43 | LOCATE_BASE "%c%c" CP0 COLOR_BASE "%c" COLOR_BASE "%c" REVERSE_ON
44 | CP4 "\x3a" CP0 "%*s%s%*s" CP4 "\x35" CP0 REVERSE_OFF,
45 | LOCATE_OFFSET + button->common.y, LOCATE_OFFSET + button->common.x,
46 | F_OFFSET + button->common.foreground,
47 | B_OFFSET + button->common.background, left, "", button->label, right,
48 | "");
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/demo/c/myt/mytbutton.h:
--------------------------------------------------------------------------------
1 | #ifndef _MYTBUTTON_H
2 | #define _MYTBUTTON_H
3 |
4 | #define BUTTON_IDLE 0
5 | #define BUTTON_SELECTED 1
6 |
7 | #include "mytwidget.h"
8 |
9 | typedef struct {
10 | MytWidget common;
11 | char *label;
12 | unsigned char length;
13 | unsigned char state;
14 | } MytButton;
15 |
16 | MytButton *new_button(MytWidget *parent, char *label, unsigned char x,
17 | unsigned char y, unsigned char width);
18 | void draw_button(int fd, MytButton *button);
19 |
20 | #endif
--------------------------------------------------------------------------------
/demo/c/myt/mytcheckbox.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "mytcheckbox.h"
7 | #include "mytcodes.h"
8 |
9 | MytCheckbox *new_checkbox(MytWidget *parent, char *label, unsigned char x,
10 | unsigned char y) {
11 | MytCheckbox *checkbox = (MytCheckbox *)malloc(sizeof(MytCheckbox));
12 |
13 | init_widget((MytWidget *)checkbox);
14 | add_child(parent, (MytWidget *)checkbox);
15 | checkbox->common.parent = parent;
16 | checkbox->common.draw = (DrawCallback)&draw_checkbox;
17 |
18 | checkbox->common.x = x;
19 | checkbox->common.y = y;
20 |
21 | if (parent != NULL) {
22 | checkbox->common.x += parent->x;
23 | checkbox->common.y += parent->y;
24 | checkbox->common.foreground = parent->foreground;
25 | checkbox->common.background = parent->background;
26 | }
27 |
28 | checkbox->common.width = mytstrlen((unsigned char *)label, 1) + 2;
29 | checkbox->common.height = 1;
30 |
31 | checkbox->label = label;
32 | checkbox->state = CHECKBOX_UNCHECKED;
33 |
34 | return checkbox;
35 | }
36 |
37 | void draw_checkbox(int fd, MytCheckbox *checkbox) {
38 | dprintf(
39 | fd,
40 | LOCATE_BASE "%c%c" COLOR_BASE "%c" COLOR_BASE "%c" CP1 "%c" CP0 " %s",
41 | LOCATE_OFFSET + checkbox->common.y, LOCATE_OFFSET + checkbox->common.x,
42 | F_OFFSET + checkbox->common.foreground,
43 | B_OFFSET + checkbox->common.background,
44 | checkbox->state, checkbox->label);
45 | }
46 |
47 | void update_checkbox(int fd, MytCheckbox *checkbox) {
48 | dprintf(
49 | fd,
50 | LOCATE_BASE "%c%c" COLOR_BASE "%c" COLOR_BASE "%c" CP1 "%c" CP0,
51 | LOCATE_OFFSET + checkbox->common.y, LOCATE_OFFSET + checkbox->common.x,
52 | F_OFFSET + checkbox->common.foreground,
53 | B_OFFSET + checkbox->common.background,
54 | checkbox->state);
55 | }
--------------------------------------------------------------------------------
/demo/c/myt/mytcheckbox.h:
--------------------------------------------------------------------------------
1 | #ifndef _MYTCHECKBOX_H
2 | #define _MYTCHECKBOX_H
3 |
4 | #include "mytwidget.h"
5 |
6 | #define CHECKBOX_UNCHECKED (0xbe)
7 | #define CHECKBOX_PLUS (0xbb)
8 | #define CHECKBOX_MINUS (0xbc)
9 | #define CHECKBOX_CHECKED (0xbd)
10 | #define CHECKBOX_CROSS (0xbf)
11 |
12 | #define RADIO_UNCHECKED (0xa2)
13 | #define RADIO_PLUS (0xa1)
14 | #define RADIO_CHECKED (0xa3)
15 |
16 | typedef struct {
17 | MytWidget common;
18 | char *label;
19 | unsigned char state;
20 | } MytCheckbox;
21 |
22 | MytCheckbox *new_checkbox(MytWidget *parent, char *label, unsigned char x,
23 | unsigned char y);
24 | void draw_checkbox(int fd, MytCheckbox *checkbox);
25 | void update_checkbox(int fd, MytCheckbox *checkbox);
26 |
27 | #endif
--------------------------------------------------------------------------------
/demo/c/myt/mytframe.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "mytcodes.h"
7 | #include "mytframe.h"
8 |
9 | MytFrame *new_frame(MytWidget *parent, char *label, unsigned char x,
10 | unsigned char y, unsigned char width,
11 | unsigned char height) {
12 | MytFrame *frame = (MytFrame *)malloc(sizeof(MytFrame));
13 |
14 | init_widget((MytWidget *)frame);
15 | add_child(parent, (MytWidget *)frame);
16 | frame->common.parent = parent;
17 | frame->common.draw = (DrawCallback)&draw_frame;
18 |
19 | frame->common.x = x;
20 | frame->common.y = y;
21 |
22 | if (parent != NULL) {
23 | frame->common.x += parent->x;
24 | frame->common.y += parent->y;
25 | frame->common.foreground = parent->foreground;
26 | frame->common.background = parent->background;
27 | } else {
28 | frame->common.foreground = LIGHT_WHITE;
29 | frame->common.background = LIGHT_BLUE;
30 | }
31 |
32 | frame->common.width = width;
33 | frame->common.height = height;
34 |
35 | frame->label = label;
36 | frame->label_width = mytstrlen((unsigned char *)label, 1);
37 | frame->label_foreground = BLACK;
38 | frame->label_background = LIGHT_YELLOW;
39 |
40 | return frame;
41 | }
42 |
43 | void draw_frame(int fd, MytFrame *frame) {
44 | fill_widget(fd, (MytWidget *)frame);
45 |
46 | dprintf(fd,
47 | LOCATE_BASE "%c%c" COLOR_BASE "%c" COLOR_BASE "%c" CP4 "\x34" CP0
48 | "%s%*s" CP4 "\x31" CP0,
49 | LOCATE_OFFSET + frame->common.y - 1, LOCATE_OFFSET + frame->common.x,
50 | F_OFFSET + frame->label_foreground,
51 | B_OFFSET + frame->label_background, frame->label,
52 | frame->common.width - frame->label_width - 2, " ");
53 | }
54 |
--------------------------------------------------------------------------------
/demo/c/myt/mytframe.h:
--------------------------------------------------------------------------------
1 | #ifndef _MYTFRAME_H
2 | #define _MYTFRAME_H
3 |
4 | #include "mytwidget.h"
5 |
6 | typedef struct {
7 | MytWidget common;
8 | char *label;
9 | unsigned char label_width;
10 | unsigned char label_foreground;
11 | unsigned char label_background;
12 | } MytFrame;
13 |
14 | MytFrame *new_frame(MytWidget *parent, char *label, unsigned char x,
15 | unsigned char y, unsigned char width, unsigned char height);
16 | void draw_frame(int fd, MytFrame *frame);
17 |
18 | #endif
--------------------------------------------------------------------------------
/demo/c/myt/mytprogress.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "mytcodes.h"
7 | #include "mytprogress.h"
8 |
9 | MytProgress *new_progress(MytWidget *parent, unsigned char x, unsigned char y,
10 | unsigned char width) {
11 | MytProgress *progress = (MytProgress *)malloc(sizeof(MytProgress));
12 |
13 | init_widget((MytWidget *)progress);
14 | add_child(parent, (MytWidget *)progress);
15 | progress->common.parent = parent;
16 | progress->common.draw = (DrawCallback)&draw_progress;
17 |
18 | progress->common.x = x;
19 | progress->common.y = y;
20 |
21 | if (parent != NULL) {
22 | progress->common.x += parent->x;
23 | progress->common.y += parent->y;
24 | progress->common.foreground = parent->foreground;
25 | progress->common.background = parent->background;
26 | }
27 |
28 | progress->common.width = width;
29 | progress->common.height = 1;
30 |
31 | progress->value = 0;
32 |
33 | return progress;
34 | }
35 |
36 | void draw_progress(int fd, MytProgress *progress) {
37 | unsigned char buf;
38 | unsigned int steps = progress->value;
39 | unsigned int start_steps = steps < PROGRESS_START ? steps : 6;
40 |
41 | dprintf(fd, LOCATE_BASE "%c%c" COLOR_BASE "%c" COLOR_BASE "%c" CP4 "%c",
42 | LOCATE_OFFSET + progress->common.y,
43 | LOCATE_OFFSET + progress->common.x,
44 | F_OFFSET + progress->common.foreground,
45 | B_OFFSET + progress->common.background, 0x40 + start_steps);
46 |
47 | unsigned int remaining_steps = steps - start_steps;
48 |
49 | for (int i = 0; i < progress->common.width - 2; i++) {
50 | if (remaining_steps >= PROGRESS_MIDDLE) {
51 | buf = 0x4f;
52 | } else {
53 | buf = 0x47 + remaining_steps;
54 | }
55 |
56 | write(fd, &buf, 1);
57 |
58 | remaining_steps = remaining_steps < PROGRESS_MIDDLE
59 | ? 0
60 | : remaining_steps - PROGRESS_MIDDLE;
61 | }
62 |
63 | dprintf(fd, "%c" CP0, 0x50 + remaining_steps);
64 | }
65 |
--------------------------------------------------------------------------------
/demo/c/myt/mytprogress.h:
--------------------------------------------------------------------------------
1 | #ifndef _MYTPROGRESS_H
2 | #define _MYTPROGRESS_H
3 |
4 | #include "mytwidget.h"
5 |
6 | #define PROGRESS_START (7)
7 | #define PROGRESS_MIDDLE (9)
8 | #define PROGRESS_END (6)
9 |
10 | typedef struct {
11 | MytWidget common;
12 | unsigned int value;
13 | } MytProgress;
14 |
15 | MytProgress *new_progress(MytWidget *parent, unsigned char x, unsigned char y,
16 | unsigned char width);
17 | void draw_progress(int fd, MytProgress *progress);
18 |
19 | #endif
--------------------------------------------------------------------------------
/demo/c/myt/mytwidget.c:
--------------------------------------------------------------------------------
1 | #include "mytwidget.h"
2 | #include "mytcodes.h"
3 | #include
4 | #include
5 | #include
6 |
7 | MytWidget *which_widget(MytWidget *widget, unsigned char x, unsigned char y) {
8 | MytWidget *child;
9 |
10 | if (widget == NULL) {
11 | return NULL;
12 | }
13 |
14 | if (x < widget->x || x >= (widget->x + widget->width) || y < widget->y ||
15 | y >= (widget->y + widget->height)) {
16 | return NULL;
17 | }
18 |
19 | for (int i = 0; i < widget->children_count; i++) {
20 | child = which_widget(widget->children[i], x, y);
21 | if (child != NULL) {
22 | return child;
23 | }
24 | }
25 |
26 | return widget;
27 | }
28 |
29 | void fill_widget(int myt, MytWidget *widget) {
30 | int y;
31 | int i;
32 |
33 | if (widget == NULL) {
34 | return;
35 | }
36 |
37 | dprintf(myt, COLOR_BASE "%c" COLOR_BASE "%c", F_OFFSET + widget->foreground,
38 | B_OFFSET + widget->background);
39 | for (y = widget->y; y < widget->y + widget->height; y++) {
40 | dprintf(myt, LOCATE(widget->x, y));
41 | for (i = 0; i < widget->width; i++) {
42 | write(myt, " ", 1);
43 | }
44 | }
45 | }
46 |
47 | void locate_widget(int myt, MytWidget *widget, unsigned char x,
48 | unsigned char y) {
49 | dprintf(myt, LOCATE_BASE "%c%c", LOCATE_OFFSET + widget->y + y,
50 | LOCATE_OFFSET + widget->x + x);
51 | }
52 |
53 | int mytstrlen(const unsigned char *string, unsigned char char_width) {
54 | int count = 0;
55 | int offset = 0;
56 |
57 | if (string == NULL) {
58 | return 0;
59 | }
60 |
61 | while (string[offset] != '\0') {
62 | if (string[offset] >= ' ') {
63 | count += char_width;
64 | offset++;
65 | } else {
66 | switch (string[offset]) {
67 | case 0x01:
68 | case 0x02:
69 | case 0x03:
70 | case 0x06:
71 | case 0x19:
72 | if (string[offset + 1] == 0x00) {
73 | return count;
74 | }
75 | offset += 2;
76 | break;
77 |
78 | case 0x04:
79 | if (string[offset + 1] == 0x00 || string[offset + 2] == 0x00) {
80 | return count;
81 | }
82 | offset += 3;
83 | break;
84 |
85 | case 0x05:
86 | switch (string[offset + 1]) {
87 | case 0x00:
88 | return count;
89 | case 0x30:
90 | case 0x32:
91 | char_width = 1;
92 | break;
93 | case 0x31:
94 | case 0x33:
95 | char_width = 2;
96 | break;
97 | }
98 | offset += 2;
99 | break;
100 |
101 | default:
102 | offset++;
103 | }
104 | }
105 | }
106 |
107 | return count;
108 | }
109 |
110 | void init_widget(MytWidget *widget) {
111 | if (widget == NULL) {
112 | return;
113 | }
114 |
115 | widget->parent = NULL;
116 | widget->children = NULL;
117 | widget->children_count = 0;
118 | widget->x = 0;
119 | widget->y = 0;
120 | widget->width = 80;
121 | widget->height = 51;
122 | widget->foreground = LIGHT_WHITE;
123 | widget->background = BLACK;
124 | }
125 |
126 | void add_child(MytWidget *parent, MytWidget *child) {
127 | if (parent == NULL || child == NULL) {
128 | return;
129 | }
130 |
131 | if (parent->children == NULL) {
132 | parent->children = malloc(sizeof(MytWidget *));
133 | } else {
134 | parent->children = realloc(parent->children, (parent->children_count + 1) *
135 | sizeof(MytWidget *));
136 | }
137 |
138 | parent->children[parent->children_count] = child;
139 | parent->children_count++;
140 | }
141 |
142 | void free_widget(MytWidget *widget) {
143 | if (widget == NULL) {
144 | return;
145 | }
146 |
147 | for (int i = 0; i < widget->children_count; i++) {
148 | free_widget(widget->children[i]);
149 | }
150 |
151 | free(widget);
152 | }
153 |
154 | void draw_widget(int myt, MytWidget *widget) {
155 | if (widget == NULL) {
156 | return;
157 | }
158 |
159 | (*(widget->draw))(myt, widget);
160 | for (int i = 0; i < widget->children_count; i++) {
161 | draw_widget(myt, widget->children[i]);
162 | }
163 | }
--------------------------------------------------------------------------------
/demo/c/myt/mytwidget.h:
--------------------------------------------------------------------------------
1 | #ifndef _MYTWIDGET_H
2 | #define _MYTWIDGET_H
3 |
4 | typedef struct MytWidget MytWidget;
5 | typedef void (*DrawCallback)(int, MytWidget *);
6 |
7 | struct MytWidget {
8 | void *parent;
9 | void **children;
10 | DrawCallback draw;
11 | unsigned char children_count;
12 | unsigned char x;
13 | unsigned char y;
14 | unsigned char width;
15 | unsigned char height;
16 | unsigned char foreground;
17 | unsigned char background;
18 | };
19 |
20 | MytWidget *which_widget(MytWidget *widget, unsigned char x, unsigned char y);
21 | void fill_widget(int myt, MytWidget *widget);
22 | void locate_widget(int myt, MytWidget *widget, unsigned char x,
23 | unsigned char y);
24 | int mytstrlen(const unsigned char *string, unsigned char char_width);
25 | void init_widget(MytWidget *widget);
26 | void add_child(MytWidget *parent, MytWidget *child);
27 | void free_widget(MytWidget *widget);
28 | void draw_widget(int myt, MytWidget *widget);
29 |
30 | #endif
--------------------------------------------------------------------------------
/demo/c/serial.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "error_message.h"
8 |
9 | int set_interface_attribs(int fd, int speed, int parity) {
10 | struct termios tty;
11 | if (tcgetattr(fd, &tty) != 0) {
12 | error_message("error %d from tcgetattr", errno);
13 | return -1;
14 | }
15 |
16 | cfsetospeed(&tty, speed);
17 | cfsetispeed(&tty, speed);
18 |
19 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
20 | tty.c_iflag &= ~IGNBRK;
21 | tty.c_lflag = 0;
22 | tty.c_oflag = 0;
23 | tty.c_cc[VMIN] = 0;
24 | tty.c_cc[VTIME] = 5;
25 |
26 | tty.c_iflag &= ~(IXON | IXOFF | IXANY);
27 |
28 | tty.c_cflag |= (CLOCAL | CREAD);
29 | tty.c_cflag &= ~(PARENB | PARODD);
30 | tty.c_cflag |= parity;
31 | tty.c_cflag &= ~CSTOPB;
32 | tty.c_cflag |= CRTSCTS;
33 |
34 | if (tcsetattr(fd, TCSANOW, &tty) != 0) {
35 | error_message("error %d from tcsetattr", errno);
36 | return -1;
37 | }
38 |
39 | return 0;
40 | }
41 |
42 | int set_blocking(int fd, int should_block) {
43 | struct termios tty;
44 | memset(&tty, 0, sizeof tty);
45 | if (tcgetattr(fd, &tty) != 0) {
46 | error_message("error %d from tggetattr", errno);
47 | return -1;
48 | }
49 |
50 | tty.c_cc[VMIN] = should_block ? 1 : 0;
51 | tty.c_cc[VTIME] = 5;
52 |
53 | if (tcsetattr(fd, TCSANOW, &tty) != 0) {
54 | error_message("error %d setting term attributes", errno);
55 | return -1;
56 | }
57 |
58 | return 0;
59 | }
60 |
61 | int open_serial_port(const char *portname) {
62 | int fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
63 | if (fd < 0) {
64 | error_message("error %d opening %s: %s", errno, portname, strerror(errno));
65 | return -1;
66 | }
67 |
68 | if (set_interface_attribs(fd, 3000000, 0) < 0) {
69 | error_message("error setting interface attributes of %s", portname);
70 | return -1;
71 | }
72 |
73 | if (set_blocking(fd, 0) < 0) {
74 | error_message("error setting blocking mode of %s", portname);
75 | return -1;
76 | }
77 |
78 | /*
79 | write (fd, "hello!\n", 7);
80 |
81 | usleep ((7 + 25) * 100);
82 |
83 | char buf[100];
84 | int n = read (fd, buf, sizeof buf);*/
85 | return fd;
86 | }
87 |
--------------------------------------------------------------------------------
/demo/c/serial.h:
--------------------------------------------------------------------------------
1 | #ifndef _SERIAL_H
2 | #define _SERIAL_H
3 |
4 | int set_interface_attribs(int fd, int speed, int parity);
5 | int set_blocking(int fd, int should_block);
6 | int open_serial_port(const char *portname);
7 |
8 | #endif
--------------------------------------------------------------------------------
/demo/cat-marta-simon-pixabay-disjoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/cat-marta-simon-pixabay-disjoint.png
--------------------------------------------------------------------------------
/demo/cat-marta-simon-pixabay-disjoint.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/cat-marta-simon-pixabay-disjoint.raw
--------------------------------------------------------------------------------
/demo/cat-marta-simon-pixabay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/cat-marta-simon-pixabay.png
--------------------------------------------------------------------------------
/demo/cat-marta-simon-pixabay.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/cat-marta-simon-pixabay.raw
--------------------------------------------------------------------------------
/demo/colors.txt:
--------------------------------------------------------------------------------
1 | O[93mMyTerminal
2 | [40m [40m 0
3 | [41m [40m 1
4 | [42m [40m 2
5 | [43m [40m 3
6 | [44m [40m 4
7 | [45m [40m 5
8 | [46m [40m 6
9 | [47m [40m 7
10 | [100m [40m 8
11 | [101m [40m 9
12 | [102m [40m 10
13 | [103m [40m 11
14 | [104m [40m 12
15 | [105m [40m 13
16 | [106m [40m 14
17 | [107m [40m 15
18 |
--------------------------------------------------------------------------------
/demo/diagonal.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import random
3 | import sys
4 |
5 | myt_print = sys.stdout.buffer.write
6 |
7 | MYT = 'ISO-8859-15'
8 | CHARPAGES = [ b'\x13', b'\x14', b'\x15', b'\x16', b'\x17' ]
9 | LEFT_ROUND = b'\x174\x13'
10 | RIGHT_ROUND = b'\x171\x13'
11 |
12 | diagonals = [
13 | b'\xD1', b'\xD2', b'\xD3', b'\xD4', b'\xD5', b'\xD6', b'\xD7',
14 | b'\xD8', b'\xD9', b'\xDA', b'\xDC', b'\xDF',
15 |
16 | b'\xE1', b'\xE2', b'\xE3', b'\xE4', b'\xE5', b'\xE6', b'\xE7',
17 | b'\xE8', b'\xE9', b'\xEA', b'\xEB', b'\xEC', b'\xED', b'\xEE', b'\xEF'
18 | ]
19 |
20 | screen = CHARPAGES[2]
21 | for _ in range(80*50 - 1):
22 | screen += random.choice(diagonals)
23 | screen += CHARPAGES[0]
24 |
25 | myt_print(b'\x0400\x02@\x02_')
26 | myt_print(LEFT_ROUND + ("Démo: diagonal | MyTerminal").ljust(78).encode(MYT) + RIGHT_ROUND)
27 | myt_print(b'\x02O\x02P' + screen)
28 |
--------------------------------------------------------------------------------
/demo/init_tty.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | stty -F /dev/ttyUSB0 speed 3000000
3 | stty -F /dev/ttyUSB0 crtscts
4 |
5 |
--------------------------------------------------------------------------------
/demo/jigsaw.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import random
3 | import sys
4 |
5 | myt_print = sys.stdout.buffer.write
6 |
7 | MYT = 'ISO-8859-15'
8 | CHARPAGES = [ b'\x13', b'\x14', b'\x15', b'\x16', b'\x17' ]
9 | LEFT_ROUND = b'\x174\x13'
10 | RIGHT_ROUND = b'\x171\x13'
11 |
12 |
13 | colors = [
14 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
15 | ]
16 |
17 | jigsaw = [ chr(j).encode(MYT) for j in range(96, 160) ]
18 | screen = CHARPAGES[3]
19 | for _ in range(80*50 - 1):
20 | screen += bytes([2, 64 + random.choice(colors)])
21 | #screen += bytes([2, 80 + random.choice(colors)])
22 | screen += random.choice(jigsaw)
23 | screen += CHARPAGES[0]
24 |
25 | myt_print(b'\x0400\x02@\x02_')
26 | myt_print(LEFT_ROUND + ("Démo: jigsaw | MyTerminal").ljust(78).encode(MYT) + RIGHT_ROUND)
27 | myt_print(b'\x02O\x02P' + screen)
28 |
--------------------------------------------------------------------------------
/demo/js/charpage0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/js/charpage0.png
--------------------------------------------------------------------------------
/demo/js/charpage1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/js/charpage1.png
--------------------------------------------------------------------------------
/demo/js/charpage2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/js/charpage2.png
--------------------------------------------------------------------------------
/demo/js/charpage3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/js/charpage3.png
--------------------------------------------------------------------------------
/demo/js/charpage4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/js/charpage4.png
--------------------------------------------------------------------------------
/demo/js/demo-age-pyramid.js:
--------------------------------------------------------------------------------
1 | /* exported demoAgePyramid */
2 | function demoAgePyramid(myTerminal) {
3 | function center(string, width) {
4 | if (string.length >= width) {
5 | return string.substr(0, width)
6 | } else {
7 | const remain = width - string.length
8 | return (
9 | " ".repeat(Math.ceil(remain / 2)) +
10 | string +
11 | " ".repeat(Math.floor(remain / 2))
12 | )
13 | }
14 | }
15 |
16 | myTerminal.write(myCode()
17 | .resetAttributes()
18 | .cursor(false)
19 | .background(2)
20 | .foreground(15)
21 | .clearScreen()
22 | .background(4)
23 | .clearEndOfLine()
24 | .print("Age pyramid demo\n")
25 | .background(2)
26 | .characterPage(3)
27 | .print("P".repeat(80))
28 | .characterPage(0)
29 | )
30 |
31 | const francePopulation2020 = {
32 | labels: [
33 | '0-2', '3-5', '6-8', '9-11', '12-14', '15-17', '18-20', '21-23',
34 | '24-26', '27-29', '30-32', '33-35', '36-38', '39-41', '42-44',
35 | '45-47', '48-50', '51-53', '54-56', '57-59', '60-62', '63-65',
36 | '66-68', '69-71', '72-74', '75-77', '78-80', '81-83', '84-86',
37 | '87-89', '90-92', '93-95', '96-98', '99-101', '102-104', '105+'
38 | ],
39 | male: [
40 | 1046287, 1129544, 1196617, 1234467, 1226853, 1217031, 1209184,
41 | 1102825, 1039280, 1096544, 1137220, 1161074, 1201592, 1198524,
42 | 1163001, 1291079, 1302411, 1257024, 1267809, 1206140, 1157727,
43 | 1105011, 1066195, 1055731, 880102, 629904, 505173, 452227, 353248,
44 | 253110, 139091, 65673, 24264, 5436, 820, 638
45 | ],
46 | female: [
47 | 1003575, 1085380, 1142765, 1179592, 1171898, 1155076, 1143048,
48 | 1072415, 1044378, 1122848, 1196731, 1228878, 1259057, 1245324,
49 | 1188265, 1315829, 1322722, 1296911, 1326992, 1278948, 1259236,
50 | 1230655, 1196366, 1204031, 1029874, 767440, 663365, 650340,
51 | 584712, 491668, 332318, 199331, 95523, 26715, 4832, 2060
52 | ],
53 | }
54 |
55 | const width = 27
56 | const maximum = Math.max(
57 | Math.max(...francePopulation2020.male),
58 | Math.max(...francePopulation2020.female)
59 | )
60 |
61 | const vpos = 4
62 |
63 | for (let i = 0; i < francePopulation2020.labels.length; i++) {
64 | let malePercent = francePopulation2020.male[i] / maximum
65 | let femalePercent = francePopulation2020.female[i] / maximum
66 | myTerminal.write(myCode()
67 | .foreground(11)
68 | .locate(35, vpos + francePopulation2020.labels.length - i)
69 | .gauge(width, malePercent, MyCode.WEST, false)
70 | .foreground(14)
71 | .locate(45, vpos + francePopulation2020.labels.length - i)
72 | .gauge(width, femalePercent, MyCode.EAST, false)
73 | .foreground(7)
74 | .locate(
75 | 35 - 6 - width * malePercent,
76 | vpos + francePopulation2020.labels.length - i
77 | )
78 | .print(String(francePopulation2020.male[i]).padStart(7))
79 | .foreground(7)
80 | .locate(
81 | 45 + 1 + width * femalePercent,
82 | vpos + francePopulation2020.labels.length - i
83 | )
84 | .print(String(francePopulation2020.female[i]))
85 | .foreground(9)
86 | .locate(37, vpos + francePopulation2020.labels.length - i)
87 | .print(center(francePopulation2020.labels[i], 7))
88 | )
89 | }
90 |
91 | myTerminal.write(myCode()
92 | .locate(23 , vpos + francePopulation2020.labels.length + 2)
93 | .size(MyCode.SIZE_DOUBLE)
94 | .foreground(15)
95 | .print("FRANCE POPULATION")
96 | .locate(25 , vpos + francePopulation2020.labels.length + 4)
97 | .size(MyCode.SIZE_DOUBLE_WIDTH)
98 | .foreground(7)
99 | .print("January 1, 2020")
100 | .locate(5, vpos + francePopulation2020.labels.length + 5)
101 | .size(MyCode.SIZE_NORMAL)
102 | .foreground(10)
103 | .print("Source: Insee, estimations de population ")
104 | .print("(résultats arrêtés fin 2019)")
105 | )
106 | }
107 |
--------------------------------------------------------------------------------
/demo/js/demo-colors.js:
--------------------------------------------------------------------------------
1 | /* exported demoColors */
2 | function demoColors(myTerminal) {
3 | myTerminal.write(myCode()
4 | .resetAttributes()
5 | .cursor(false)
6 | .background(2)
7 | .foreground(15)
8 | .clearScreen()
9 | .background(4)
10 | .clearEndOfLine()
11 | .print("List of colors\n")
12 | .background(2)
13 | .characterPage(3)
14 | .repeat("P", 80)
15 | .characterPage(0)
16 | )
17 |
18 | let y
19 | for (let i = 0; i < 16; i++) {
20 | y = 2 + i * 3
21 |
22 | myTerminal.write(myCode()
23 | .resetAttributes()
24 | .foreground(i)
25 | .background(2)
26 | .size(3)
27 | .characterPage(4)
28 | )
29 |
30 | myTerminal.write(myCode()
31 | .locate(1, y)
32 | .applyPattern(11, MyCode.FUNCTION_AND)
33 | .repeat(String.fromCharCode(0xdf), 10)
34 | .stopPattern()
35 | .repeat(String.fromCharCode(0xdf), 19)
36 | .applyPattern(11, MyCode.FUNCTION_AND)
37 | .repeat(String.fromCharCode(0xdf), 10)
38 | .stopPattern()
39 | )
40 |
41 | myTerminal.write(myCode()
42 | .characterPage(0)
43 | .locate(i > 9 ? 30 : 31, y)
44 | .background(i)
45 | .foreground(i > 6 && i != 12 ? 0 : 15)
46 | .print(" Color " + i + " ")
47 | )
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/demo/js/demo-frames.js:
--------------------------------------------------------------------------------
1 | /* exported demoFrames */
2 | function demoFrames(myTerminal) {
3 | myTerminal.write(myCode()
4 | .resetAttributes()
5 | .cursor(false)
6 | .background(2)
7 | .foreground(15)
8 | .clearScreen()
9 | .background(4)
10 | .clearEndOfLine()
11 | .print("Examples of frames and patterns\n")
12 | .background(2)
13 | .characterPage(3)
14 | .print("P".repeat(80))
15 | .characterPage(0)
16 | )
17 |
18 | const interestingForLight = [ 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12 ]
19 | const interestingForStrong = [ 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13 ]
20 | const interestingForDouble = [ 0, 1, 2, 3, 7, 8 ]
21 |
22 | for (let patternId = 0; patternId < 15; patternId++) {
23 | myTerminal.write(myCode()
24 | .locate(4 + patternId*5, 2)
25 | .foreground(15)
26 | .size(1)
27 | .print(String(patternId))
28 | .size(0)
29 | )
30 |
31 | myTerminal.write(myCode()
32 | .foreground(interestingForLight.includes(patternId) ? 15 : 10)
33 | .applyPattern(patternId, MyCode.FUNCTION_AND)
34 | .lightFrame(3 + patternId*5, 3, 5, 3)
35 | .stopPattern()
36 | .locate(3 + patternId*5 + 1, 4)
37 | .print("LIT")
38 | )
39 |
40 | myTerminal.write(myCode()
41 | .foreground(interestingForStrong.includes(patternId) ? 15 : 10)
42 | .applyPattern(patternId, MyCode.FUNCTION_AND)
43 | .strongFrame(3 + patternId*5, 6, 5, 3)
44 | .stopPattern()
45 | .locate(3 + patternId*5 + 1, 7)
46 | .print("STR")
47 | )
48 |
49 | myTerminal.write(myCode()
50 | .foreground(interestingForDouble.includes(patternId) ? 15 : 10)
51 | .applyPattern(patternId, MyCode.FUNCTION_AND)
52 | .doubleFrame(3 + patternId*5, 9, 5, 3)
53 | .stopPattern()
54 | .locate(3 + patternId*5 + 1, 10)
55 | .print("DBL")
56 | )
57 |
58 | }
59 |
60 | myTerminal.write(myCode()
61 | .background(2)
62 | .foreground(10)
63 | .bubble(MyCode.NOT_FILLED, 30, 13, 19, 2, 5, MyCode.NORTH)
64 | .locate(30, 13)
65 | .print("These combinations")
66 | .locate(30, 14)
67 | .print("are not interesting")
68 | )
69 |
70 | myTerminal.write(myCode()
71 | .background(2)
72 | .foreground(15)
73 | .bubble(MyCode.FILLED, 5, 13, 23, 2, 5, MyCode.NORTH)
74 | .reverse(true)
75 | .locate(5, 13)
76 | .print("These combinations give")
77 | .locate(5, 14)
78 | .print("interesting results")
79 | .reverse(false)
80 | )
81 | }
--------------------------------------------------------------------------------
/demo/js/demo-gauges.js:
--------------------------------------------------------------------------------
1 | /* exported demoGauges */
2 | function demoGauges(myTerminal) {
3 | myTerminal.write(myCode()
4 | .resetAttributes()
5 | .cursor(false)
6 | .background(2)
7 | .foreground(15)
8 | .clearScreen()
9 | .background(4)
10 | .clearEndOfLine()
11 | .print("Examples of gauges and progress bars\n")
12 | .background(2)
13 | .characterPage(3)
14 | .print("P".repeat(80))
15 | .characterPage(0)
16 | )
17 |
18 | for (let i = 0; i < 47; i++) {
19 | myTerminal.write(myCode()
20 | .locate(15, 2 + i)
21 | .characterPage(3)
22 | .foreground(15)
23 | .print(String.fromCharCode(0xb1))
24 | .characterPage(0)
25 | .foreground(7)
26 | .applyPattern(i % 15, 0)
27 | .gauge(10, i / 47, MyCode.EAST, false)
28 | .stopPattern()
29 | .print(String(i))
30 | )
31 | }
32 |
33 | for (let i = 0; i < 47; i++) {
34 | myTerminal.write(myCode()
35 | .locate(30, 2 + i)
36 | .foreground(7)
37 | .progressBar(10, i / 47)
38 | )
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/demo/js/demo-hires.js:
--------------------------------------------------------------------------------
1 | /* exported demoHires */
2 | function BMFastPixelArtLine(ctx, x1, y1, x2, y2) {
3 | x1 = Math.round(x1);
4 | y1 = Math.round(y1);
5 | x2 = Math.round(x2);
6 | y2 = Math.round(y2);
7 | const dx = Math.abs(x2 - x1);
8 | const sx = x1 < x2 ? 1 : -1;
9 | const dy = Math.abs(y2 - y1);
10 | const sy = y1 < y2 ? 1 : -1;
11 | var error, len, rev, count = dx;
12 | ctx.beginPath();
13 | if (dx > dy) {
14 | error = dx / 2;
15 | rev = x1 > x2 ? 1 : 0;
16 | if (dy > 1) {
17 | error = 0;
18 | count = dy - 1;
19 | do {
20 | len = error / dy + 2 | 0;
21 | ctx.rect(x1 - len * rev, y1, len, 1);
22 | x1 += len * sx;
23 | y1 += sy;
24 | error -= len * dy - dx;
25 | } while (count--);
26 | }
27 | if (error > 0) {ctx.rect(x1, y2, x2 - x1, 1) }
28 | } else if (dx < dy) {
29 | error = dy / 2;
30 | rev = y1 > y2 ? 1 : 0;
31 | if (dx > 1) {
32 | error = 0;
33 | count --;
34 | do {
35 | len = error / dx + 2 | 0;
36 | ctx.rect(x1 ,y1 - len * rev, 1, len);
37 | y1 += len * sy;
38 | x1 += sx;
39 | error -= len * dx - dy;
40 | } while (count--);
41 | }
42 | if (error > 0) { ctx.rect(x2, y1, 1, y2 - y1) }
43 | } else {
44 | do {
45 | ctx.rect(x1, y1, 1, 1);
46 | x1 += sx;
47 | y1 += sy;
48 | } while (count --);
49 | }
50 | ctx.fill();
51 | }
52 |
53 | function updateGraph(myTerminal) {
54 | const aCanvas = document.createElement('canvas')
55 | aCanvas.width = 240
56 | aCanvas.height = 200
57 |
58 | const ctx = aCanvas.getContext('2d')
59 | ctx.imageSmoothingEnabled = false
60 |
61 | ctx.beginPath()
62 | ctx.fillStyle = '#007f00'
63 | ctx.rect(0, 0, aCanvas.width, aCanvas.height)
64 | ctx.fill()
65 |
66 | ctx.beginPath()
67 | ctx.fillStyle = '#ffffff'
68 | BMFastPixelArtLine(
69 | ctx,
70 | 0, aCanvas.height - 5,
71 | aCanvas.width, aCanvas.height - 5
72 | )
73 |
74 | BMFastPixelArtLine(
75 | ctx,
76 | 3, 0,
77 | 3, aCanvas.height - 1
78 | )
79 |
80 | let px = 4
81 | let py = Math.floor((aCanvas.height - 5) * Math.random())
82 | let y = 0
83 | ctx.fillStyle = '#ffff00'
84 | for (let x = px + 5; x < aCanvas.width; x += 5) {
85 | y = Math.max(
86 | 0,
87 | Math.min(
88 | aCanvas.height - 6,
89 | Math.floor(py + (0.5 - Math.random()) * aCanvas.height / 3)
90 | )
91 | )
92 |
93 | BMFastPixelArtLine(ctx, px, py, x, y)
94 | px = x
95 | py = y
96 | }
97 |
98 |
99 | px = 4
100 | py = Math.floor((aCanvas.height - 5) * Math.random())
101 | y = 0
102 | ctx.fillStyle = '#ff00ff'
103 | for (let x = px + 5; x < aCanvas.width; x += 5) {
104 | y = Math.max(
105 | 0,
106 | Math.min(
107 | aCanvas.height - 6,
108 | Math.floor(py + (0.5 - Math.random()) * aCanvas.height / 3)
109 | )
110 | )
111 |
112 | BMFastPixelArtLine(ctx, px, py, x, y)
113 | px = x
114 | py = y
115 | }
116 |
117 | const hires = new MyTerminalHiRes(8, 5, aCanvas.width, aCanvas.height)
118 | const raw = hires.convert(ctx)
119 |
120 | myTerminal.write(new RawCode(raw))
121 | }
122 |
123 | function demoHires(myTerminal) {
124 | myTerminal.write(myCode()
125 | .resetAttributes()
126 | .cursor(false)
127 | .background(2)
128 | .foreground(15)
129 | .clearScreen()
130 | .background(4)
131 | .clearEndOfLine()
132 | .print("Example hi-resolution graphics\n")
133 | .background(2)
134 | .characterPage(3)
135 | .print("P".repeat(80))
136 | .characterPage(0)
137 | .locate(70, 5)
138 | .size(MyCode.SIZE_DOUBLE_HEIGHT)
139 | .reverse(true)
140 | .print("Refresh")
141 | .resetAttributes()
142 | .mouse(true)
143 | )
144 |
145 | updateGraph(myTerminal)
146 | }
147 |
--------------------------------------------------------------------------------
/demo/js/demo-load-rawfile.js:
--------------------------------------------------------------------------------
1 | /* exported loadRawFile */
2 | function loadRawFile(myTerminal, fileList) {
3 | if (fileList.length !== 1) return;
4 |
5 | const rawFile = fileList[0];
6 | const reader = new FileReader();
7 |
8 | reader.onload = (event) => {
9 | const bytes = new Uint8Array(
10 | event.target.result
11 | );
12 |
13 | myTerminal.write(new RawCode(bytes));
14 | };
15 |
16 | reader.readAsArrayBuffer(rawFile);
17 | }
--------------------------------------------------------------------------------
/demo/js/myterminal-memory.js:
--------------------------------------------------------------------------------
1 | /* exported MyTerminalCell, MyTerminalMemory */
2 | class MyTerminalCell {
3 | constructor() {
4 | this.foreground = 15
5 | this.background = 0
6 | this.pattern = 0
7 | this.func = MyTerminalCell.FUNC_AND
8 | this.underline = false
9 | this.invert = false
10 | this.blink = MyTerminalCell.BLINK_NONE
11 | this.ord = 32
12 | this.charPage = MyTerminalCell.CHAR_PAGE_0
13 | this.size = MyTerminalCell.SIZE_NORMAL
14 | this.part = MyTerminalCell.PART_TOP_LEFT
15 | }
16 | }
17 |
18 | MyTerminalCell.SIZE_NORMAL = 0
19 | MyTerminalCell.SIZE_DOUBLE_WIDTH = 1
20 | MyTerminalCell.SIZE_DOUBLE_HEIGHT = 2
21 | MyTerminalCell.SIZE_DOUBLE = 3
22 |
23 | MyTerminalCell.PART_TOP_LEFT = 0
24 | MyTerminalCell.PART_TOP_RIGHT = 1
25 | MyTerminalCell.PART_BOTTOM_LEFT = 2
26 | MyTerminalCell.PART_BOTTOM_RIGHT = 3
27 |
28 | MyTerminalCell.FUNC_AND = 0
29 | MyTerminalCell.FUNC_OR = 1
30 | MyTerminalCell.FUNC_XOR = 2
31 | MyTerminalCell.FUNC_BORDER = 3
32 |
33 | MyTerminalCell.BLINK_NONE = 0
34 | MyTerminalCell.BLINK_SLOW = 1
35 | MyTerminalCell.BLINK_NORMAL = 2
36 | MyTerminalCell.BLINK_FAST = 3
37 |
38 | MyTerminalCell.CHAR_PAGE_0 = 0
39 | MyTerminalCell.CHAR_PAGE_1 = 1
40 | MyTerminalCell.CHAR_PAGE_2 = 2
41 | MyTerminalCell.CHAR_PAGE_3 = 3
42 | MyTerminalCell.CHAR_PAGE_4 = 4
43 |
44 | class MyTerminalMemory {
45 | constructor() {
46 | this.memory = []
47 | this.rows = 51
48 | this.columns = 80
49 | this.reset()
50 | }
51 |
52 | reset() {
53 | this.memory = []
54 | for (let row = 0; row < this.rows; row++) {
55 | this.memory[row] = []
56 | for (let column = 0; column < this.columns; column++) {
57 | this.memory[row][column] = new MyTerminalCell()
58 | }
59 | }
60 | }
61 |
62 | setCell(column, row, cell) {
63 | this.memory[row][column] = cell
64 | }
65 |
66 | getCell(column, row) {
67 | return this.memory[row][column]
68 | }
69 |
70 | export() {
71 | const rawMemory = new Uint8Array(this.rows * this.columns * 4)
72 |
73 | for (let row = 0; row < this.rows; row++) {
74 | for (let column = 0; column < this.columns; column++) {
75 | let offset = row * this.columns * 4 + column * 4
76 | let cell = this.memory[row][column]
77 | let charCode
78 |
79 | switch (cell.charPage) {
80 | case MyTerminalCell.CHAR_PAGE_0:
81 | charCode = ((0x00 << 5) + cell.ord) % 1024
82 | break
83 |
84 | case MyTerminalCell.CHAR_PAGE_1:
85 | charCode = ((0x04 << 5) + cell.ord) % 1024
86 | break
87 |
88 | case MyTerminalCell.CHAR_PAGE_2:
89 | charCode = ((0x0b << 5) + cell.ord) % 1024
90 | break
91 |
92 | case MyTerminalCell.CHAR_PAGE_3:
93 | charCode = ((0x12 << 5) + cell.ord) % 1024
94 | break
95 |
96 | case MyTerminalCell.CHAR_PAGE_4:
97 | charCode = ((0x19 << 5) + cell.ord) % 1024
98 | break
99 | }
100 |
101 | rawMemory[offset + 3] = (cell.background << 4)
102 | | cell.foreground
103 | rawMemory[offset + 2] = (cell.pattern << 4)
104 | | (cell.func << 2)
105 | | ((cell.underline ? 1 : 0) << 1)
106 | | (cell.invert ? 1 : 0)
107 | rawMemory[offset + 1] = (cell.blink << 6)
108 | | (cell.part << 4)
109 | | (cell.size << 2)
110 | | ((charCode & 0x300) >> 8)
111 | rawMemory[offset + 0] = charCode & 0xff
112 | }
113 | }
114 |
115 | return rawMemory
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/demo/js/zigazou.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Inkscape Output
6 |
7 |
8 |
9 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/demo/mosaic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import random
3 | import sys
4 |
5 | myt_print = sys.stdout.buffer.write
6 |
7 | MYT = 'ISO-8859-15'
8 | CHARPAGES = [ b'\x13', b'\x14', b'\x15', b'\x16', b'\x17' ]
9 | LEFT_ROUND = b'\x174\x13'
10 | RIGHT_ROUND = b'\x171\x13'
11 |
12 | mosaic = [
13 | b'\xA0', b'\xA1', b'\xA2', b'\xA3', b'\xA4', b'\xA5', b'\xA6', b'\xA7',
14 | b'\xA8', b'\xA9', b'\xAA', b'\xAB', b'\xAC', b'\xAD', b'\xAE', b'\xAF',
15 | b'\xB0', b'\xB1', b'\xB2', b'\xB3', b'\xB4', b'\xB5', b'\xB6', b'\xB7',
16 | b'\xB8', b'\xB9', b'\xBA', b'\xBB', b'\xBC', b'\xBD', b'\xBE', b'\xBF',
17 | b'\xC0', b'\xC1', b'\xC2', b'\xC3', b'\xC4', b'\xC5', b'\xC6', b'\xC7',
18 | b'\xC8', b'\xC9', b'\xCA', b'\xCB', b'\xCC', b'\xCD', b'\xCE', b'\xCF',
19 | b'\xD0', b'\xD1', b'\xD2', b'\xD3', b'\xD4', b'\xD5', b'\xD6', b'\xD7',
20 | b'\xD8', b'\xD9', b'\xDA', b'\xDB', b'\xDC', b'\xDD', b'\xDE', b'\xDF'
21 | ]
22 |
23 | colors = [
24 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
25 | ]
26 |
27 | screen = CHARPAGES[4]
28 | for _ in range(80*50 - 1):
29 | screen += bytes([2, 64 + random.choice(colors)])
30 | screen += bytes([2, 80 + random.choice(colors)])
31 | screen += random.choice(mosaic)
32 | screen += CHARPAGES[0]
33 |
34 | myt_print(b'\x0400\x02@\x02_')
35 | myt_print(LEFT_ROUND + ("Démo: mosaïque | MyTerminal").ljust(78).encode(MYT) + RIGHT_ROUND)
36 | myt_print(b'\x02O\x02P' + screen)
--------------------------------------------------------------------------------
/demo/myterminal-colors.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/myterminal-colors.raw
--------------------------------------------------------------------------------
/demo/myterminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/myterminal.png
--------------------------------------------------------------------------------
/demo/panda-clker-free-vector-images-pixabay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/panda-clker-free-vector-images-pixabay.png
--------------------------------------------------------------------------------
/demo/panda-clker-free-vector-images-pixabay.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/demo/panda-clker-free-vector-images-pixabay.raw
--------------------------------------------------------------------------------
/demo/readme_size.txt:
--------------------------------------------------------------------------------
1 | O[93mMyTerminal
2 | [m
3 | MyTerminal is a serial terminal implemented on an FPGA.
4 |
5 | N[92mCharacteristics
6 | [m
7 | - VGA output
8 | - 1280×1024@60Hz,
9 | - 16 colors from a 512 colors/9 bits palette
10 | - 16x20 1024 character set
11 | - semi-graphic characters
12 | - fast serial input (tested at 1Mbps)
13 | - CTSRTS control signal when doing "intensive" operations
14 | - 8 characters FIFO
15 | - UTF-8 support
16 | - low cost (cheap FPGA, 9 resistor DAC etc.)
17 | - written in Verilog
18 | - inspired by Videotex and text mode video card
19 |
20 | N[92mRequirements
21 | [m
22 | - Tang SiPeed Primer (Anlogic Eagle EG4S20BG256)
23 | - Tang Dynasty 4.6
24 | - Icarus Verilog
25 | - Python 3
26 |
27 | N[92mNotes
28 | [m
29 | This is work in progress!
--------------------------------------------------------------------------------
/demo/test_gfx.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | const char f[] =
5 | "1111"
6 | "1000"
7 | "1110"
8 | "1000"
9 | "1000"
10 | ;
11 |
12 | const char half1[] =
13 | "1010"
14 | "0101"
15 | "1010"
16 | "0101"
17 | "1010"
18 | ;
19 |
20 | const char half2[] =
21 | "0101"
22 | "1010"
23 | "0101"
24 | "1010"
25 | "0101"
26 | ;
27 |
28 | char gfxchar(int pos, const char bitmap[]) {
29 | if (pos == 0) {
30 | return 128
31 | + (bitmap[0] == '1' ? 64 : 0)
32 | + (bitmap[1] == '1' ? 32 : 0)
33 | + (bitmap[2] == '1' ? 16 : 0)
34 | + (bitmap[3] == '1' ? 8 : 0)
35 | + (bitmap[4] == '1' ? 4 : 0)
36 | + (bitmap[5] == '1' ? 2 : 0)
37 | + (bitmap[6] == '1' ? 1 : 0)
38 | ;
39 | } else if (pos == 1) {
40 | return 128
41 | + (bitmap[7] == '1' ? 64 : 0)
42 | + (bitmap[8] == '1' ? 32 : 0)
43 | + (bitmap[9] == '1' ? 16 : 0)
44 | + (bitmap[10] == '1' ? 8 : 0)
45 | + (bitmap[11] == '1' ? 4 : 0)
46 | + (bitmap[12] == '1' ? 2 : 0)
47 | + (bitmap[13] == '1' ? 1 : 0)
48 | ;
49 | } else {
50 | return 128
51 | + (bitmap[14] == '1' ? 32 : 0)
52 | + (bitmap[15] == '1' ? 16 : 0)
53 | + (bitmap[16] == '1' ? 8 : 0)
54 | + (bitmap[17] == '1' ? 4 : 0)
55 | + (bitmap[18] == '1' ? 2 : 0)
56 | + (bitmap[19] == '1' ? 1 : 0)
57 | ;
58 | }
59 | }
60 |
61 | void main() {
62 | int i, j;
63 |
64 | printf("\001!\030");
65 |
66 | for (j = 0; j < 51; j++) {
67 | for (i = 0; i < (j == 50 ? 79 : 80); i++) {
68 | if ((j & 1) == 0) {
69 | printf(
70 | "%c%c%c",
71 | gfxchar(0, half1),
72 | gfxchar(1, half1),
73 | gfxchar(2, half1)
74 | );
75 | } else {
76 | printf(
77 | "%c%c%c",
78 | gfxchar(0, half2),
79 | gfxchar(1, half2),
80 | gfxchar(2, half2)
81 | );
82 | }
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/doc/character_attributes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/character_attributes.png
--------------------------------------------------------------------------------
/doc/dawnbringer-16.gpl:
--------------------------------------------------------------------------------
1 | GIMP Palette
2 | #Palette Name: DawnBringer 16
3 | #Description: Created by DawnBringer.
4 | #Colors: 16
5 | 20 12 28 140c1c
6 | 68 36 52 442434
7 | 48 52 109 30346d
8 | 78 74 78 4e4a4e
9 | 133 76 48 854c30
10 | 52 101 36 346524
11 | 208 70 72 d04648
12 | 117 113 97 757161
13 | 89 125 206 597dce
14 | 210 125 44 d27d2c
15 | 133 149 161 8595a1
16 | 109 170 44 6daa2c
17 | 210 170 153 d2aa99
18 | 109 194 202 6dc2ca
19 | 218 212 94 dad45e
20 | 222 238 214 deeed6
21 |
--------------------------------------------------------------------------------
/doc/fpga-pins.txt:
--------------------------------------------------------------------------------
1 | Gauche Ligne Droite
2 | A4 P
3 | A3 O
4 | C5 N N5
5 | B6 M P5
6 | C9 L T7
7 | B10 K R7
8 | GND J GND
9 | B14 I M10
10 | A14 H P11
11 | B15 G L10
12 | B16 F N11
13 | C16 E P12
14 | C15 D N12
15 | E16 C R16
16 | F16 B M12
17 | GND A GND
18 |
--------------------------------------------------------------------------------
/doc/gen_palette.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env, python3
2 |
3 | # This script generates a Verilog snippet generating a 16 × 9 bit RGB palette
4 | # and stores it in registers.
5 |
6 | # DawnBringer 16 color palette v1.0
7 | # https://pixeljoint.com/forum/forum_posts.asp?TID=12795
8 | dawnbringer = [
9 | (20, 12, 28),
10 | (68, 36, 52),
11 | (48, 52, 109),
12 | (78, 74, 78),
13 | (133, 76, 48),
14 | (52, 101, 36),
15 | (208, 70, 72),
16 | (117, 113, 97),
17 | (89, 125, 206),
18 | (210, 125, 44),
19 | (133, 149, 161),
20 | (109, 170, 44),
21 | (210, 170, 153),
22 | (109, 194, 202),
23 | (218, 212, 94),
24 | (222, 238, 214)
25 | ]
26 |
27 | # Convert the DawnBringer’s palette to 9 bits RGB and generate Verilog code.
28 | index = 0
29 | for (red, green, blue) in dawnbringer:
30 | print("palette[{}] <= 9'b{}_{}_{};".format(
31 | index,
32 | bin(red >> 5)[2:].rjust(3, "0"),
33 | bin(green >> 5)[2:].rjust(3, "0"),
34 | bin(blue >> 5)[2:].rjust(3, "0")
35 | ))
36 | index += 1
37 |
--------------------------------------------------------------------------------
/doc/layout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/layout.png
--------------------------------------------------------------------------------
/doc/myterminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/myterminal.png
--------------------------------------------------------------------------------
/doc/pattern00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern00.png
--------------------------------------------------------------------------------
/doc/pattern01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern01.png
--------------------------------------------------------------------------------
/doc/pattern02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern02.png
--------------------------------------------------------------------------------
/doc/pattern03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern03.png
--------------------------------------------------------------------------------
/doc/pattern04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern04.png
--------------------------------------------------------------------------------
/doc/pattern05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern05.png
--------------------------------------------------------------------------------
/doc/pattern06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern06.png
--------------------------------------------------------------------------------
/doc/pattern07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern07.png
--------------------------------------------------------------------------------
/doc/pattern08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern08.png
--------------------------------------------------------------------------------
/doc/pattern09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern09.png
--------------------------------------------------------------------------------
/doc/pattern10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern10.png
--------------------------------------------------------------------------------
/doc/pattern11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern11.png
--------------------------------------------------------------------------------
/doc/pattern12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern12.png
--------------------------------------------------------------------------------
/doc/pattern13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern13.png
--------------------------------------------------------------------------------
/doc/pattern14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/doc/pattern14.png
--------------------------------------------------------------------------------
/doc/testcurses.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import curses
3 |
4 | def main(stdscr):
5 | # Clear screen
6 | curses.start_color()
7 | stdscr.clear()
8 |
9 | for y in range(0, 4):
10 | for x in range(0, 4):
11 | color_num = x + y * 4
12 | if color_num == 0: continue
13 | curses.init_pair(color_num, color_num, curses.COLOR_BLACK)
14 |
15 | for y in range(0, 4):
16 | for x in range(0, 4):
17 | color_num = x + y * 4
18 | stdscr.addstr(
19 | y * 3, x * 10,
20 | '{} {}'.format(chr(0x05) + "3" + chr(0xE3FF) + chr(0xE3FF), color_num),
21 | curses.color_pair(color_num) | curses.A_HORIZONTAL
22 | )
23 |
24 | stdscr.refresh()
25 |
26 | curses.wrapper(main)
27 |
--------------------------------------------------------------------------------
/emulator/Makefile:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/emulator/Makefile
--------------------------------------------------------------------------------
/emulator/automaton.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/emulator/automaton.c
--------------------------------------------------------------------------------
/emulator/bitmap.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "bitmap.h"
3 |
4 | bitmap *new_bitmap() {
5 | return (bitmap *) malloc(sizeof(bitmap));
6 | }
--------------------------------------------------------------------------------
/emulator/bitmap.h:
--------------------------------------------------------------------------------
1 | #ifndef BITMAP_H
2 | #define BITMAP_H
3 |
4 | #include "myterminal.h"
5 |
6 | typedef unsigned char bitmap[MYT_TOTAL_HEIGHT][MYT_TOTAL_WIDTH];
7 |
8 | bitmap *new_bitmap();
9 | #endif
--------------------------------------------------------------------------------
/emulator/character_cell.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "character_cell.h""
4 |
5 | character_cell *new_character_cell() {
6 | character_cell *cell;
7 |
8 | cell = (character_cell *) malloc(sizeof(character_cell));
9 |
10 | if (cell) {
11 | cell->ordinal = 0x20;
12 | cell->character_size = 0x00;
13 | cell->character_part = 0x00;
14 | cell->blink = 0x00;
15 | cell->invert = false;
16 | cell->underline = false;
17 | cell->function = 0x00;
18 | cell->pattern = 0x00;
19 | cell->foreground = 0x0f;
20 | cell->background = 0x00;
21 | }
22 |
23 | return cell;
24 | }
25 |
26 | unsigned long pack(character_cell *cell) {
27 | return
28 | ( ((cell->ordinal & 0x2F) << 0)
29 | | ((cell->character_size & 0x03) << 10)
30 | | ((cell->character_part & 0x03) << 12)
31 | | ((cell->blink & 0x03) << 14)
32 | | ((cell->invert & 0x01) << 16)
33 | | ((cell->underline & 0x01) << 17)
34 | | ((cell->function & 0x03) << 18)
35 | | ((cell->pattern & 0x0F) << 20)
36 | | ((cell->foreground & 0x0F) << 24)
37 | | ((cell->background & 0x0F) << 28)
38 | );
39 | }
40 |
41 | character_cell *unpack(character_cell *cell, unsigned long value) {
42 | if (cell) {
43 | cell->ordinal = (value >> 0) & 0x2F;
44 | cell->character_size = (value >> 10) & 0x03;
45 | cell->character_part = (value >> 12) & 0x03;
46 | cell->blink = (value >> 14) & 0x03;
47 | cell->invert = (value >> 16) & 0x01;
48 | cell->underline = (value >> 17) & 0x01;
49 | cell->function = (value >> 18) & 0x03;
50 | cell->pattern = (value >> 20) & 0x0F;
51 | cell->foreground = (value >> 24) & 0x0F;
52 | cell->background = (value >> 28) & 0x0F;
53 | }
54 |
55 | return cell;
56 | }
57 |
--------------------------------------------------------------------------------
/emulator/character_cell.h:
--------------------------------------------------------------------------------
1 | #ifndef CHARACTER_CELL_H
2 | #define CHARACTER_CELL_H
3 |
4 | #include
5 |
6 | typedef struct {
7 | unsigned short ordinal;
8 | unsigned int character_size;
9 | unsigned int character_part;
10 | unsigned int blink;
11 | bool invert;
12 | bool underline;
13 | unsigned char function;
14 | unsigned char pattern;
15 | unsigned char foreground;
16 | unsigned char background;
17 | } character_cell;
18 |
19 | character_cell *new_character_cell();
20 | unsigned long pack(character_cell cell);
21 | character_cell *unpack(character_cell *cell, unsigned long value);
22 |
23 | #endif
--------------------------------------------------------------------------------
/emulator/emulator.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "myterminal.h"
4 | #include "video_memory.h"
5 | #include "bitmap.h"
6 |
7 | unsigned char palette[16][3] = {
8 | { 0, 0, 0 },
9 | { 128, 0, 0 },
10 | { 0, 128, 0 },
11 | { 128, 128, 0 },
12 | { 0, 0, 128 },
13 | { 128, 0, 128 },
14 | { 0, 128, 128 },
15 | { 192, 192, 192 },
16 | { 128, 128, 128 },
17 | { 255, 0, 0 },
18 | { 0, 255, 0 },
19 | { 255, 255, 0 },
20 | { 0, 0, 255 },
21 | { 255, 0, 255 },
22 | { 0, 255, 255 },
23 | { 255, 255, 255 }
24 | };
25 |
26 | void write_ppm(FILE *ppm, bitmap *image) {
27 | int x, y;
28 | static unsigned char color[3];
29 |
30 | if (ppm && image) {
31 | fprintf(ppm, "P6\n%d %d\n255\n", MYT_TOTAL_WIDTH, MYT_TOTAL_HEIGHT);
32 |
33 | for (y = 0; y < MYT_TOTAL_HEIGHT; y++) {
34 | for (x = 0; x < MYT_TOTAL_WIDTH; x++) {
35 | fwrite(palette[(*image)[y][x]], 1, 3, ppm);
36 | }
37 | }
38 | }
39 | }
40 |
41 | int main(int argc, char *argv[]) {
42 | video_memory *vram;
43 | bitmap *image;
44 | FILE *ppm;
45 |
46 | vram = new_video_memory();
47 | image = new_bitmap();
48 |
49 | ppm = freopen(NULL, "wb", stdout);
50 | write_ppm(ppm, image);
51 | fclose(ppm);
52 |
53 | return EXIT_SUCCESS;
54 | }
--------------------------------------------------------------------------------
/emulator/image_generator.c:
--------------------------------------------------------------------------------
1 | #include "image_generator.h"
2 | #include "video_memory.h"
3 | #include "bitmap.h"
4 | #include "character_cell.h"
5 | #include "myterminal_font.h"
6 |
7 | void generate_image(video_memory *vram, bitmap *image) {
8 | video_memory *vram;
9 | character_cell *cell;
10 | int row, real_row;
11 | int column;
12 | int char_row;
13 | int char_col;
14 | int x;
15 | int y;
16 | bool pixel_mask;
17 | unsigned short char_bitmap;
18 |
19 | if (!(vram && image)) return;
20 |
21 | for (row = 0; row < MYT_ROWS; row++) {
22 | real_row = (vram->top_row + row) % MYT_ROWS;
23 |
24 | for (column = 0; column < MYT_COLUMNS; column++) {
25 | cell = vram->cells[real_row][column];
26 |
27 | for (char_row = 0; char_row < MYT_CHARACTER_HEIGHT; char_row++) {
28 | char_bitmap = myterminal_font[cell->ordinal][char_row];
29 | for (char_col = 0; char_col < MYT_CHARACTER_WIDTH; char_col++) {
30 | x = column * MYT_CHARACTER_WIDTH + char_col;
31 | y = row * MYT_CHARACTER_HEIGHT + char_row;
32 | pixel_mask = 1 << (MYT_CHARACTER_WIDTH - 1 - char_col);
33 | (*image)[y][x] = (char_bitmap & pixel_mask)
34 | ? cell->foreground
35 | : cell->background;
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/emulator/image_generator.h:
--------------------------------------------------------------------------------
1 | #ifndef IMAGE_GENERATOR_H
2 | #define IMAGE_GENERATOR_H
3 |
4 | #include "video_memory.h"
5 | #include "bitmap.h"
6 |
7 | void generate_image(video_memory *vram, bitmap *image);
8 |
9 | #endif
--------------------------------------------------------------------------------
/emulator/myterminal.h:
--------------------------------------------------------------------------------
1 | #ifndef MYTERMINAL_H
2 | #define MYTERMINAL_H
3 |
4 | #define MYT_COLUMNS (80)
5 | #define MYT_ROWS (51)
6 | #define MYT_CHARACTER_WIDTH (16)
7 | #define MYT_CHARACTER_HEIGHT (20)
8 | #define MYT_TOTAL_WIDTH (1280)
9 | #define MYT_TOTAL_HEIGHT (1024)
10 |
11 | #endif
--------------------------------------------------------------------------------
/emulator/myterminal_font.h:
--------------------------------------------------------------------------------
1 | #ifndef MYTERMINAL_FONT_H
2 | #define MYTERMINAL_FONT_H
3 | unsigned short myterminal_font[1024][20];
4 | #endif
5 |
--------------------------------------------------------------------------------
/emulator/png_to_c.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from PIL import Image
3 |
4 | # Generate a Verilog file that can be used as a font RAM simulator.
5 |
6 | # Character dimension
7 | CHAR_HEIGHT = 20
8 | CHAR_WIDTH = 16
9 |
10 | # Bitmap dimension
11 | GRID_WIDTH = 1024
12 | GRID_HEIGHT = 320
13 |
14 | CHAR_COUNT = (GRID_WIDTH // CHAR_WIDTH) * (GRID_HEIGHT // CHAR_HEIGHT)
15 |
16 | def getbit(rgbs, x, y):
17 | r, g, b = rgbs.getpixel((x, y))
18 | if r < 32 and g < 32 and b < 32:
19 | return 1
20 |
21 | return 0
22 |
23 | def getcharwords(rgbs, i, j):
24 | x = i * CHAR_WIDTH
25 | words = []
26 |
27 | for y in range(j * CHAR_HEIGHT, (j + 1) * CHAR_HEIGHT):
28 | word = 0
29 | for i in range(0, CHAR_WIDTH):
30 | word += getbit(rgbs, x + i, y) << (CHAR_WIDTH - 1 - i)
31 |
32 | words.append(word)
33 |
34 | return words
35 |
36 | # Load the image
37 | charset = Image.open("../font/extended_videotex.png")
38 |
39 | # Convert the image to RGB
40 | rgbs = charset.convert('RGB')
41 |
42 | with open('myterminal_font.h', 'w') as f:
43 | f.write("#ifndef MYTERMINAL_FONT_H\n")
44 | f.write("#define MYTERMINAL_FONT_H\n")
45 | f.write("unsigned short myterminal_font[{}][{}];\n".format(
46 | CHAR_COUNT,
47 | CHAR_HEIGHT
48 | ))
49 | f.write("#endif\n")
50 |
51 | with open('myterminal_font.c', 'w') as f:
52 | f.write("#include \"myterminal_font.h\"\n")
53 | f.write("\n")
54 |
55 | f.write("unsigned short myterminal_font[{}][{}] = {}\n".format(
56 | CHAR_COUNT,
57 | CHAR_HEIGHT,
58 | "{"
59 | ))
60 |
61 | for i in range(0, GRID_WIDTH // CHAR_WIDTH):
62 | for j in range(0, CHAR_WIDTH):
63 | f.write(" {\n")
64 | for word in getcharwords(rgbs, i, j):
65 | f.write(" {},\n".format(word))
66 | f.write(" },\n")
67 |
68 | f.write("};\n")
69 |
--------------------------------------------------------------------------------
/emulator/video_memory.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "myterminal.h"
3 | #include "character_cell.h"
4 | #include "video_memory.h"
5 |
6 | typedef struct {
7 | int top_row;
8 | bool cursor_visible;
9 | unsigned long cells[MYT_ROWS][MYT_COLUMNS];
10 | } video_memory;
11 |
12 | video_memory *new_video_memory() {
13 | video_memory *vram;
14 | int row;
15 | int column;
16 |
17 | vram = (video_memory *) malloc(sizeof(video_memory));
18 |
19 | if (vram) {
20 | vram->top_row = 0;
21 | vram->cursor_visible = true;
22 |
23 | for (row = 0; row < MYT_ROWS; row++) {
24 | for (column = 0; column < MYT_COLUMNS; column++) {
25 | vram->cells[row][column] = new_character_cell();
26 | }
27 | }
28 | }
29 |
30 | return vram;
31 | }
32 |
--------------------------------------------------------------------------------
/emulator/video_memory.h:
--------------------------------------------------------------------------------
1 | #ifndef VIDEO_MEMORY_H
2 | #define VIDEO_MEMORY_H
3 |
4 | #include
5 | #include "myterminal.h"
6 |
7 | typedef struct {
8 | int top_row;
9 | bool cursor_visible;
10 | unsigned long cells[MYT_ROWS][MYT_COLUMNS];
11 | } video_memory;
12 |
13 | video_memory *new_video_memory();
14 |
15 | #endif
--------------------------------------------------------------------------------
/falsepath.rpt:
--------------------------------------------------------------------------------
1 | =========================================================================================================
2 | Auto created by the td v5.0.38657
3 | @Copy Right: Shanghai Anlogic Infotech, 2011 - 2021.
4 | Wed Oct 20 08:09:21 2021
5 | =========================================================================================================
6 |
7 |
8 | Top Model: myterminal
9 | Device: eagle_s20
10 | Timing Constraint File: src/myterminal.sdc
11 | STA Level: Detail
12 |
13 | ---------------------------------------------------------------------------------------------------------
14 |
15 | ---------------------------------------------------------------------------------------------------------
16 |
--------------------------------------------------------------------------------
/falsepath.tsm:
--------------------------------------------------------------------------------
1 | eagle_s20
2 | 12 0 0 0 0 0 0
3 | 0.000 0.000 myterminal eagle_s20 BG256 Detail 1 0
4 |
5 | Timing group statistics:
6 |
7 |
--------------------------------------------------------------------------------
/font/Makefile:
--------------------------------------------------------------------------------
1 | extended_videotex.mif: extended_videotex.png
2 | python3 png_to_mif.py
3 |
4 | extended_videotex.png: extended_videotex.svg
5 | inkscape -f extended_videotex.svg -e extended_videotex.png
6 |
7 | font_sim.v: extended_videotex.png
8 | python3 png_to_sim.py
9 |
10 | clean:
11 | rm -f extended_videotex.png extended_videotex.mif font_sim.v
12 |
--------------------------------------------------------------------------------
/font/charpage-0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/charpage-0.pdf
--------------------------------------------------------------------------------
/font/charpage-1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/charpage-1.pdf
--------------------------------------------------------------------------------
/font/charpage-2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/charpage-2.pdf
--------------------------------------------------------------------------------
/font/charpage-3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/charpage-3.pdf
--------------------------------------------------------------------------------
/font/charpage-4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/charpage-4.pdf
--------------------------------------------------------------------------------
/font/charpage.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/charpage.pdf
--------------------------------------------------------------------------------
/font/extended_videotex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/font/extended_videotex.png
--------------------------------------------------------------------------------
/font/png_to_mif.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from PIL import Image
3 |
4 | # Generate a MIF file containing the font ROM of our extended videotex character
5 | # set. The MIF file can then be used as an initialization file for FPGA project.
6 |
7 | # Character dimension
8 | CHAR_HEIGHT = 20
9 | CHAR_WIDTH = 16
10 |
11 | # Bitmap dimension
12 | GRID_WIDTH = 1024
13 | GRID_HEIGHT = 320
14 |
15 | CHAR_COUNT = (GRID_WIDTH // CHAR_WIDTH) * (GRID_HEIGHT // CHAR_HEIGHT)
16 |
17 | def getbit(rgbs, x, y):
18 | r, g, b = rgbs.getpixel((x, y))
19 | if r < 32 and g < 32 and b < 32:
20 | return 1
21 |
22 | return 0
23 |
24 | def getcharwords(rgbs, i, j):
25 | x = i * CHAR_WIDTH
26 | words = []
27 |
28 | for y in range(j * CHAR_HEIGHT, (j + 1) * CHAR_HEIGHT):
29 | word = 0
30 | for i in range(0, CHAR_WIDTH):
31 | word += getbit(rgbs, x + i, y) << (CHAR_WIDTH - 1 - i)
32 |
33 | words.append(word)
34 |
35 | return words
36 |
37 | # Load the image
38 | charset = Image.open("extended_videotex.png")
39 |
40 | # Convert the image to RGB
41 | rgbs = charset.convert('RGB')
42 |
43 | allwords = []
44 | for i in range(0, GRID_WIDTH // CHAR_WIDTH):
45 | for j in range(0, CHAR_WIDTH):
46 | for word in getcharwords(rgbs, i, j):
47 | allwords.append(word)
48 |
49 | with open('extended_videotex.mif', 'w') as f:
50 | f.write("DEPTH = {};\n".format(CHAR_HEIGHT * CHAR_COUNT))
51 | f.write("WIDTH = {};\n\n".format(CHAR_WIDTH))
52 |
53 | f.write("ADDRESS_RADIX = HEX;\n")
54 | f.write("DATA_RADIX = BIN;\n\n")
55 |
56 | f.write("CONTENT\n")
57 | f.write("BEGIN\n")
58 |
59 | offset = 0
60 | for word in allwords:
61 | if offset % CHAR_HEIGHT == 0:
62 | f.write("-- Character {}\n".format(offset // CHAR_HEIGHT))
63 |
64 | f.write("{}: {};\n".format(
65 | hex(offset)[2:].rjust(6, "0"),
66 | bin(word)[2:].rjust(CHAR_WIDTH, "0")
67 | ))
68 |
69 | offset += 1
70 |
71 | f.write("END;\n")
72 |
--------------------------------------------------------------------------------
/font/png_to_sim.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from PIL import Image
3 |
4 | # Generate a Verilog file that can be used as a font RAM simulator.
5 |
6 | # Character dimension
7 | CHAR_HEIGHT = 20
8 | CHAR_WIDTH = 16
9 |
10 | # Bitmap dimension
11 | GRID_WIDTH = 1024
12 | GRID_HEIGHT = 320
13 |
14 | CHAR_COUNT = (GRID_WIDTH // CHAR_WIDTH) * (GRID_HEIGHT // CHAR_HEIGHT)
15 |
16 | def getbit(rgbs, x, y):
17 | r, g, b = rgbs.getpixel((x, y))
18 | if r < 32 and g < 32 and b < 32:
19 | return 1
20 |
21 | return 0
22 |
23 | def getcharwords(rgbs, i, j):
24 | x = i * CHAR_WIDTH
25 | words = []
26 |
27 | for y in range(j * CHAR_HEIGHT, (j + 1) * CHAR_HEIGHT):
28 | word = 0
29 | for i in range(0, CHAR_WIDTH):
30 | word += getbit(rgbs, x + i, y) << (CHAR_WIDTH - 1 - i)
31 |
32 | words.append(word)
33 |
34 | return words
35 |
36 | # Load the image
37 | charset = Image.open("extended_videotex.png")
38 |
39 | # Convert the image to RGB
40 | rgbs = charset.convert('RGB')
41 |
42 | allwords = []
43 | for i in range(0, GRID_WIDTH // CHAR_WIDTH):
44 | for j in range(0, CHAR_WIDTH):
45 | for word in getcharwords(rgbs, i, j):
46 | allwords.append(word)
47 |
48 | with open('font_sim.v', 'w') as f:
49 | f.write("module font (\n")
50 | f.write(" input wire clk,\n")
51 | f.write(" input wire [14:0] font_address,\n")
52 | f.write(" output reg [15:0] char_row_bitmap\n")
53 | f.write(");\n")
54 | f.write("\n")
55 |
56 | f.write("reg [29:0] fifo = 30'd0;\n")
57 | f.write("always @(posedge clk) fifo <= { font_address, fifo[29:15] };\n")
58 | f.write("\n")
59 |
60 | f.write("always @(posedge clk)\n")
61 | f.write(" case (fifo[14:0])\n")
62 |
63 | offset = 0
64 | for word in allwords:
65 | f.write(" 15'h{}: char_row_bitmap <= 16'b{};\n".format(
66 | hex(offset)[2:].rjust(4, "0"),
67 | bin(word)[2:].rjust(CHAR_WIDTH, "0")
68 | ))
69 |
70 | offset += 1
71 |
72 | f.write(" endcase\n")
73 | f.write("\n")
74 |
75 | f.write("endmodule\n")
76 |
--------------------------------------------------------------------------------
/myterminal.bit:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/myterminal.bit
--------------------------------------------------------------------------------
/myterminal_devicesetting.cfg:
--------------------------------------------------------------------------------
1 | Device Configuration Summary:
2 | **Option** **Current Value**
3 | hswapen 0
4 | mclk_freq_div 5MHz
5 | active_done 0
6 | cascade_mode None
7 | security 0
8 | auto_clear_en 0
9 | persist_bit 0
10 | done_sync 0
11 | done_phase 100
12 | goe_phase 101
13 | gsr_phase 110
14 | gwd_phase 110
15 | ch_dedicate_0 gpio
16 | ch_dedicate_1 gpio
17 | ch_dedicate_2 gpio
18 | ch_dedicate_3 gpio
19 | ch_dedicate_4 gpio
20 | ch_dedicate_5 gpio
21 | ch_dedicate_6 gpio
22 | ch_dedicate_7 gpio
23 | cso_b_cclk_mosi_miso_dout gpio
24 | done gpio
25 | initn gpio
26 | program_b gpio
27 | tdi_tms_tck_tdo dedicate
28 |
--------------------------------------------------------------------------------
/myterminal_place.area:
--------------------------------------------------------------------------------
1 | standard
2 | ***Report Model: myterminal***
3 |
4 | IO Statistics
5 | #IO 20
6 | #input 5
7 | #output 13
8 | #inout 2
9 |
10 | Utilization Statistics
11 | #lut 3767 out of 19600 19.22%
12 | #reg 1646 out of 19600 8.40%
13 | #le 3767
14 | #lut only 2121 out of 3767 56.30%
15 | #reg only 0 out of 3767 0.00%
16 | #lut® 1646 out of 3767 43.70%
17 | #dsp 0 out of 29 0.00%
18 | #bram 14 out of 64 21.88%
19 | #bram9k 14
20 | #fifo9k 0
21 | #bram32k 10 out of 16 62.50%
22 | #pad 20 out of 189 10.58%
23 | #ireg 0
24 | #oreg 0
25 | #treg 0
26 | #pll 1 out of 4 25.00%
27 |
28 |
29 | Detailed IO Report
30 |
31 | Name Direction Location IOStandard DriveStrength PullType PackReg
32 | ps2_0_clock INPUT P11 LVCMOS33 N/A PULLUP NONE
33 | ps2_0_data INPUT L10 LVCMOS33 N/A PULLUP NONE
34 | refclk INPUT K14 LVCMOS33 N/A PULLUP NONE
35 | reset_n INPUT T2 LVCMOS33 N/A PULLUP NONE
36 | rx INPUT P12 LVCMOS33 N/A PULLUP NONE
37 | cts OUTPUT N12 LVCMOS33 8 NONE NONE
38 | tx OUTPUT N11 LVCMOS33 8 NONE NONE
39 | vga_blue[2] OUTPUT B14 LVCMOS33 8 NONE NONE
40 | vga_blue[1] OUTPUT A3 LVCMOS33 8 NONE NONE
41 | vga_blue[0] OUTPUT C5 LVCMOS33 8 NONE NONE
42 | vga_green[2] OUTPUT C9 LVCMOS33 8 NONE NONE
43 | vga_green[1] OUTPUT B6 LVCMOS33 8 NONE NONE
44 | vga_green[0] OUTPUT B10 LVCMOS33 8 NONE NONE
45 | vga_hsync OUTPUT P5 LVCMOS33 8 NONE NONE
46 | vga_red[2] OUTPUT A14 LVCMOS33 8 NONE NONE
47 | vga_red[1] OUTPUT B15 LVCMOS33 8 NONE NONE
48 | vga_red[0] OUTPUT A4 LVCMOS33 8 NONE NONE
49 | vga_vsync OUTPUT N5 LVCMOS33 8 NONE NONE
50 | ps2_1_clock INOUT M10 LVCMOS33 8 PULLUP NONE
51 | ps2_1_data INOUT R7 LVCMOS33 8 PULLUP NONE
52 |
53 | Report Hierarchy Area:
54 | +--------------------------------------------------------------------+
55 | |Instance |Module |le |lut |ripple |seq |bram |dsp |
56 | +--------------------------------------------------------------------+
57 | |top |myterminal |3767 |3525 |242 |1646 |24 |0 |
58 | +--------------------------------------------------------------------+
59 |
--------------------------------------------------------------------------------
/src/constant.v:
--------------------------------------------------------------------------------
1 | localparam
2 | // TRUE/FALSE
3 | TRUE = 1'b1,
4 | FALSE = 1'b0,
5 |
6 | // TRUE/FALSE inverted
7 | TRUE_n = 1'b0,
8 | FALSE_n = 1'b1,
9 |
10 | // HIGH/LOW
11 | HIGH = 1'b1,
12 | LOW = 1'b0;
13 |
--------------------------------------------------------------------------------
/src/font.v:
--------------------------------------------------------------------------------
1 | module font #(
2 | parameter CHAR_WIDTH = 'd16,
3 | parameter ROWS_PER_CHAR = 'd20,
4 | parameter CHARS = 'd1024,
5 | parameter RAM_WIDTH = 15
6 | ) (
7 | input wire clk,
8 |
9 | input wire [RAM_WIDTH - 1:0] font_address,
10 | output wire [CHAR_WIDTH - 1:0] char_row_bitmap
11 | );
12 |
13 | wire [CHAR_WIDTH - 1:0] dummy_input = 'd0;
14 | wire dummy_write_enable = 1'b0;
15 | wire dummy_reset = 'd0;
16 |
17 | font_ram font_ram (
18 | .doa (char_row_bitmap),
19 | .dia (dummy_input),
20 | .addra (font_address),
21 | .clka (clk),
22 | .wea (dummy_write_enable),
23 | .rsta (dummy_reset)
24 | );
25 |
26 | endmodule
27 |
--------------------------------------------------------------------------------
/src/four_byte.v:
--------------------------------------------------------------------------------
1 | module four_byte (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire [7:0] current_byte,
6 | input wire ie,
7 |
8 | output reg [31:0] value,
9 | output reg oe
10 | );
11 |
12 | localparam
13 | TRUE = 'd1,
14 | FALSE = 'd0;
15 |
16 | reg [2:0] count;
17 | reg [31:0] bytes;
18 | always @(posedge clk)
19 | if (reset) begin
20 | count <= 'd0;
21 | bytes <= 'd0;
22 | oe <= FALSE;
23 | end else if (ie == TRUE) begin
24 | if (count == 'd3) begin
25 | oe <= TRUE;
26 | value <= { bytes[23:0], current_byte };
27 | count <= 'd0;
28 | end else begin
29 | bytes <= { bytes[23:0], current_byte };
30 | oe <= FALSE;
31 | count <= count + 'd1;
32 | end
33 | end else
34 | oe <= FALSE;
35 | endmodule
--------------------------------------------------------------------------------
/src/muxer.v:
--------------------------------------------------------------------------------
1 | module muxer #(
2 | parameter DATA_WIDTH = 8
3 | ) (
4 | input wire clk,
5 | input wire reset,
6 |
7 | input wire [DATA_WIDTH - 1:0] in_data_0,
8 | input wire in_data_0_available,
9 | output wire in_data_0_ready,
10 |
11 | input wire [DATA_WIDTH - 1:0] in_data_1,
12 | input wire in_data_1_available,
13 | output wire in_data_1_ready,
14 |
15 | input wire receiver_ready,
16 | output reg [DATA_WIDTH - 1:0] out_data,
17 | output reg out_data_available
18 | );
19 |
20 | `include "constant.v"
21 |
22 | reg [1:0] current_channel = 1'd0;
23 | assign in_data_0_ready =
24 | current_channel & receiver_ready & ~out_data_available;
25 |
26 | assign in_data_1_ready =
27 | ~current_channel & receiver_ready & ~out_data_available;
28 |
29 | always @(posedge clk)
30 | if (reset) begin
31 | current_channel <= 1'd0;
32 | out_data_available <= FALSE;
33 | end else begin
34 | if (current_channel == 0) begin
35 | if (in_data_0_available) begin
36 | out_data_available <= TRUE;
37 | out_data <= in_data_0;
38 | end else begin
39 | out_data_available <= FALSE;
40 | current_channel <= 1;
41 | end
42 | end else begin
43 | if (in_data_1_available) begin
44 | out_data_available <= TRUE;
45 | out_data <= in_data_1;
46 | end else begin
47 | out_data_available <= FALSE;
48 | current_channel <= 0;
49 | end
50 | end
51 | end
52 |
53 | endmodule
--------------------------------------------------------------------------------
/src/myterminal.adc:
--------------------------------------------------------------------------------
1 | set_pin_assignment { refclk } { LOCATION = K14; IOSTANDARD = LVCMOS33; }
2 | set_pin_assignment { reset_n } { LOCATION = T2; IOSTANDARD = LVCMOS33; }
3 |
4 | ##set_pin_assignment { rx } { LOCATION = C9; IOSTANDARD = LVCMOS33; }
5 | ##set_pin_assignment { tx } { LOCATION = B6; IOSTANDARD = LVCMOS33; }
6 | #set_pin_assignment { rx } { LOCATION = A14; IOSTANDARD = LVCMOS33; }
7 | #set_pin_assignment { tx } { LOCATION = B14; IOSTANDARD = LVCMOS33; }
8 | #set_pin_assignment { cts } { LOCATION = B10; IOSTANDARD = LVCMOS33; }
9 |
10 | #set_pin_assignment { vga_blue[0] } { LOCATION = N5; IOSTANDARD = LVCMOS33; }
11 | #set_pin_assignment { vga_blue[1] } { LOCATION = P5; IOSTANDARD = LVCMOS33; }
12 | #set_pin_assignment { vga_blue[2] } { LOCATION = T7; IOSTANDARD = LVCMOS33; }
13 | #set_pin_assignment { vga_green[0] } { LOCATION = R7; IOSTANDARD = LVCMOS33; }
14 | #set_pin_assignment { vga_green[1] } { LOCATION = P11; IOSTANDARD = LVCMOS33; }
15 | #set_pin_assignment { vga_green[2] } { LOCATION = M10; IOSTANDARD = LVCMOS33; }
16 | #set_pin_assignment { vga_hsync } { LOCATION = N11; IOSTANDARD = LVCMOS33; }
17 | #set_pin_assignment { vga_red[0] } { LOCATION = A4; IOSTANDARD = LVCMOS33; }
18 | #set_pin_assignment { vga_red[1] } { LOCATION = A3; IOSTANDARD = LVCMOS33; }
19 | #set_pin_assignment { vga_red[2] } { LOCATION = C5; IOSTANDARD = LVCMOS33; }
20 | #set_pin_assignment { vga_vsync } { LOCATION = L10; IOSTANDARD = LVCMOS33; }
21 |
22 | # MAX3232
23 | #set_pin_assignment { rx } { LOCATION = M12; IOSTANDARD = LVCMOS33; }
24 | #set_pin_assignment { tx } { LOCATION = R16; IOSTANDARD = LVCMOS33; }
25 |
26 | # FTDI232
27 | set_pin_assignment { rx } { LOCATION = P12; IOSTANDARD = LVCMOS33; }
28 | set_pin_assignment { tx } { LOCATION = N11; IOSTANDARD = LVCMOS33; }
29 | set_pin_assignment { cts } { LOCATION = N12; IOSTANDARD = LVCMOS33; }
30 |
31 | set_pin_assignment { vga_blue[0] } { LOCATION = C5; IOSTANDARD = LVCMOS33; }
32 | set_pin_assignment { vga_blue[1] } { LOCATION = A3; IOSTANDARD = LVCMOS33; }
33 | set_pin_assignment { vga_blue[2] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }
34 | set_pin_assignment { vga_green[0] } { LOCATION = B10; IOSTANDARD = LVCMOS33; }
35 | set_pin_assignment { vga_green[1] } { LOCATION = B6; IOSTANDARD = LVCMOS33; }
36 | set_pin_assignment { vga_green[2] } { LOCATION = C9; IOSTANDARD = LVCMOS33; }
37 | set_pin_assignment { vga_hsync } { LOCATION = P5; IOSTANDARD = LVCMOS33; }
38 | set_pin_assignment { vga_red[0] } { LOCATION = A4; IOSTANDARD = LVCMOS33; }
39 | set_pin_assignment { vga_red[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }
40 | set_pin_assignment { vga_red[2] } { LOCATION = A14; IOSTANDARD = LVCMOS33; }
41 | set_pin_assignment { vga_vsync } { LOCATION = N5; IOSTANDARD = LVCMOS33; }
42 |
43 | set_pin_assignment { ps2_0_data } { LOCATION = L10; IOSTANDARD = LVCMOS33; }
44 | set_pin_assignment { ps2_0_clock } { LOCATION = P11; IOSTANDARD = LVCMOS33; }
45 | set_pin_assignment { ps2_1_data } { LOCATION = R7; IOSTANDARD = LVCMOS33; }
46 | set_pin_assignment { ps2_1_clock } { LOCATION = M10; IOSTANDARD = LVCMOS33; }
47 |
--------------------------------------------------------------------------------
/src/myterminal.sdc:
--------------------------------------------------------------------------------
1 | create_clock -name "refclk" -period 41.66667 [get_ports refclk]
2 | derive_pll_clocks
--------------------------------------------------------------------------------
/src/ps2_keyboard_state.v:
--------------------------------------------------------------------------------
1 | module ps2_keyboard_state (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire scan_code_ready,
6 | input wire [7:0] scan_code_in,
7 |
8 | output reg keyboard_state_ready = 0,
9 | output reg [7:0] scan_code_out,
10 | output reg scan_code_extended = 0,
11 | output wire keyboard_shift,
12 | output reg keyboard_alt = 0,
13 | output reg keyboard_altgr = 0,
14 | output wire keyboard_ctrl,
15 | output wire keyboard_meta
16 | );
17 |
18 | `include "ps2_scan_code_set2_fr.v"
19 |
20 | // Definitions to make code easier to read and understand.
21 | localparam
22 | HIGH = 1'b1,
23 | LOW = 1'b0,
24 |
25 | TRUE = HIGH,
26 | FALSE = LOW;
27 |
28 | reg keyboard_shift_left = FALSE;
29 | reg keyboard_shift_right = FALSE;
30 | assign keyboard_shift = keyboard_shift_left | keyboard_shift_right;
31 |
32 | reg keyboard_ctrl_left = FALSE;
33 | reg keyboard_ctrl_right = FALSE;
34 | assign keyboard_ctrl = keyboard_ctrl_left | keyboard_ctrl_right;
35 |
36 | reg keyboard_meta_left = FALSE;
37 | reg keyboard_meta_right = FALSE;
38 | assign keyboard_meta = keyboard_meta_left | keyboard_meta_right;
39 |
40 | localparam
41 | STATE_IDLE = 'd0,
42 | STATE_E0 = 'd1,
43 | STATE_E1_1 = 'd2,
44 | STATE_E1_2 = 'd3,
45 | STATE_BREAK = 'd4,
46 | STATE_E0_BREAK = 'd5,
47 | STATE_E1_1_BREAK = 'd6,
48 | STATE_E1_2_BREAK = 'd7;
49 |
50 | reg [2:0] state;
51 |
52 | task state_idle;
53 | begin
54 | state <= STATE_IDLE;
55 | case (scan_code_in)
56 | SCAN_SHIFT_LEFT: keyboard_shift_left <= TRUE;
57 | SCAN_SHIFT_RIGHT: keyboard_shift_right <= TRUE;
58 | SCAN_CTRL_LEFT: keyboard_ctrl_left <= TRUE;
59 | SCAN_ALT: keyboard_alt <= TRUE;
60 | SCAN_E0: state <= STATE_E0;
61 | SCAN_E1: state <= STATE_E1_1;
62 | SCAN_BREAK: state <= STATE_BREAK;
63 | default: begin
64 | keyboard_state_ready <= TRUE;
65 | scan_code_extended <= FALSE;
66 | scan_code_out <= scan_code_in;
67 | end
68 | endcase
69 | end
70 | endtask
71 |
72 | task state_e0;
73 | begin
74 | state <= STATE_IDLE;
75 | case (scan_code_in)
76 | SCAN_E0_IGNORE: state <= STATE_IDLE;
77 | SCAN_E0_CTRL_RIGHT: keyboard_ctrl_right <= TRUE;
78 | SCAN_E0_META_LEFT: keyboard_meta_left <= TRUE;
79 | SCAN_E0_META_RIGHT: keyboard_meta_right <= TRUE;
80 | SCAN_E0_ALTGR: keyboard_altgr <= TRUE;
81 | SCAN_BREAK: state <= STATE_E0_BREAK;
82 | default: begin
83 | keyboard_state_ready <= TRUE;
84 | scan_code_extended <= TRUE;
85 | scan_code_out <= scan_code_in;
86 | end
87 | endcase
88 | end
89 | endtask
90 |
91 | task state_e1_1;
92 | case (scan_code_in)
93 | SCAN_BREAK: state <= STATE_E1_1_BREAK;
94 | SCAN_E1_PAUSE_1: state <= STATE_E1_2;
95 | default: state <= STATE_IDLE;
96 | endcase
97 | endtask
98 |
99 | task state_e1_2;
100 | begin
101 | state <= STATE_IDLE;
102 | case (scan_code_in)
103 | SCAN_BREAK: state <= STATE_E1_2_BREAK;
104 | SCAN_E1_PAUSE_2: begin
105 | keyboard_state_ready <= TRUE;
106 | scan_code_extended <= TRUE;
107 | scan_code_out <= SCAN_E0_PAUSE;
108 | end
109 | default: state <= STATE_IDLE;
110 | endcase
111 | end
112 | endtask
113 |
114 | task state_break;
115 | begin
116 | state <= STATE_IDLE;
117 | case (scan_code_in)
118 | SCAN_SHIFT_LEFT: keyboard_shift_left <= FALSE;
119 | SCAN_SHIFT_RIGHT: keyboard_shift_right <= FALSE;
120 | SCAN_CTRL_LEFT: keyboard_ctrl_left <= FALSE;
121 | SCAN_ALT: keyboard_alt <= FALSE;
122 | endcase
123 | end
124 | endtask
125 |
126 | task state_e0_break;
127 | begin
128 | state <= STATE_IDLE;
129 | case (scan_code_in)
130 | SCAN_E0_CTRL_RIGHT: keyboard_ctrl_right <= FALSE;
131 | SCAN_E0_META_LEFT: keyboard_meta_left <= FALSE;
132 | SCAN_E0_META_RIGHT: keyboard_meta_right <= FALSE;
133 | SCAN_E0_ALTGR: keyboard_altgr <= FALSE;
134 | endcase
135 | end
136 | endtask
137 |
138 | task state_e1_1_break;
139 | state <= STATE_E1_2;
140 | endtask
141 |
142 | task state_e1_2_break;
143 | state <= STATE_IDLE;
144 | endtask
145 |
146 | always @(posedge clk)
147 | if (reset) begin
148 | state <= STATE_IDLE;
149 | keyboard_state_ready <= FALSE;
150 | scan_code_out <= 'd0;
151 | scan_code_extended <= FALSE;
152 | keyboard_shift_right <= FALSE;
153 | keyboard_shift_left <= FALSE;
154 | keyboard_alt <= FALSE;
155 | keyboard_altgr <= FALSE;
156 | keyboard_ctrl_left <= FALSE;
157 | keyboard_ctrl_right <= FALSE;
158 | keyboard_meta_left <= FALSE;
159 | keyboard_meta_right <= FALSE;
160 | end else begin
161 | keyboard_state_ready <= FALSE;
162 | if (scan_code_ready) begin
163 | case (state)
164 | STATE_IDLE: state_idle();
165 | STATE_E0: state_e0();
166 | STATE_E1_1: state_e1_1();
167 | STATE_E1_2: state_e1_2();
168 | STATE_BREAK: state_break();
169 | STATE_E0_BREAK: state_e0_break();
170 | STATE_E1_1_BREAK: state_e1_1_break();
171 | STATE_E1_2_BREAK: state_e1_2_break();
172 | endcase
173 | end
174 | end
175 |
176 | endmodule
177 |
--------------------------------------------------------------------------------
/src/ps2_mouse_ascii.v:
--------------------------------------------------------------------------------
1 | module ps2_mouse_ascii (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire [1:0] mouse_control,
6 |
7 | input wire keyboard_shift,
8 | input wire keyboard_alt,
9 | input wire keyboard_ctrl,
10 | input wire keyboard_meta,
11 |
12 | input wire mouse_state_ready,
13 | input wire button_left,
14 | input wire button_middle,
15 | input wire button_right,
16 | input wire [6:0] x_text,
17 | input wire [5:0] y_text,
18 | input wire [10:0] x_screen,
19 | input wire [9:0] y_screen,
20 |
21 | output reg [31:0] sequence_out = 0,
22 | output reg [2:0] sequence_out_count = 0
23 | );
24 |
25 | `include "constant.v"
26 |
27 | wire [7:0] event_modifier = {
28 | HIGH,
29 | keyboard_meta,
30 | keyboard_alt,
31 | keyboard_ctrl,
32 | keyboard_shift,
33 | button_middle,
34 | button_right,
35 | button_left
36 | };
37 |
38 | wire [7:0] event_x = { HIGH, x_text };
39 | wire [7:0] event_y = { HIGH, LOW, y_text };
40 |
41 | task send_nothing;
42 | begin
43 | sequence_out <= 32'h00000000;
44 | sequence_out_count <= 'd0;
45 | end
46 | endtask
47 |
48 | reg [23:0] previous_sequence = 24'h000000;
49 | task send_event;
50 | begin
51 | sequence_out <= {
52 | 8'h1E,
53 | event_x,
54 | event_y,
55 | event_modifier
56 | };
57 |
58 | previous_sequence <= { event_x, event_y, event_modifier };
59 |
60 | sequence_out_count <= 'd4;
61 | end
62 | endtask
63 |
64 | wire state_is_new = previous_sequence != { event_x, event_y, event_modifier };
65 | wire mouse_enabled = mouse_control != 'd0;
66 |
67 | always @(posedge clk)
68 | if (reset) begin
69 | previous_sequence <= 'd0;
70 | send_nothing();
71 | end else if (mouse_state_ready && mouse_enabled && state_is_new)
72 | send_event();
73 | else
74 | send_nothing();
75 | endmodule
76 |
--------------------------------------------------------------------------------
/src/ps2_mouse_state2.v:
--------------------------------------------------------------------------------
1 | module ps2_mouse_state2 (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire left_button,
6 | input wire right_button,
7 | input wire middle_button,
8 | input wire [8:0] x_increment,
9 | input wire [8:0] y_increment,
10 | input wire data_ready,
11 | output reg read,
12 |
13 | output reg mouse_state_ready = 0,
14 | output reg button_left = 0,
15 | output reg button_middle = 0,
16 | output reg button_right = 0,
17 | output reg [6:0] x_text = 0,
18 | output reg [5:0] y_text = 0,
19 | output reg [10:0] x_screen = 'd0,
20 | output reg [9:0] y_screen = 'd0,
21 |
22 | output reg [3:0] register_index,
23 | output reg [22:0] register_value
24 | );
25 |
26 | `include "constant.v"
27 | `include "video_controller/registers.v"
28 |
29 | localparam
30 | MAX_X = 11'd1279,
31 | MAX_Y = 10'd1023;
32 |
33 | localparam
34 | STATE_IDLE = 'd0,
35 | STATE_SEND = 'd1,
36 | STATE_SENT = 'd2;
37 |
38 | reg [1:0] state = STATE_IDLE;
39 |
40 | reg [10:0] new_x_screen;
41 | reg [9:0] new_y_screen;
42 |
43 | task state_idle;
44 | begin
45 | read <= FALSE;
46 | mouse_state_ready <= FALSE;
47 | register_index <= VIDEO_NOP;
48 | register_value <= 'd0;
49 |
50 | if (data_ready)
51 | state <= STATE_SEND;
52 | else
53 | state <= STATE_IDLE;
54 | end
55 | endtask
56 |
57 | wire x_increment_is_negative = x_increment[8];
58 | wire y_increment_is_negative = y_increment[8];
59 | task state_send;
60 | begin
61 | read <= TRUE;
62 | mouse_state_ready <= FALSE;
63 |
64 | button_left <= left_button;
65 | button_right <= right_button;
66 | button_middle <= middle_button;
67 |
68 | if (x_increment_is_negative)
69 | // new_x_screen <= x_screen + { 2'b11, x_increment }; // speed x 1
70 | new_x_screen <= x_screen + { 1'b1, x_increment, 1'b0 }; // speed x 2
71 | else
72 | // new_x_screen <= x_screen + { 2'b00, x_increment }; // speed x 1
73 | new_x_screen <= x_screen + { 1'b0, x_increment, 1'b0 }; // speed x 2
74 |
75 | if (y_increment_is_negative)
76 | // new_y_screen <= y_screen - { 1'b1, y_increment }; // speed x 1
77 | new_y_screen <= y_screen - { y_increment, 1'b0 }; // speed x 2
78 | else
79 | // new_y_screen <= y_screen - { 1'b0, y_increment }; // speed x 1
80 | new_y_screen <= y_screen - { y_increment, 1'b0 }; // speed x 2
81 |
82 | state <= STATE_SENT;
83 | end
84 | endtask
85 |
86 | wire x_too_low = x_increment_is_negative && (new_x_screen > x_screen);
87 | wire x_too_high =
88 | !x_increment_is_negative
89 | && (new_x_screen < x_screen || new_x_screen > 'd1279);
90 |
91 | wire y_too_low = !y_increment_is_negative && (new_y_screen > y_screen);
92 | wire y_too_high =
93 | y_increment_is_negative
94 | && (new_y_screen < y_screen || new_y_screen > 'd1019);
95 |
96 | task state_sent;
97 | begin
98 | read <= FALSE;
99 | mouse_state_ready <= TRUE;
100 |
101 | if (x_too_low) begin
102 | x_screen <= 'd0;
103 | x_text <= 'd0;
104 | end else if (x_too_high) begin
105 | x_screen <= 'd1279;
106 | x_text <= 'd79;
107 | end else begin
108 | x_screen <= new_x_screen;
109 | x_text <= new_x_screen[10:4];
110 | end
111 |
112 | if (y_too_low) begin
113 | y_screen <= 'd0;
114 | y_text <= 'd0;
115 | end else if (y_too_high) begin
116 | y_screen <= 'd1019;
117 | y_text <= 'd50;
118 | end else begin
119 | y_screen <= new_y_screen;
120 | y_text <= new_y_screen / 'd20;
121 | end
122 |
123 | register_index <= VIDEO_MOUSE_POSITION;
124 | register_value <= {
125 | 2'b0,
126 | y_too_low ? 10'd0 : y_too_high ? 10'd1019 : new_y_screen,
127 | x_too_low ? 11'd0 : x_too_high ? 11'd1279 : new_x_screen
128 | };
129 |
130 | state <= STATE_IDLE;
131 | end
132 | endtask
133 |
134 | always @(posedge clk)
135 | if (reset) begin
136 | state <= STATE_IDLE;
137 | read <= FALSE;
138 | mouse_state_ready <= FALSE;
139 | button_left <= FALSE;
140 | button_middle <= FALSE;
141 | button_right <= FALSE;
142 | x_text <= 'd0;
143 | y_text <= 'd0;
144 | x_screen <= 'd0;
145 | y_screen <= 'd0;
146 | register_index <= VIDEO_NOP;
147 | register_value <= 'd0;
148 | end else begin
149 | case (state)
150 | STATE_IDLE: state_idle();
151 | STATE_SEND: state_send();
152 | STATE_SENT: state_sent();
153 | default: state_idle();
154 | endcase
155 | end
156 | endmodule
157 |
--------------------------------------------------------------------------------
/src/ps2_receiver.v:
--------------------------------------------------------------------------------
1 | module ps2_receiver (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire ps2_data,
6 | input wire ps2_clock, // ps2 data and clock inputs
7 |
8 | output reg rx_done_tick, // ps2 receive done tick
9 | output wire [7:0] rx_data // data received
10 | );
11 |
12 | // FSMD state declaration
13 | localparam
14 | idle = 1'b0,
15 | rx = 1'b1;
16 |
17 | // internal signal declaration
18 | reg state_reg, state_next; // FSMD state register
19 | reg [7:0] filter_reg; // shift register filter for ps2_clock
20 | wire [7:0] filter_next; // next state value of ps2_clock filter register
21 | reg f_val_reg; // reg for ps2_clock filter value, either 1 or 0
22 | wire f_val_next; // next state for ps2_clock filter value
23 | reg [3:0] n_reg, n_next; // register to keep track of bit number
24 | reg [10:0] d_reg, d_next; // register to shift in rx data
25 | wire neg_edge; // negative edge of ps2_clock clock filter value
26 |
27 | // register for ps2_clock filter register and filter value
28 | always @(posedge clk, posedge reset)
29 | if (reset) begin
30 | filter_reg <= 0;
31 | f_val_reg <= 0;
32 | end else begin
33 | filter_reg <= filter_next;
34 | f_val_reg <= f_val_next;
35 | end
36 |
37 | // next state value of ps2_clock filter: right shift in current ps2_clock value to register
38 | assign filter_next = {ps2_clock, filter_reg[7:1]};
39 |
40 | // filter value next state, 1 if all bits are 1, 0 if all bits are 0, else no change
41 | assign f_val_next = (filter_reg == 8'b11111111) ? 1'b1 :
42 | (filter_reg == 8'b00000000) ? 1'b0 :
43 | f_val_reg;
44 |
45 | // negative edge of filter value: if current value is 1, and next state value is 0
46 | assign neg_edge = f_val_reg & ~f_val_next;
47 |
48 | // FSMD state, bit number, and data registers
49 | always @(posedge clk, posedge reset)
50 | if (reset) begin
51 | state_reg <= idle;
52 | n_reg <= 0;
53 | d_reg <= 0;
54 | end else begin
55 | state_reg <= state_next;
56 | n_reg <= n_next;
57 | d_reg <= d_next;
58 | end
59 |
60 | // FSMD next state logic
61 | always @* begin
62 | // defaults
63 | state_next = state_reg;
64 | rx_done_tick = 1'b0;
65 | n_next = n_reg;
66 | d_next = d_reg;
67 |
68 | case (state_reg)
69 | idle: if (neg_edge) begin // start bit received
70 | n_next = 4'd10; // set bit count down to 10
71 | state_next = rx; // go to rx state
72 | end
73 |
74 | rx: begin // shift in 8 data, 1 parity, and 1 stop bit
75 | if (neg_edge) begin // if ps2_clock negative edge...
76 | d_next = { ps2_data, d_reg[10:1] }; // sample ps2_data, right shift into data register
77 | n_next = n_reg - 1; // decrement bit count
78 | end
79 |
80 | if (n_reg == 0) begin // after 10 bits shifted in, go to done state
81 | rx_done_tick = 1'b1; // assert dat received done tick
82 | state_next = idle; // go back to idle
83 | end
84 | end
85 | endcase
86 | end
87 |
88 | assign rx_data = d_reg[8:1]; // output data bits
89 |
90 | endmodule
--------------------------------------------------------------------------------
/src/ps2_scan_code_set2_fr.v:
--------------------------------------------------------------------------------
1 | // From https://www.avrfreaks.net/sites/default/files/PS2%20Keyboard.pdf
2 | // Codes are given for a french keyboard!
3 | // Standard codes
4 | localparam
5 | SCAN_BREAK = 'hf0,
6 |
7 | // Escape and function keys
8 | SCAN_ESC = 'h76,
9 | SCAN_F1 = 'h05,
10 | SCAN_F2 = 'h06,
11 | SCAN_F3 = 'h04,
12 | SCAN_F4 = 'h0c,
13 | SCAN_F5 = 'h03,
14 | SCAN_F6 = 'h0b,
15 | SCAN_F7 = 'h83,
16 | SCAN_F8 = 'h0a,
17 | SCAN_F9 = 'h01,
18 | SCAN_F10 = 'h09,
19 | SCAN_F11 = 'h78,
20 | SCAN_F12 = 'h07,
21 |
22 | SCAN_SCROLL = 'h7e,
23 | SCAN_PRNT_SCR = 'h84, // When used in combination with Alt or AltGr key
24 |
25 | // Row 1
26 | SCAN_SQUARE = 'h0e,
27 | SCAN_1 = 'h16,
28 | SCAN_2 = 'h1e,
29 | SCAN_3 = 'h26,
30 | SCAN_4 = 'h25,
31 | SCAN_5 = 'h2e,
32 | SCAN_6 = 'h36,
33 | SCAN_7 = 'h3d,
34 | SCAN_8 = 'h3e,
35 | SCAN_9 = 'h46,
36 | SCAN_0 = 'h45,
37 | SCAN_RIGHT_PAREN = 'h4e,
38 | SCAN_EQUAL = 'h55,
39 | SCAN_BACKSPACE = 'h66,
40 |
41 | // Row 2
42 | SCAN_TAB = 'h0d,
43 | SCAN_A = 'h15,
44 | SCAN_Z = 'h1d,
45 | SCAN_E = 'h24,
46 | SCAN_R = 'h2d,
47 | SCAN_T = 'h2c,
48 | SCAN_Y = 'h35,
49 | SCAN_U = 'h3c,
50 | SCAN_I = 'h43,
51 | SCAN_O = 'h44,
52 | SCAN_P = 'h4d,
53 | SCAN_CIRC = 'h54,
54 | SCAN_DOLLAR = 'h5b,
55 | SCAN_RETURN = 'h5a,
56 |
57 | // Row 3
58 | SCAN_CAPS_LOCK = 'h58,
59 | SCAN_Q = 'h1c,
60 | SCAN_S = 'h1b,
61 | SCAN_D = 'h23,
62 | SCAN_F = 'h2b,
63 | SCAN_G = 'h34,
64 | SCAN_H = 'h33,
65 | SCAN_J = 'h3b,
66 | SCAN_K = 'h42,
67 | SCAN_L = 'h4b,
68 | SCAN_M = 'h4c,
69 | SCAN_PERCENT = 'h52,
70 | SCAN_STAR = 'h5d,
71 |
72 | // Row 4
73 | SCAN_SHIFT_LEFT = 'h12,
74 | SCAN_LESS_THAN = 'h61,
75 | SCAN_W = 'h1a,
76 | SCAN_X = 'h22,
77 | SCAN_C = 'h21,
78 | SCAN_V = 'h2a,
79 | SCAN_B = 'h32,
80 | SCAN_N = 'h31,
81 | SCAN_COMMA = 'h3a,
82 | SCAN_SEMICOLON = 'h41,
83 | SCAN_COLON = 'h49,
84 | SCAN_EXCLAMATION = 'h4a,
85 | SCAN_SHIFT_RIGHT = 'h59,
86 |
87 | // Row 5
88 | SCAN_CTRL_LEFT = 'h14,
89 | SCAN_ALT = 'h11,
90 | SCAN_SPACE = 'h29,
91 |
92 | // Keypad
93 | SCAN_NUM = 'h77,
94 | SCAN_KP_MUL = 'h7c,
95 | SCAN_KP_SUB = 'h7b,
96 |
97 | SCAN_KP_7 = 'h6c,
98 | SCAN_KP_8 = 'h75,
99 | SCAN_KP_9 = 'h7d,
100 | SCAN_KP_ADD = 'h79,
101 |
102 | SCAN_KP_4 = 'h6b,
103 | SCAN_KP_5 = 'h73,
104 | SCAN_KP_6 = 'h74,
105 |
106 | SCAN_KP_1 = 'h69,
107 | SCAN_KP_2 = 'h72,
108 | SCAN_KP_3 = 'h7a,
109 |
110 | SCAN_KP_0 = 'h70,
111 | SCAN_KP_PERIOD = 'h71
112 | ;
113 |
114 | // Extended codes 0
115 | localparam
116 | SCAN_E0 = 'he0,
117 | SCAN_E0_IGNORE = 'h12,
118 |
119 | // Escape and function keys
120 | SCAN_E0_PRNT_SCR = 'h7c,
121 | SCAN_E0_PAUSE = 'h7e, // When used in combination with Ctrl key
122 |
123 | // Row 5
124 | SCAN_E0_META_LEFT = 'h1f,
125 | SCAN_E0_ALTGR = 'h11,
126 | SCAN_E0_META_RIGHT = 'h27,
127 | SCAN_E0_CONTEXTUAL = 'h2f,
128 | SCAN_E0_CTRL_RIGHT = 'h14,
129 |
130 | // Cursor keys
131 | SCAN_E0_INSERT = 'h70,
132 | SCAN_E0_HOME = 'h6c,
133 | SCAN_E0_PAGE_UP = 'h7d,
134 | SCAN_E0_DELETE = 'h71,
135 | SCAN_E0_END = 'h69,
136 | SCAN_E0_PAGE_DOWN = 'h7a,
137 |
138 | SCAN_E0_UP = 'h75,
139 | SCAN_E0_LEFT = 'h6b,
140 | SCAN_E0_DOWN = 'h72,
141 | SCAN_E0_RIGHT = 'h74,
142 |
143 | // Keypad
144 | SCAN_E0_KP_DIV = 'h4a,
145 | SCAN_E0_KP_ENTER = 'h5a,
146 |
147 | // ACPI keys
148 | SCAN_E0_POWER = 'h37,
149 | SCAN_E0_SLEEP = 'h3f,
150 | SCAN_E0_WAKE = 'h5e,
151 |
152 | // Multimedia keys
153 | SCAN_E0_NEXT_TRACK = 'h4d,
154 | SCAN_E0_PREV_TRACK = 'h15,
155 | SCAN_E0_STOP = 'h3b,
156 | SCAN_E0_PLAY_PAUSE = 'h34,
157 | SCAN_E0_MUTE = 'h23,
158 | SCAN_E0_VOLUME_UP = 'h32,
159 | SCAN_E0_VOLUME_DN = 'h21,
160 | SCAN_E0_MEDA_SEL = 'h50,
161 | SCAN_E0_EMAIL = 'h48,
162 | SCAN_E0_CALCULATOR = 'h2b,
163 | SCAN_E0_COMPUTER = 'h40,
164 | SCAN_E0_WWW_SRCH = 'h10,
165 | SCAN_E0_WWW_HOME = 'h3a,
166 | SCAN_E0_WWW_BACK = 'h38,
167 | SCAN_E0_WWW_FWRD = 'h30,
168 | SCAN_E0_WWW_STOP = 'h28,
169 | SCAN_E0_WWW_RFSH = 'h20,
170 | SCAN_E0_WWW_FAVS = 'h18
171 | ;
172 |
173 | // Extended codes 1
174 | localparam
175 | SCAN_E1 = 'he1,
176 | SCAN_E1_PAUSE_1 = 'h14,
177 | SCAN_E1_PAUSE_2 = 'h77
178 | ;
--------------------------------------------------------------------------------
/src/register_muxer.v:
--------------------------------------------------------------------------------
1 | module register_muxer (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire [3:0] register_index_0,
6 | input wire [3:0] register_index_1,
7 |
8 | input wire [22:0] register_value_0,
9 | input wire [22:0] register_value_1,
10 |
11 | output reg [3:0] register_index,
12 | output reg [22:0] register_value
13 | );
14 |
15 | reg switch = 1'b0;
16 |
17 | always @(posedge clk)
18 | if (reset) begin
19 | switch <= 1'b0;
20 | register_index <= 'd0;
21 | register_value <= 'd0;
22 | end else if (switch == 1'b0) begin
23 | switch <= 1'b1;
24 | register_index <= register_index_0;
25 | register_value <= register_value_0;
26 | end else begin
27 | switch <= 1'b0;
28 | register_index <= register_index_1;
29 | register_value <= register_value_1;
30 | end
31 |
32 | endmodule
33 |
--------------------------------------------------------------------------------
/src/sequence_to_bytes.v:
--------------------------------------------------------------------------------
1 | module sequence_to_bytes (
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire [34:0] in_sequence,
6 | input wire in_sequence_available,
7 | output reg in_sequence_ready,
8 |
9 | input wire receiver_ready,
10 | output reg [7:0] out_data,
11 | output reg out_data_available
12 | );
13 |
14 | `include "constant.v"
15 |
16 | reg [2:0] sequence_remain = 3'd0;
17 | reg [31:0] sequence = 32'd0;
18 |
19 | always @(posedge clk)
20 | if (reset) begin
21 | sequence_remain <= 3'd0;
22 | sequence <= 32'd0;
23 | out_data_available <= FALSE;
24 | in_sequence_ready <= FALSE;
25 | end else if (sequence_remain == 3'd0) begin
26 | if (in_sequence_available) begin
27 | sequence <= in_sequence[31:0];
28 | sequence_remain <= in_sequence[34:32];
29 | in_sequence_ready <= FALSE;
30 | end else begin
31 | in_sequence_ready <= TRUE;
32 | out_data_available <= FALSE;
33 | end
34 | end else if (~out_data_available & receiver_ready) begin
35 | case (sequence_remain)
36 | 3'd4: out_data <= sequence[31:24];
37 | 3'd3: out_data <= sequence[23:16];
38 | 3'd2: out_data <= sequence[15:8];
39 | 3'd1: out_data <= sequence[7:0];
40 | default:
41 | out_data <= 8'd0;
42 | endcase
43 |
44 | sequence_remain <= sequence_remain - 3'd1;
45 | out_data_available <= TRUE;
46 | end else
47 | out_data_available <= FALSE;
48 | endmodule
49 |
--------------------------------------------------------------------------------
/src/serial_in.v:
--------------------------------------------------------------------------------
1 | module serial_in #(
2 | parameter CLK_FREQUENCY_HZ = 50_000_000,
3 | parameter SERIAL_BPS = 230_400,
4 | parameter DATA_WIDTH = 8
5 | ) (
6 | input wire clk,
7 | input wire reset,
8 |
9 | input wire rx,
10 |
11 | output reg [DATA_WIDTH - 1:0] data,
12 | output reg oe
13 | );
14 |
15 | // Definitions to make code easier to read and understand.
16 | localparam
17 | HIGH = 1'b1,
18 | LOW = 1'b0,
19 |
20 | TRUE = HIGH,
21 | FALSE = LOW;
22 |
23 | // The serial automaton converts a packet to a byte.
24 | localparam
25 | BIT_DURATION = CLK_FREQUENCY_HZ / SERIAL_BPS,
26 | HALF_BIT_DURATION = BIT_DURATION / 2,
27 |
28 | WAIT_FALLING_EDGE = 'd0,
29 | WAIT_START_BIT = 'd1,
30 | WAIT_STOP_BIT = WAIT_START_BIT + DATA_WIDTH + 1,
31 | MAX_STATE = WAIT_STOP_BIT + 1,
32 |
33 | START_BIT = LOW,
34 | STOP_BIT = HIGH;
35 |
36 | reg [$clog2(BIT_DURATION):0] counter = 'd0;
37 | reg [$clog2(MAX_STATE):0] state = 'd0;
38 | reg [DATA_WIDTH - 1:0] _data = 'd0;
39 |
40 | always @(posedge clk)
41 | case (state)
42 | WAIT_FALLING_EDGE: begin
43 | oe <= FALSE;
44 | _data <= 'd0;
45 | if (rx == LOW) begin
46 | state <= state + 'd1;
47 | counter <= 'd0;
48 | end
49 | end
50 |
51 | WAIT_START_BIT:
52 | if (rx == HIGH)
53 | state <= WAIT_FALLING_EDGE;
54 | else if (counter == HALF_BIT_DURATION) begin
55 | state <= state + 'd1;
56 | counter <= 'd0;
57 | end else
58 | counter <= counter + 'd1;
59 |
60 | WAIT_STOP_BIT:
61 | if (counter == BIT_DURATION) begin
62 | state <= WAIT_FALLING_EDGE;
63 | counter <= 'd0;
64 | if (rx == STOP_BIT) begin
65 | data <= _data;
66 | oe <= TRUE;
67 | end
68 | end else
69 | counter <= counter + 'd1;
70 |
71 | default:
72 | if (counter == BIT_DURATION) begin
73 | state <= state + 'd1;
74 | counter <= 'd0;
75 | _data <= { rx, _data[DATA_WIDTH - 1:1] };
76 | end else
77 | counter <= counter + 'd1;
78 | endcase
79 | endmodule
80 |
--------------------------------------------------------------------------------
/src/serial_out.v:
--------------------------------------------------------------------------------
1 | module serial_out #(
2 | parameter CLK_FREQUENCY_HZ = 50_000_000,
3 | parameter SERIAL_BPS = 230_400,
4 | parameter DATA_WIDTH = 8
5 | ) (
6 | input wire clk,
7 | input wire reset,
8 |
9 | input wire ie,
10 | input wire [DATA_WIDTH - 1:0] data,
11 |
12 | output reg tx,
13 | output reg sending = 0
14 | );
15 |
16 | // Definitions to make code easier to read and understand.
17 | localparam
18 | HIGH = 1'b1,
19 | LOW = 1'b0,
20 |
21 | TRUE = HIGH,
22 | FALSE = LOW;
23 |
24 | localparam
25 | BIT_DURATION = CLK_FREQUENCY_HZ / SERIAL_BPS;
26 |
27 | reg [$clog2(BIT_DURATION):0] counter = 'd0;
28 | reg serial_tick = LOW;
29 |
30 | always @(posedge clk)
31 | if (counter == 'd0) begin
32 | serial_tick <= LOW;
33 | counter <= counter + 'd1;
34 | end else if (counter == BIT_DURATION) begin
35 | serial_tick <= HIGH;
36 | counter <= 'd0;
37 | end else begin
38 | counter <= counter + 'd1;
39 | end
40 |
41 | // The serial automaton converts a packet to a byte.
42 | localparam
43 | FIRST_STEP = 'd0,
44 | LAST_STEP = DATA_WIDTH + 2 - 1,
45 | END_STEP = DATA_WIDTH + 2,
46 | MAX_STEP = END_STEP + 1,
47 |
48 | START_BIT = LOW,
49 | STOP_BIT = HIGH;
50 |
51 | reg [$clog2(MAX_STEP):0] serial_step = 'd0;
52 | reg [DATA_WIDTH - 1:0] _data = 'd0;
53 |
54 | always @(posedge clk)
55 | if (!sending) begin
56 | if (ie) begin
57 | sending <= TRUE;
58 | _data <= data;
59 | end
60 | end else
61 | if (serial_tick)
62 | case (serial_step)
63 | FIRST_STEP: begin
64 | serial_step <= serial_step + 'd1;
65 | tx <= START_BIT;
66 | end
67 |
68 | LAST_STEP: begin
69 | serial_step <= serial_step + 'd1;
70 | tx <= STOP_BIT;
71 | end
72 |
73 | END_STEP: begin
74 | serial_step <= FIRST_STEP;
75 | tx <= HIGH;
76 | sending <= FALSE;
77 | end
78 |
79 | default: begin
80 | serial_step <= serial_step + 'd1;
81 | tx <= _data[0];
82 | _data <= { 1'b0, _data[DATA_WIDTH - 1:1] };
83 | end
84 | endcase
85 |
86 | endmodule
87 |
--------------------------------------------------------------------------------
/src/simple_fifo.v:
--------------------------------------------------------------------------------
1 | module simple_fifo #(
2 | parameter DATA_WIDTH = 8,
3 | parameter FIFO_SIZE = 32
4 | ) (
5 | input wire clk,
6 | input wire reset,
7 |
8 | input wire [DATA_WIDTH - 1:0] in_data,
9 | input wire in_data_available,
10 |
11 | input wire receiver_ready,
12 | output reg out_data_available,
13 | output reg [DATA_WIDTH - 1:0] out_data
14 | );
15 |
16 | `include "constant.v"
17 |
18 | reg [DATA_WIDTH - 1:0] fifo [0:FIFO_SIZE - 1];
19 | reg [$clog2(FIFO_SIZE) - 1:0] fifo_in_index;
20 | reg [$clog2(FIFO_SIZE) - 1:0] fifo_out_index;
21 |
22 | // Data coming in
23 | always @(posedge clk)
24 | if (reset)
25 | fifo_in_index <= 'd0;
26 | else if (in_data_available) begin
27 | fifo[fifo_in_index] <= in_data;
28 | fifo_in_index <= fifo_in_index + 'd1;
29 | end
30 |
31 | // Data going out
32 | always @(posedge clk)
33 | if (reset) begin
34 | fifo_out_index <= 'd0;
35 | out_data_available <= FALSE;
36 | out_data <= 'd0;
37 | end else if (out_data_available)
38 | out_data_available <= FALSE;
39 | else if (receiver_ready && fifo_in_index != fifo_out_index) begin
40 | out_data <= fifo[fifo_out_index];
41 | out_data_available <= TRUE;
42 | fifo_out_index <= fifo_out_index + 'd1;
43 | end
44 | endmodule
45 |
--------------------------------------------------------------------------------
/src/terminal_stream/attributes.v:
--------------------------------------------------------------------------------
1 | localparam
2 | SPACE_CHARACTER = 10'h020,
3 |
4 | CHARPAGE_0 = 5'h00,
5 | CHARPAGE_1 = 5'h04,
6 | CHARPAGE_2 = 5'h0b,
7 | CHARPAGE_3 = 5'h12,
8 | CHARPAGE_4 = 5'h19,
9 | CHARPAGE_GFX = 5'h1f,
10 |
11 | DEFAULT_FOREGROUND = 4'd7,
12 | DEFAULT_BACKGROUND = 4'd0,
13 |
14 | SIZE_NORMAL = 2'b00,
15 | SIZE_DOUBLE_WIDTH = 2'b01,
16 | SIZE_DOUBLE_HEIGHT = 2'b10,
17 | SIZE_DOUBLE = 2'b11,
18 |
19 | PART_TOP_LEFT = 2'b00,
20 | PART_TOP_RIGHT = 2'b01,
21 | PART_BOTTOM_LEFT = 2'b10,
22 | PART_BOTTOM_RIGHT = 2'b11,
23 |
24 | BLINK_NONE = 2'b00,
25 | BLINK_SLOW = 2'b01,
26 | BLINK_NORMAL = 2'b10,
27 | BLINK_FAST = 2'b11,
28 |
29 | LOGICAL_AND = 2'b00,
30 | LOGICAL_OR = 2'b01,
31 | LOGICAL_XOR = 2'b10,
32 | LOGICAL_NONE = 2'b11,
33 |
34 | PATTERN_NONE = 4'b0000
35 | ;
36 |
37 | // Automaton registers
38 | reg [5:0] first_row;
39 | reg [6:0] in_x;
40 | reg [5:0] in_y;
41 | wire [6:0] text_x;
42 | wire [5:0] text_y;
43 | reg cursor_visible;
44 | reg [2:0] ts_command;
45 | reg [1:0] orientation;
46 | wire scroll;
47 |
48 | reg [13:0] current_pixels;
49 | reg [1:0] current_pixels_offset;
50 |
51 | reg [4:0] charpage_base;
52 |
53 | reg [3:0] foreground;
54 | reg [3:0] background;
55 | reg bold;
56 |
57 | reg [1:0] blink;
58 | reg invert;
59 | reg underline;
60 |
61 | reg [1:0] size;
62 | reg [1:0] func;
63 | reg [3:0] pattern;
64 |
65 | task reset_all;
66 | begin
67 | first_row <= 'd0;
68 | cursor_visible <= TRUE;
69 | foreground <= DEFAULT_FOREGROUND;
70 | background <= DEFAULT_BACKGROUND;
71 | reset_position();
72 | reset_attributes();
73 | end
74 | endtask
75 |
76 | task reset_position;
77 | begin
78 | ts_command <= TS_CURSOR_SET;
79 | in_x <= 'd0;
80 | in_y <= 'd0;
81 | end
82 | endtask
83 |
84 | task reset_attributes;
85 | begin
86 | charpage_base <= CHARPAGE_0;
87 | last_unicode <= 'h20;
88 | bold <= FALSE;
89 | blink <= BLINK_NONE;
90 | size <= SIZE_NORMAL;
91 | func <= LOGICAL_AND;
92 | pattern <= PATTERN_NONE;
93 | invert <= FALSE;
94 | underline <= FALSE;
95 | current_pixels <= 20'b0;
96 | current_pixels_offset <= 2'b0;
97 | orientation <= TS_ORIENTATION_RIGHT;
98 | end
99 | endtask
100 |
101 | // =============================================================================
102 | // Generate a cell
103 | // =============================================================================
104 | function [31:0] generate_cell;
105 | input [9:0] ord;
106 | input [1:0] size;
107 | input [1:0] part;
108 | input [1:0] blink;
109 | input invert;
110 | input underline;
111 | input [1:0] func;
112 | input [3:0] pattern;
113 | input [3:0] foreground;
114 | input [3:0] background;
115 |
116 | generate_cell = {
117 | background, foreground, pattern, func, underline,
118 | invert, blink, part, size, ord
119 | };
120 | endfunction
121 |
122 | function [31:0] generate_cell_part;
123 | input [7:0] ord;
124 | input [1:0] part;
125 |
126 | generate_cell_part = generate_cell(
127 | .ord ({ charpage_base, 5'b0 } + { 2'b0, ord }),
128 | .size (size),
129 | .part (part),
130 | .blink (blink),
131 | .invert (invert),
132 | .underline (underline),
133 | .func (func),
134 | .pattern (pattern),
135 | .foreground (foreground | { bold, 3'b000 }),
136 | .background (background)
137 | );
138 | endfunction
139 |
140 | function [31:0] generate_cell_gfx;
141 | input [19:0] pixels;
142 | input disjoint;
143 |
144 | generate_cell_gfx = generate_cell(
145 | .ord (pixels[9:0]),
146 | .size (SIZE_NORMAL),
147 | .part (disjoint ? PART_BOTTOM_LEFT : PART_TOP_RIGHT),
148 | .blink (pixels[11:10]),
149 | .invert (pixels[12]),
150 | .underline (pixels[13]),
151 | .func (pixels[15:14]),
152 | .pattern (pixels[19:16]),
153 | .foreground (foreground | { bold, 3'b000 }),
154 | .background (background)
155 | );
156 | endfunction
157 |
158 | function [31:0] clear_cell;
159 | input [9:0] ord;
160 | clear_cell = generate_cell(
161 | .ord (ord),
162 | .size (SIZE_NORMAL),
163 | .part (PART_TOP_LEFT),
164 | .blink (BLINK_NONE),
165 | .invert (FALSE),
166 | .underline (FALSE),
167 | .func (LOGICAL_AND),
168 | .pattern (PATTERN_NONE),
169 | .foreground (foreground | { bold, 3'b000 }),
170 | .background (background)
171 | );
172 | endfunction
173 |
--------------------------------------------------------------------------------
/src/terminal_stream/escape_codes.v:
--------------------------------------------------------------------------------
1 | localparam
2 |
3 | CTRL_CODE_00 = 'h00, // ^@
4 |
5 | CTRL_CLEAR = 'h01, // ^A
6 | CLEAR_SCREEN = "!",
7 | CLEAR_BOL = ")",
8 | CLEAR_EOL = "(",
9 | CLEAR_BOD = "+",
10 | CLEAR_EOD = "*",
11 | CLEAR_LINE = "-",
12 | CLEAR_CHARS = "0",
13 |
14 | CTRL_COLOR = 'h02, // ^B
15 | COLOR_FOREGROUND = "@",
16 | COLOR_BACKGROUND = "P",
17 |
18 | CTRL_PATTERN = 'h03, // ^C
19 | FUNCTION_AND = 'h40,
20 | FUNCTION_OR = 'h41,
21 | FUNCTION_XOR = 'h42,
22 | FUNCTION_BORDER = 'h43,
23 | PATTERN_BASE = 'h04,
24 |
25 | CTRL_CURSOR = 'h04, // ^D
26 | CURSOR_RELATIVE = "#",
27 |
28 | CTRL_ATTRIBUTE = 'h05, // ^E
29 | ATTRIBUTE_RESET = "*",
30 | SET_UNDERLINE_ON = "U",
31 | SET_UNDERLINE_OFF = "u",
32 | SET_BLINK_ON = "B",
33 | SET_BLINK_OFF = "b",
34 | SET_HIGHLIGHT_ON = "H",
35 | SET_HIGHLIGHT_OFF = "h",
36 | SET_REVERSE_ON = "R",
37 | SET_REVERSE_OFF = "r",
38 | SET_SIZE_NORMAL = "0",
39 | SET_SIZE_DBLWIDTH = "1",
40 | SET_SIZE_DBLHEIGHT = "2",
41 | SET_SIZE_DOUBLE = "3",
42 |
43 | CTRL_PARAMETER = 'h06, // ^F
44 | CURSOR_VISIBLE = "C",
45 | CURSOR_EMPHASIZE = "V",
46 | CURSOR_HIDDEN = "c",
47 | ORIENTATION_RIGHT = "r",
48 | ORIENTATION_LEFT = "l",
49 | ORIENTATION_DOWN = "d",
50 | ORIENTATION_UP = "u",
51 |
52 | BELL = 'h07, // ^G
53 | CTRL_SELECT_ATTRIBUTES = 'h08, // ^H
54 | TAB = 'h09, // ^I
55 | LF = 'h0a, // ^J
56 | CTRL_SCROLL_UP = 'h0b, // ^K
57 | CTRL_SCROLL_DOWN = 'h0c, // ^L
58 | CR = 'h0d, // ^M
59 | CTRL_CURSOR_UP = 'h0e, // ^N
60 | CTRL_CURSOR_DOWN = 'h0f, // ^O
61 | CTRL_CURSOR_LEFT = 'h10, // ^P
62 | CTRL_CURSOR_RIGHT = 'h11, // ^Q
63 | CTRL_REPEAT = 'h12, // ^R
64 | CTRL_CHARPAGE_0 = 'h13, // ^S
65 | CTRL_CHARPAGE_1 = 'h14, // ^T
66 | CTRL_CHARPAGE_2 = 'h15, // ^U
67 | CTRL_CHARPAGE_3 = 'h16, // ^V
68 | CTRL_CHARPAGE_4 = 'h17, // ^W
69 | CTRL_CHARPAGE_GFX = 'h18, // ^X
70 | CTRL_MOUSE_CONTROL = 'h19, // ^Y
71 | CTRL_APPLY_ATTRIBUTES = 'h1a, // ^Z
72 | CTRL_CODE_1B = 'h1b, // ^[
73 | CTRL_CODE_1C = 'h1c, // ^\
74 | CTRL_CODE_1D = 'h1d, // ^]
75 | CTRL_CODE_1E = 'h1e, // ^^
76 | CTRL_CODE_1F = 'h1f; // ^_
77 |
--------------------------------------------------------------------------------
/src/test/Makefile:
--------------------------------------------------------------------------------
1 | all: screen_capture.ppm
2 |
3 | video_controller_tb: video_controller_tb.v ../video_controller.v font_sim.v charattr_row_sim.v pixels_sim.v
4 | iverilog -o video_controller_tb \
5 | video_controller_tb.v \
6 | ../video_controller.v \
7 | font_sim.v \
8 | charattr_row_sim.v \
9 | pixels_sim.v
10 |
11 | screen_capture.ppm: video_controller_tb
12 | ./video_controller_tb > screen_capture.ppm
13 |
14 | screen_capture.png: screen_capture.ppm
15 | convert screen_capture screen_capture.png
16 |
17 | clean:
18 | rm -f video_controller_tb screen_capture.ppm screen_capture.png
--------------------------------------------------------------------------------
/src/test/charattr_row_sim.v:
--------------------------------------------------------------------------------
1 | module charattr_row (
2 | input wire clka,
3 | input wire [6:0] addra,
4 | input wire [31:0] dia,
5 | input wire cea,
6 |
7 | input wire clkb,
8 | input wire [6:0] addrb,
9 | output reg [31:0] dob
10 | );
11 |
12 | reg [31:0] memory [127:0];
13 |
14 | always @(posedge clka) if (cea) memory[addra] <= dia;
15 |
16 | reg [13:0] fifo = 14'd0;
17 | always @(posedge clkb) begin
18 | fifo <= { addrb, fifo[13:7] };
19 | dob <= memory[fifo[6:0]];
20 | end
21 |
22 | endmodule
23 |
--------------------------------------------------------------------------------
/src/test/pixels_sim.v:
--------------------------------------------------------------------------------
1 | module pixels (
2 | input wire clka,
3 | input wire [63:0] dia,
4 | input wire [6:0] addra,
5 | input wire cea,
6 |
7 | input wire clkb,
8 | input wire [10:0] addrb,
9 | output reg [3:0] dob
10 | );
11 |
12 | reg wr_pixel_enable;
13 | reg [63:0] wr_pixel_data;
14 | reg [6:0] wr_pixel_addr;
15 | wire [3:0] current_pixel_index;
16 |
17 | reg [3:0] memory [2047:0];
18 |
19 | always @(posedge clka) if (cea) begin
20 | memory[addra * 16 + 15] <= dia[63:60];
21 | memory[addra * 16 + 14] <= dia[59:56];
22 | memory[addra * 16 + 13] <= dia[55:52];
23 | memory[addra * 16 + 12] <= dia[51:48];
24 | memory[addra * 16 + 11] <= dia[47:44];
25 | memory[addra * 16 + 10] <= dia[43:40];
26 | memory[addra * 16 + 9] <= dia[39:36];
27 | memory[addra * 16 + 8] <= dia[35:32];
28 | memory[addra * 16 + 7] <= dia[31:28];
29 | memory[addra * 16 + 6] <= dia[27:24];
30 | memory[addra * 16 + 5] <= dia[23:20];
31 | memory[addra * 16 + 4] <= dia[19:16];
32 | memory[addra * 16 + 3] <= dia[15:12];
33 | memory[addra * 16 + 2] <= dia[11:8];
34 | memory[addra * 16 + 1] <= dia[7:4];
35 | memory[addra * 16 + 0] <= dia[3:0];
36 | end
37 |
38 | reg [21:0] fifo = 22'd0;
39 | always @(posedge clkb) begin
40 | fifo <= { addrb, fifo[21:11] };
41 | dob <= memory[fifo[10:0]];
42 | end
43 |
44 | endmodule
45 |
--------------------------------------------------------------------------------
/src/test/pua_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | print (chr(0x01) + chr(0x1b) + chr(0x4f), end='')
4 | for codepoint in range(0xE000, 0xE400):
5 | print(chr(codepoint), end='')
6 |
7 | """if (codepoint - 0xE000) % 40 == 39:
8 | print()"""
--------------------------------------------------------------------------------
/src/test/screen_capture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/src/test/screen_capture.png
--------------------------------------------------------------------------------
/src/test/video_controller_tb.v:
--------------------------------------------------------------------------------
1 | module video_controller_tb;
2 |
3 | localparam
4 | TRUE = 1,
5 | FALSE = 0,
6 |
7 | HORZ_TOTAL = 1688,
8 | VERT_TOTAL = 1066,
9 | PIXEL_TOTAL = HORZ_TOTAL * VERT_TOTAL;
10 |
11 | reg clk = 0;
12 | always #1 clk <= ~clk;
13 |
14 | reg reset = TRUE;
15 |
16 | wire [14:0] font_address;
17 | wire [15:0] char_row_bitmap;
18 | font font (
19 | .clk (clk),
20 | .font_address (font_address),
21 | .char_row_bitmap (char_row_bitmap)
22 | );
23 |
24 | wire rd_request;
25 | wire [22:0] rd_address;
26 | reg rd_available;
27 | reg [31:0] rd_data = 32'b0100_1011_00000000_000000_00_00110101;
28 |
29 | localparam WAIT_CYCLES = 'd12;
30 | reg [3:0] wait_cycles;
31 | reg [31:0] value;
32 | always @(posedge clk)
33 | if (reset) begin
34 | rd_available <= FALSE;
35 | wait_cycles <= 'd0;
36 | end else begin
37 | if (rd_request) begin
38 | wait_cycles <= WAIT_CYCLES;
39 | end
40 |
41 | if (wait_cycles > 'd0) begin
42 | wait_cycles <= wait_cycles - 'd1;
43 |
44 | if (wait_cycles == 'd1) begin
45 | rd_available <= TRUE;
46 | rd_data <= { rd_address[11:4], 14'b0, rd_address[15:6] };
47 | end else begin
48 | rd_available <= FALSE;
49 | end
50 | end else
51 | rd_available <= FALSE;
52 | end
53 |
54 | wire hsync;
55 | wire vsync;
56 | wire [2:0] red;
57 | wire [2:0] green;
58 | wire [2:0] blue;
59 | video_controller video_controller(
60 | .clk (clk),
61 | .reset (reset),
62 | .hsync (hsync),
63 | .vsync (vsync),
64 | .pixel_red (red),
65 | .pixel_green (green),
66 | .pixel_blue (blue),
67 | .rd_request (rd_request),
68 | .rd_address (rd_address),
69 | .rd_available (rd_available),
70 | .rd_data (rd_data),
71 | .font_address (font_address),
72 | .char_row_bitmap (char_row_bitmap)
73 | );
74 |
75 | reg [31:0] pixel_count = 'd0;
76 | always @(posedge clk)
77 | if (~reset) begin
78 | $display("%0d %0d %0d", red, green, blue);
79 | pixel_count <= pixel_count + 'd1;
80 | end
81 |
82 | always @(posedge clk)
83 | // Finish the simulation when an entire frame has been rendered
84 | if (pixel_count == PIXEL_TOTAL) $finish;
85 |
86 | initial begin
87 | // Generate a PPM file of exactly 1 frame
88 | $display("P3");
89 | $display("# Image generated by video_controller_tb");
90 | $display("%0d %0d", HORZ_TOTAL, VERT_TOTAL);
91 | $display("7");
92 |
93 | #10 reset <= FALSE;
94 | end
95 |
96 | endmodule
97 |
--------------------------------------------------------------------------------
/src/ts_cursor.vh:
--------------------------------------------------------------------------------
1 | localparam
2 | TS_CURSOR_NOP = 'd0,
3 | TS_CURSOR_SET = 'd1,
4 | TS_CURSOR_UP = 'd2,
5 | TS_CURSOR_DOWN = 'd3,
6 | TS_CURSOR_LEFT = 'd4,
7 | TS_CURSOR_RIGHT = 'd5,
8 | TS_CURSOR_NEXT_CHAR = 'd6,
9 | TS_CURSOR_LINE_FEED = 'd7;
10 |
11 | localparam
12 | TS_ORIENTATION_RIGHT = 'd0,
13 | TS_ORIENTATION_LEFT = 'd1,
14 | TS_ORIENTATION_DOWN = 'd2,
15 | TS_ORIENTATION_UP = 'd3;
16 |
--------------------------------------------------------------------------------
/src/utf8_decode.v:
--------------------------------------------------------------------------------
1 | module utf8_decode(
2 | input wire clk,
3 | input wire reset,
4 |
5 | input wire [7:0] current_byte,
6 | input wire ie,
7 |
8 | output reg [20:0] unicode,
9 | output reg oe
10 | );
11 |
12 | // https://fr.wikipedia.org/wiki/UTF-8
13 | localparam
14 | TRUE = 'd1,
15 | FALSE = 'd0;
16 |
17 | localparam
18 | STATE_FIRST_BYTE = 'd0,
19 | STATE_TWO_BYTES = 'd1,
20 | STATE_THREE_BYTES_SECOND = 'd2,
21 | STATE_THREE_BYTES_THIRD = 'd3,
22 | STATE_FOUR_BYTES_SECOND = 'd4,
23 | STATE_FOUR_BYTES_THIRD = 'd5,
24 | STATE_FOUR_BYTES_FOURTH = 'd6;
25 |
26 | reg [7:0] first_byte;
27 | reg [7:0] second_byte;
28 | reg [7:0] third_byte;
29 | reg [2:0] state;
30 |
31 | task state_first_byte;
32 | begin
33 | first_byte <= current_byte;
34 | oe <= current_byte[7] == 1'b0;
35 |
36 | if (current_byte[7] == 1'b0) begin
37 | // 1-byte UTF-8 sequence
38 | unicode <= { 13'b0, current_byte };
39 | state <= STATE_FIRST_BYTE;
40 | end else if (current_byte[7:5] == 3'b110)
41 | // 2-byte UTF-8 sequence
42 | state <= STATE_TWO_BYTES;
43 | else if (current_byte[7:4] == 4'b1110)
44 | // 3-byte UTF-8 sequence
45 | state <= STATE_THREE_BYTES_SECOND;
46 | else if (current_byte[7:3] == 'b11110) begin
47 | // 4-byte UTF-8 sequence
48 | if (current_byte[2:0] > 3'b100)
49 | // Not a valid 4-byte starting value
50 | state <= STATE_FIRST_BYTE;
51 | else
52 | state <= STATE_FOUR_BYTES_SECOND;
53 | end else
54 | // Invalid UTF-8 codes are ignored
55 | state <= STATE_FIRST_BYTE;
56 | end
57 | endtask
58 |
59 | task state_two_bytes;
60 | if (current_byte[7:6] == 2'b10) begin
61 | oe <= TRUE;
62 | unicode <= { 1'b1, first_byte[4:0], current_byte[4:0] };
63 | state <= STATE_FIRST_BYTE;
64 | end else
65 | state_first_byte();
66 | endtask
67 |
68 | task state_three_bytes_second;
69 | if (current_byte[7:6] == 2'b10 && (
70 | (first_byte[3:0] == 4'b0000 && current_byte[7] == 1'b1) ||
71 | (first_byte[3:0] == 4'b1101 && current_byte[7] == 1'b0) ||
72 | (first_byte[3:0] != 4'b0000 && first_byte[3:0] != 4'b1101)
73 | )) begin
74 | oe <= FALSE;
75 | second_byte <= current_byte;
76 | state <= STATE_THREE_BYTES_THIRD;
77 | end else
78 | state_first_byte();
79 | endtask
80 |
81 | task state_three_bytes_third;
82 | if (current_byte[7:6] == 2'b10) begin
83 | oe <= TRUE;
84 | unicode <=
85 | { 2'b11, first_byte[3:0], second_byte[5:0], current_byte[5:0] };
86 | state <= STATE_FIRST_BYTE;
87 | end else
88 | state_first_byte();
89 | endtask
90 |
91 | task state_four_bytes_second;
92 | if (current_byte[7:6] == 2'b10 && (
93 | (first_byte[2:0] == 3'b000 && current_byte[5:4] == 2'b01) ||
94 | (first_byte[2:0] == 3'b000 && current_byte[5] == 1'b1) ||
95 | (first_byte[2:0] == 3'b100 && current_byte[5:4] == 2'b00) ||
96 | first_byte[2:0] == 3'b001 ||
97 | first_byte[2:0] == 3'b010 ||
98 | first_byte[2:0] == 3'b011
99 | )) begin
100 | oe <= FALSE;
101 | second_byte <= current_byte;
102 | state <= STATE_THREE_BYTES_THIRD;
103 | end else
104 | state_first_byte();
105 | endtask
106 |
107 | task state_four_bytes_third;
108 | if (current_byte[7:6] == 'b10) begin
109 | oe <= FALSE;
110 | third_byte <= current_byte;
111 | state <= STATE_FIRST_BYTE;
112 | end else
113 | state_first_byte();
114 | endtask
115 |
116 | task state_four_bytes_fourth;
117 | if (current_byte[7:6] == 'b10) begin
118 | oe <= TRUE;
119 | unicode <= {
120 | 3'b1, first_byte[2:0], second_byte[5:0],
121 | third_byte[5:0], current_byte[5:0]
122 | };
123 | state <= STATE_FIRST_BYTE;
124 | end else
125 | state_first_byte();
126 | endtask
127 |
128 | always @(posedge clk)
129 | if (reset) begin
130 | first_byte <= 8'd0;
131 | second_byte <= 8'd0;
132 | third_byte <= 8'd0;
133 | unicode <= 21'd0;
134 | oe <= FALSE;
135 | state <= STATE_FIRST_BYTE;
136 | end else if (ie == TRUE)
137 | case (state)
138 | STATE_FIRST_BYTE: state_first_byte();
139 | STATE_TWO_BYTES: state_two_bytes();
140 | STATE_THREE_BYTES_SECOND: state_three_bytes_second();
141 | STATE_THREE_BYTES_THIRD: state_three_bytes_third();
142 | STATE_FOUR_BYTES_SECOND: state_four_bytes_second();
143 | STATE_FOUR_BYTES_THIRD: state_four_bytes_third();
144 | STATE_FOUR_BYTES_FOURTH: state_four_bytes_fourth();
145 | default: state_first_byte();
146 | endcase
147 | else
148 | oe <= FALSE;
149 | endmodule
--------------------------------------------------------------------------------
/src/video_controller/ansi_palette.v:
--------------------------------------------------------------------------------
1 | palette[0] <= 9'b000_000_000;
2 | palette[1] <= 9'b100_000_000;
3 | palette[2] <= 9'b000_100_000;
4 | palette[3] <= 9'b100_100_000;
5 | palette[4] <= 9'b000_000_100;
6 | palette[5] <= 9'b100_000_100;
7 | palette[6] <= 9'b000_100_100;
8 | palette[7] <= 9'b101_101_101;
9 | palette[8] <= 9'b100_100_100;
10 | palette[9] <= 9'b111_000_000;
11 | palette[10] <= 9'b000_111_000;
12 | palette[11] <= 9'b111_111_000;
13 | palette[12] <= 9'b000_000_111;
14 | palette[13] <= 9'b111_000_111;
15 | palette[14] <= 9'b000_111_111;
16 | palette[15] <= 9'b111_111_111;
17 |
--------------------------------------------------------------------------------
/src/video_controller/apply_pattern.v:
--------------------------------------------------------------------------------
1 | localparam
2 | LOGICAL_AND = 2'b00,
3 | LOGICAL_OR = 2'b01,
4 | LOGICAL_XOR = 2'b10,
5 | LOGICAL_NONE = 2'b11;
6 |
7 | function [15:0] apply_pattern;
8 | input [1:0] logical_operator;
9 | input [15:0] value;
10 | input [15:0] pattern;
11 | case (logical_operator)
12 | LOGICAL_AND: apply_pattern = value & pattern;
13 | LOGICAL_OR: apply_pattern = value | pattern;
14 | LOGICAL_XOR: apply_pattern = value ^ pattern;
15 | LOGICAL_NONE: apply_pattern = value;
16 | endcase
17 | endfunction
18 |
--------------------------------------------------------------------------------
/src/video_controller/cursor_ids.v:
--------------------------------------------------------------------------------
1 | localparam
2 | CURSOR_DEFAULT = 'd0,
3 | CURSOR_POINTER = 'd1,
4 | CURSOR_NOT_ALLOWED = 'd2,
5 | CURSOR_WAIT = 'd3,
6 | CURSOR_MOVE = 'd4,
7 | CURSOR_GRAB = 'd5,
8 | CURSOR_CROSSHAIR = 'd6,
9 | CURSOR_CELL = 'd7;
10 |
--------------------------------------------------------------------------------
/src/video_controller/cursor_offset.v:
--------------------------------------------------------------------------------
1 | function [3:0] cursor_offset_x;
2 | input [2:0] cursor_id;
3 | case (cursor_id)
4 | CURSOR_DEFAULT: cursor_offset_x = 'd0;
5 | CURSOR_POINTER: cursor_offset_x = 'd4;
6 | CURSOR_NOT_ALLOWED: cursor_offset_x = 'd7;
7 | CURSOR_WAIT: cursor_offset_x = 'd11;
8 | CURSOR_MOVE: cursor_offset_x = 'd7;
9 | CURSOR_GRAB: cursor_offset_x = 'd8;
10 | CURSOR_CROSSHAIR: cursor_offset_x = 'd7;
11 | CURSOR_CELL: cursor_offset_x = 'd7;
12 | endcase
13 | endfunction
14 |
15 | function [4:0] cursor_offset_y;
16 | input [2:0] cursor_id;
17 | case (cursor_id)
18 | CURSOR_DEFAULT: cursor_offset_y = 'd0;
19 | CURSOR_POINTER: cursor_offset_y = 'd0;
20 | CURSOR_NOT_ALLOWED: cursor_offset_y = 'd7;
21 | CURSOR_WAIT: cursor_offset_y = 'd6;
22 | CURSOR_MOVE: cursor_offset_y = 'd8;
23 | CURSOR_GRAB: cursor_offset_y = 'd5;
24 | CURSOR_CROSSHAIR: cursor_offset_y = 'd7;
25 | CURSOR_CELL: cursor_offset_y = 'd7;
26 | endcase
27 | endfunction
28 |
--------------------------------------------------------------------------------
/src/video_controller/gen_palette.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | ubuntu_palette = [
4 | (1, 1, 1),
5 | (222, 56, 43),
6 | (57, 181, 74),
7 | (255, 199, 6),
8 | (0, 111, 184),
9 | (118, 38, 113),
10 | (44, 181, 233),
11 | (204, 204, 204),
12 |
13 | (128, 128, 128),
14 | (255, 0, 0),
15 | (0, 255, 0),
16 | (255, 255, 0),
17 | (0, 0, 255),
18 | (255, 0, 255),
19 | (0, 255, 255),
20 | (255, 255, 255)
21 | ]
22 |
23 | ansi_palette = [
24 | (0, 0, 0),
25 | (128, 0, 0),
26 | (0, 128, 0),
27 | (128, 128, 0),
28 | (0, 0, 128),
29 | (128, 0, 128),
30 | (0, 128, 128),
31 | (192, 192, 192),
32 |
33 | (128, 128, 128),
34 | (255, 0, 0),
35 | (0, 255, 0),
36 | (255, 255, 0),
37 | (0, 0, 255),
38 | (255, 0, 255),
39 | (0, 255, 255),
40 | (255, 255, 255)
41 | ]
42 |
43 | selected_palette = ansi_palette
44 |
45 | index = 0
46 | for (red8, green8, blue8) in selected_palette:
47 | (red3, green3, blue3) = (red8 >> 5, green8 >> 5, blue8 >> 5)
48 | print("\t\tpalette[{}] <= 9'b{:03b}_{:03b}_{:03b};".format(
49 | index,
50 | red3, green3, blue3
51 | ))
52 |
53 | index += 1
54 |
--------------------------------------------------------------------------------
/src/video_controller/generate_pattern.v:
--------------------------------------------------------------------------------
1 | function [15:0] generate_pattern;
2 | input [3:0] pattern_id;
3 | input [3:0] vertical_offset;
4 | case (pattern_id)
5 | 4'd1:
6 | if (vertical_offset[0])
7 | generate_pattern = 16'b01010101_01010101;
8 | else
9 | generate_pattern = 16'b10101010_10101010;
10 | 4'd2:
11 | if (vertical_offset[1])
12 | generate_pattern = 16'b00110011_00110011;
13 | else
14 | generate_pattern = 16'b11001100_11001100;
15 | 4'd3:
16 | if (vertical_offset[2])
17 | generate_pattern = 16'b00001111_00001111;
18 | else
19 | generate_pattern = 16'b11110000_11110000;
20 | 4'd4:
21 | if (vertical_offset[3])
22 | generate_pattern = 16'b00000000_11111111;
23 | else
24 | generate_pattern = 16'b11111111_00000000;
25 | 4'd5:
26 | case (vertical_offset[2:1])
27 | 2'b00: generate_pattern = 16'b10001000_10001000;
28 | 2'b01: generate_pattern = 16'b01000100_01000100;
29 | 2'b10: generate_pattern = 16'b00100010_00100010;
30 | 2'b11: generate_pattern = 16'b00010001_00010001;
31 | endcase
32 | 4'd6:
33 | case (vertical_offset[2:1])
34 | 2'b00: generate_pattern = 16'b00010001_00010001;
35 | 2'b01: generate_pattern = 16'b00100010_00100010;
36 | 2'b10: generate_pattern = 16'b01000100_01000100;
37 | 2'b11: generate_pattern = 16'b10001000_10001000;
38 | endcase
39 | 4'd7:
40 | case (vertical_offset[1:0])
41 | 2'b00: generate_pattern = 16'b10001000_10001000;
42 | 2'b01: generate_pattern = 16'b01000100_01000100;
43 | 2'b10: generate_pattern = 16'b00100010_00100010;
44 | 2'b11: generate_pattern = 16'b00010001_00010001;
45 | endcase
46 | 4'd8:
47 | case (vertical_offset[1:0])
48 | 2'b00: generate_pattern = 16'b00010001_00010001;
49 | 2'b01: generate_pattern = 16'b00100010_00100010;
50 | 2'b10: generate_pattern = 16'b01000100_01000100;
51 | 2'b11: generate_pattern = 16'b10001000_10001000;
52 | endcase
53 | 4'd9:
54 | case (vertical_offset[1:0])
55 | 2'b00: generate_pattern = 16'b01000100_01000100;
56 | 2'b01: generate_pattern = 16'b11101110_11101110;
57 | 2'b10: generate_pattern = 16'b01000100_01000100;
58 | 2'b11: generate_pattern = 16'b00000000_00000000;
59 | endcase
60 | 4'd10:
61 | if (vertical_offset[0])
62 | generate_pattern = 16'b00000000_00000000;
63 | else
64 | generate_pattern = 16'b10101010_10101010;
65 | 4'd11:
66 | case (vertical_offset[2:0])
67 | 3'd0: generate_pattern = 16'b11110000_11110000;
68 | 3'd1: generate_pattern = 16'b01111000_01111000;
69 | 3'd2: generate_pattern = 16'b00111100_00111100;
70 | 3'd3: generate_pattern = 16'b00011110_00011110;
71 | 3'd4: generate_pattern = 16'b00001111_00001111;
72 | 3'd5: generate_pattern = 16'b10000111_10000111;
73 | 3'd6: generate_pattern = 16'b11000011_11000011;
74 | 3'd7: generate_pattern = 16'b11100001_11100001;
75 | endcase
76 | 4'd12:
77 | case (vertical_offset[2:0])
78 | 3'd0: generate_pattern = 16'b11100001_11100001;
79 | 3'd1: generate_pattern = 16'b11000011_11000011;
80 | 3'd2: generate_pattern = 16'b10000111_10000111;
81 | 3'd3: generate_pattern = 16'b00001111_00001111;
82 | 3'd4: generate_pattern = 16'b00011110_00011110;
83 | 3'd5: generate_pattern = 16'b00111100_00111100;
84 | 3'd6: generate_pattern = 16'b01111000_01111000;
85 | 3'd7: generate_pattern = 16'b11110000_11110000;
86 | endcase
87 | 4'd13:
88 | case (vertical_offset[2:0])
89 | 3'd0: generate_pattern = 16'b00000000_00000000;
90 | 3'd1: generate_pattern = 16'b01111110_01111110;
91 | 3'd2: generate_pattern = 16'b01000010_01000010;
92 | 3'd3: generate_pattern = 16'b01000010_01000010;
93 | 3'd4: generate_pattern = 16'b01000010_01000010;
94 | 3'd5: generate_pattern = 16'b01000010_01000010;
95 | 3'd6: generate_pattern = 16'b01111110_01111110;
96 | 3'd7: generate_pattern = 16'b00000000_00000000;
97 | endcase
98 | 4'd14:
99 | case (vertical_offset[2:0])
100 | 3'd0: generate_pattern = 16'b10001000_10001000;
101 | 3'd1: generate_pattern = 16'b00010000_00010000;
102 | 3'd2: generate_pattern = 16'b00100000_00100000;
103 | 3'd3: generate_pattern = 16'b01000000_01000000;
104 | 3'd4: generate_pattern = 16'b10001000_10001000;
105 | 3'd5: generate_pattern = 16'b00000100_00000100;
106 | 3'd6: generate_pattern = 16'b00000010_00000010;
107 | 3'd7: generate_pattern = 16'b00000001_00000001;
108 | endcase
109 | default: generate_pattern = 16'b11111111_11111111;
110 | endcase
111 | endfunction
112 |
--------------------------------------------------------------------------------
/src/video_controller/horizontal_resize.v:
--------------------------------------------------------------------------------
1 | localparam
2 | SIZE_NORMAL = 1'b0,
3 | SIZE_DOUBLE = 1'b1,
4 | PART_FIRST = 1'b0,
5 | PART_LAST = 1'b1;
6 |
7 | function [15:0] horizontal_resize;
8 | input double_size;
9 | input double_part;
10 | input [15:0] pixels;
11 | case ({ double_part, double_size })
12 | { PART_FIRST, SIZE_NORMAL }, { PART_LAST, SIZE_NORMAL }:
13 | horizontal_resize = pixels;
14 |
15 | { PART_FIRST, SIZE_DOUBLE }:
16 | horizontal_resize = {
17 | pixels[15], pixels[15],
18 | pixels[14], pixels[14],
19 | pixels[13], pixels[13],
20 | pixels[12], pixels[12],
21 | pixels[11], pixels[11],
22 | pixels[10], pixels[10],
23 | pixels[9], pixels[9],
24 | pixels[8], pixels[8]
25 | };
26 |
27 | { PART_LAST, SIZE_DOUBLE }:
28 | horizontal_resize = {
29 | pixels[7], pixels[7],
30 | pixels[6], pixels[6],
31 | pixels[5], pixels[5],
32 | pixels[4], pixels[4],
33 | pixels[3], pixels[3],
34 | pixels[2], pixels[2],
35 | pixels[1], pixels[1],
36 | pixels[0], pixels[0]
37 | };
38 | endcase
39 | endfunction
40 |
--------------------------------------------------------------------------------
/src/video_controller/registers.v:
--------------------------------------------------------------------------------
1 | localparam
2 | VIDEO_NOP = 'd0,
3 | VIDEO_SET_BASE_ADDRESS = 'd1,
4 | VIDEO_SET_FIRST_ROW = 'd2,
5 | VIDEO_CURSOR_POSITION = 'd3,
6 | VIDEO_MOUSE_CURSOR = 'd4,
7 | VIDEO_MOUSE_POSITION = 'd5,
8 |
9 | COLUMNS = 'd80,
10 | COLUMNS_REAL = 'd128,
11 | ROWS = 'd51,
12 | CHARATTR_SIZE = 'd4,
13 | ROW_SIZE = COLUMNS_REAL * CHARATTR_SIZE,
14 | PAGE_SIZE = ROW_SIZE * ROWS
15 | ;
16 |
--------------------------------------------------------------------------------
/src/video_controller/ubuntu_palette.v:
--------------------------------------------------------------------------------
1 | palette[0] <= 9'b000_000_000;
2 | palette[1] <= 9'b110_001_001;
3 | palette[2] <= 9'b001_101_010;
4 | palette[3] <= 9'b111_110_000;
5 | palette[4] <= 9'b000_011_101;
6 | palette[5] <= 9'b011_001_011;
7 | palette[6] <= 9'b001_101_111;
8 | palette[7] <= 9'b110_110_110;
9 | palette[8] <= 9'b100_100_100;
10 | palette[9] <= 9'b111_000_000;
11 | palette[10] <= 9'b000_111_000;
12 | palette[11] <= 9'b111_111_000;
13 | palette[12] <= 9'b000_000_111;
14 | palette[13] <= 9'b111_000_111;
15 | palette[14] <= 9'b000_111_111;
16 | palette[15] <= 9'b111_111_111;
17 |
--------------------------------------------------------------------------------
/src/video_controller/vertical_resize.v:
--------------------------------------------------------------------------------
1 | function [4:0] vertical_resize;
2 | input double_size;
3 | input double_part;
4 | input [4:0] row;
5 | case ({ double_part, double_size })
6 | { PART_FIRST, SIZE_NORMAL },
7 | { PART_LAST, SIZE_NORMAL }: vertical_resize = row;
8 |
9 | { PART_FIRST, SIZE_DOUBLE }: vertical_resize = { 1'b0, row[4:1] };
10 |
11 | { PART_LAST, SIZE_DOUBLE }:
12 | vertical_resize = { 1'b0, row[4:1] } + (CHAR_HEIGHT / 2);
13 | endcase
14 | endfunction
15 |
--------------------------------------------------------------------------------
/src/vp_bitmap_to_pixels.v:
--------------------------------------------------------------------------------
1 | module vp_bitmap_to_pixels (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Inputs
6 | input wire [3:0] foreground,
7 | input wire [3:0] background,
8 | input wire [15:0] bitmap,
9 | input wire enabled,
10 |
11 | // Outputs
12 | output reg [63:0] pixels,
13 | output reg enable
14 | );
15 |
16 | `include "constant.v"
17 |
18 | always @(posedge clk) begin
19 | enable <= enabled;
20 | pixels <= {
21 | bitmap[ 0] ? foreground : background,
22 | bitmap[ 1] ? foreground : background,
23 | bitmap[ 2] ? foreground : background,
24 | bitmap[ 3] ? foreground : background,
25 | bitmap[ 4] ? foreground : background,
26 | bitmap[ 5] ? foreground : background,
27 | bitmap[ 6] ? foreground : background,
28 | bitmap[ 7] ? foreground : background,
29 | bitmap[ 8] ? foreground : background,
30 | bitmap[ 9] ? foreground : background,
31 | bitmap[10] ? foreground : background,
32 | bitmap[11] ? foreground : background,
33 | bitmap[12] ? foreground : background,
34 | bitmap[13] ? foreground : background,
35 | bitmap[14] ? foreground : background,
36 | bitmap[15] ? foreground : background
37 | };
38 | end
39 | endmodule
--------------------------------------------------------------------------------
/src/vp_bitmap_to_pixels_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1 ns / 100 ps
2 | `include "vp_bitmap_to_pixels.v"
3 | module vp_gfx_bitmap_tb ();
4 | `include "constant.v"
5 |
6 | reg clk;
7 | reg reset;
8 |
9 |
10 | reg [3:0] foreground;
11 | reg [3:0] background;
12 | reg [15:0] bitmap;
13 | reg enabled;
14 |
15 | wire [63:0] pixels;
16 | wire enable;
17 |
18 | vp_bitmap_to_pixels vp_bitmap_to_pixels (
19 | // Base signals
20 | .clk (clk),
21 | .reset (reset),
22 |
23 | // Inputs
24 | .foreground (foreground),
25 | .background (background),
26 | .bitmap (bitmap),
27 | .enabled (enabled),
28 |
29 | // Outputs
30 | .pixels (pixels),
31 | .enable (enable)
32 | );
33 |
34 | always #10 clk <= ~clk;
35 |
36 | reg [15:0] ticks = 'd0;
37 | always @(posedge clk) begin
38 | $display($time, " ticks=%d", ticks);
39 | ticks <= ticks + 'd1;
40 | end
41 |
42 | always @(posedge clk)
43 | case (ticks)
44 | 'd1: begin
45 | foreground <= 'd15;
46 | background <= 'd00;
47 | bitmap <= 'b1010_0101_0000_1111_1001;
48 | enabled <= TRUE;
49 | end
50 |
51 | 'd2: $finish;
52 |
53 | default:
54 | enabled <= FALSE;
55 | endcase
56 |
57 | initial begin
58 | $monitor(
59 | $time,
60 | " enabled=%b, bitmap=%b, foreground=%d, background=%d\n",
61 | enabled, bitmap, foreground, background,
62 | " enable =%b, pixels=%b\n",
63 | enable, pixels
64 | );
65 |
66 | clk <= 1'b0;
67 | reset <= TRUE;
68 |
69 | #10 reset <= FALSE;
70 | end
71 |
72 | endmodule
--------------------------------------------------------------------------------
/src/vp_gfx_bitmap.v:
--------------------------------------------------------------------------------
1 | module vp_gfx_bitmap (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Inputs
6 | input wire [3:0] foreground,
7 | input wire [3:0] background,
8 | input wire [19:0] gfx_bits,
9 | input wire [4:0] char_row,
10 | input wire mosaic,
11 | input wire enabled,
12 |
13 | // Outputs
14 | output reg [3:0] gfx_foreground,
15 | output reg [3:0] gfx_background,
16 | output reg [15:0] gfx_bitmap,
17 | output reg enable
18 | );
19 |
20 | `include "constant.v"
21 |
22 | always @(posedge clk) begin
23 | enable <= enabled;
24 | gfx_foreground <= foreground;
25 | gfx_background <= background;
26 | if (mosaic) begin
27 | case (char_row)
28 | 'd01, 'd02: gfx_bitmap <= {
29 | 1'b0, gfx_bits[19], gfx_bits[19], 1'b0,
30 | 1'b0, gfx_bits[18], gfx_bits[18], 1'b0,
31 | 1'b0, gfx_bits[17], gfx_bits[17], 1'b0,
32 | 1'b0, gfx_bits[16], gfx_bits[16], 1'b0
33 | };
34 |
35 | 'd05, 'd06: gfx_bitmap <= {
36 | 1'b0, gfx_bits[15], gfx_bits[15], 1'b0,
37 | 1'b0, gfx_bits[14], gfx_bits[14], 1'b0,
38 | 1'b0, gfx_bits[13], gfx_bits[13], 1'b0,
39 | 1'b0, gfx_bits[12], gfx_bits[12], 1'b0
40 | };
41 |
42 | 'd09, 'd10: gfx_bitmap <= {
43 | 1'b0, gfx_bits[11], gfx_bits[11], 1'b0,
44 | 1'b0, gfx_bits[10], gfx_bits[10], 1'b0,
45 | 1'b0, gfx_bits[ 9], gfx_bits[ 9], 1'b0,
46 | 1'b0, gfx_bits[ 8], gfx_bits[ 8], 1'b0
47 | };
48 |
49 | 'd13, 'd14: gfx_bitmap <= {
50 | 1'b0, gfx_bits[ 7], gfx_bits[ 7], 1'b0,
51 | 1'b0, gfx_bits[ 6], gfx_bits[ 6], 1'b0,
52 | 1'b0, gfx_bits[ 5], gfx_bits[ 5], 1'b0,
53 | 1'b0, gfx_bits[ 4], gfx_bits[ 4], 1'b0
54 | };
55 |
56 | 'd00, 'd04, 'd08, 'd12, 'd16, 'd03, 'd07, 'd11, 'd15, 'd19:
57 | gfx_bitmap <= 16'b0;
58 |
59 | default: gfx_bitmap <= {
60 | 1'b0, gfx_bits[ 3], gfx_bits[ 3], 1'b0,
61 | 1'b0, gfx_bits[ 2], gfx_bits[ 2], 1'b0,
62 | 1'b0, gfx_bits[ 1], gfx_bits[ 1], 1'b0,
63 | 1'b0, gfx_bits[ 0], gfx_bits[ 0], 1'b0
64 | };
65 | endcase
66 | end else begin
67 | case (char_row)
68 | 'd00, 'd01, 'd02, 'd03: gfx_bitmap <= {
69 | gfx_bits[19], gfx_bits[19], gfx_bits[19], gfx_bits[19],
70 | gfx_bits[18], gfx_bits[18], gfx_bits[18], gfx_bits[18],
71 | gfx_bits[17], gfx_bits[17], gfx_bits[17], gfx_bits[17],
72 | gfx_bits[16], gfx_bits[16], gfx_bits[16], gfx_bits[16]
73 | };
74 |
75 | 'd04, 'd05, 'd06, 'd07: gfx_bitmap <= {
76 | gfx_bits[15], gfx_bits[15], gfx_bits[15], gfx_bits[15],
77 | gfx_bits[14], gfx_bits[14], gfx_bits[14], gfx_bits[14],
78 | gfx_bits[13], gfx_bits[13], gfx_bits[13], gfx_bits[13],
79 | gfx_bits[12], gfx_bits[12], gfx_bits[12], gfx_bits[12]
80 | };
81 |
82 | 'd08, 'd09, 'd10, 'd11: gfx_bitmap <= {
83 | gfx_bits[11], gfx_bits[11], gfx_bits[11], gfx_bits[11],
84 | gfx_bits[10], gfx_bits[10], gfx_bits[10], gfx_bits[10],
85 | gfx_bits[ 9], gfx_bits[ 9], gfx_bits[ 9], gfx_bits[ 9],
86 | gfx_bits[ 8], gfx_bits[ 8], gfx_bits[ 8], gfx_bits[ 8]
87 | };
88 |
89 | 'd12, 'd13, 'd14, 'd15: gfx_bitmap <= {
90 | gfx_bits[ 7], gfx_bits[ 7], gfx_bits[ 7], gfx_bits[ 7],
91 | gfx_bits[ 6], gfx_bits[ 6], gfx_bits[ 6], gfx_bits[ 6],
92 | gfx_bits[ 5], gfx_bits[ 5], gfx_bits[ 5], gfx_bits[ 5],
93 | gfx_bits[ 4], gfx_bits[ 4], gfx_bits[ 4], gfx_bits[ 4]
94 | };
95 |
96 | default: gfx_bitmap <= {
97 | gfx_bits[ 3], gfx_bits[ 3], gfx_bits[ 3], gfx_bits[ 3],
98 | gfx_bits[ 2], gfx_bits[ 2], gfx_bits[ 2], gfx_bits[ 2],
99 | gfx_bits[ 1], gfx_bits[ 1], gfx_bits[ 1], gfx_bits[ 1],
100 | gfx_bits[ 0], gfx_bits[ 0], gfx_bits[ 0], gfx_bits[ 0]
101 | };
102 | endcase
103 | end
104 | end
105 | endmodule
--------------------------------------------------------------------------------
/src/vp_gfx_bitmap_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1 ns / 100 ps
2 | `include "vp_gfx_bitmap.v"
3 | module vp_gfx_bitmap_tb ();
4 | `include "constant.v"
5 |
6 | reg clk;
7 | reg reset;
8 |
9 | reg [3:0] foreground;
10 | reg [3:0] background;
11 | reg [19:0] gfx_bits;
12 | reg [4:0] char_row;
13 | reg mosaic;
14 | reg enabled;
15 | wire [3:0] gfx_foreground;
16 | wire [3:0] gfx_background;
17 | wire [15:0] gfx_bitmap;
18 | wire enable;
19 |
20 | vp_gfx_bitmap vp_gfx_bitmap (
21 | // Base signals
22 | .clk (clk),
23 | .reset (reset),
24 |
25 | // Inputs
26 | .background (background),
27 | .gfx_bits (gfx_bits),
28 | .foreground (foreground),
29 | .char_row (char_row),
30 | .mosaic (mosaic),
31 | .enabled (enabled),
32 |
33 | // Outputs
34 | .gfx_foreground (gfx_foreground),
35 | .gfx_background (gfx_background),
36 | .gfx_bitmap (gfx_bitmap),
37 | .enable (enable)
38 | );
39 |
40 | always #10 clk <= ~clk;
41 |
42 | reg [15:0] ticks = 'd0;
43 | always @(posedge clk) begin
44 | $display($time, " ticks=%d", ticks);
45 | ticks <= ticks + 'd1;
46 | end
47 |
48 | always @(posedge clk)
49 | case (ticks)
50 | 'd1: begin
51 | foreground <= 'd01;
52 | background <= 'd02;
53 | gfx_bits <= 'b1010_0101_0000_1111_1001;
54 | char_row <= 'd0;
55 | mosaic <= FALSE;
56 | enabled <= TRUE;
57 | end
58 |
59 | 'd2: begin
60 | foreground <= 'd03;
61 | background <= 'd04;
62 | gfx_bits <= 'b1010_0101_0000_1111_1001;
63 | char_row <= 'd4;
64 | mosaic <= FALSE;
65 | enabled <= TRUE;
66 | end
67 |
68 | 'd3: begin
69 | foreground <= 'd05;
70 | background <= 'd06;
71 | gfx_bits <= 'b1010_0101_0000_1111_1001;
72 | char_row <= 'd8;
73 | mosaic <= FALSE;
74 | enabled <= TRUE;
75 | end
76 |
77 | 'd4: begin
78 | foreground <= 'd07;
79 | background <= 'd08;
80 | gfx_bits <= 'b1010_0101_0000_1111_1001;
81 | char_row <= 'd12;
82 | mosaic <= FALSE;
83 | enabled <= TRUE;
84 | end
85 |
86 | 'd5: begin
87 | foreground <= 'd08;
88 | background <= 'd09;
89 | gfx_bits <= 'b1010_0101_0000_1111_1001;
90 | char_row <= 'd16;
91 | mosaic <= FALSE;
92 | enabled <= TRUE;
93 | end
94 |
95 | 'd10: begin
96 | foreground <= 'd01;
97 | background <= 'd02;
98 | gfx_bits <= 'b1010_0101_0000_1111_1001;
99 | char_row <= 'd1;
100 | mosaic <= TRUE;
101 | enabled <= TRUE;
102 | end
103 |
104 | 'd11: begin
105 | foreground <= 'd03;
106 | background <= 'd04;
107 | gfx_bits <= 'b1010_0101_0000_1111_1001;
108 | char_row <= 'd5;
109 | mosaic <= TRUE;
110 | enabled <= TRUE;
111 | end
112 |
113 | 'd12: begin
114 | foreground <= 'd05;
115 | background <= 'd06;
116 | gfx_bits <= 'b1010_0101_0000_1111_1001;
117 | char_row <= 'd9;
118 | mosaic <= TRUE;
119 | enabled <= TRUE;
120 | end
121 |
122 | 'd13: begin
123 | foreground <= 'd07;
124 | background <= 'd08;
125 | gfx_bits <= 'b1010_0101_0000_1111_1001;
126 | char_row <= 'd13;
127 | mosaic <= TRUE;
128 | enabled <= TRUE;
129 | end
130 |
131 | 'd14: begin
132 | foreground <= 'd08;
133 | background <= 'd09;
134 | gfx_bits <= 'b1010_0101_0000_1111_1001;
135 | char_row <= 'd17;
136 | mosaic <= TRUE;
137 | enabled <= TRUE;
138 | end
139 |
140 | 'd15: $finish;
141 |
142 | default:
143 | enabled <= FALSE;
144 | endcase
145 |
146 | initial begin
147 | $monitor(
148 | $time,
149 | " enabled=%b, gfx_bits =%b, foreground =%d, background =%d\n",
150 | enabled, gfx_bits, foreground, background,
151 | " enable =%b, gfx_bitmap=%b , gfx_foreground=%d, gfx_background=%d\n",
152 | enable, gfx_bitmap, gfx_foreground, gfx_background
153 | );
154 |
155 | clk <= 1'b0;
156 | reset <= TRUE;
157 |
158 | #10 reset <= FALSE;
159 | end
160 |
161 | endmodule
--------------------------------------------------------------------------------
/src/vp_gfx_delay.v:
--------------------------------------------------------------------------------
1 | module vp_gfx_delay (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Inputs
6 | input wire [3:0] foreground,
7 | input wire [3:0] background,
8 | input wire [15:0] bitmap,
9 | input wire enabled,
10 |
11 | // Outputs
12 | output reg [3:0] gfx_foreground,
13 | output reg [3:0] gfx_background,
14 | output reg [15:0] gfx_bitmap,
15 | output reg enable
16 | );
17 |
18 | `include "constant.v"
19 |
20 | reg [49:0] fifo = 50'b0;
21 | always @(posedge clk) begin
22 | fifo <= { background, foreground, bitmap, enabled, fifo[49:25] };
23 | { gfx_background, gfx_foreground, gfx_bitmap, enable } <= fifo;
24 | end
25 | endmodule
--------------------------------------------------------------------------------
/src/vp_merge_bitmaps.v:
--------------------------------------------------------------------------------
1 | module vp_merge_bitmaps (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Text inputs
6 | input wire [3:0] txt_foreground,
7 | input wire [3:0] txt_background,
8 | input wire [15:0] txt_bitmap,
9 | input wire txt_enabled,
10 |
11 | // Graphic inputs
12 | input wire [3:0] gfx_foreground,
13 | input wire [3:0] gfx_background,
14 | input wire [15:0] gfx_bitmap,
15 | input wire gfx_enabled,
16 |
17 | // Outputs
18 | output reg [3:0] foreground,
19 | output reg [3:0] background,
20 | output reg [15:0] bitmap,
21 | output reg enable
22 | );
23 |
24 | `include "constant.v"
25 |
26 | always @(posedge clk) begin
27 | enable <= txt_enabled | gfx_enabled;
28 |
29 | foreground <= gfx_enabled ? gfx_foreground : txt_foreground;
30 | background <= gfx_enabled ? gfx_background : txt_background;
31 | bitmap <= gfx_enabled ? gfx_bitmap : txt_bitmap;
32 | end
33 | endmodule
--------------------------------------------------------------------------------
/src/vp_pipeline_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1 ns / 100 ps
2 | `include "vp_pipeline.v"
3 | `include "../font/font_sim.v"
4 | module vp_pipeline_tb ();
5 | `include "constant.v"
6 |
7 | reg clk;
8 | reg reset;
9 |
10 | reg [31:0] charattr;
11 | reg [4:0] char_row_in;
12 | reg [3:0] ypos;
13 | reg enabled;
14 |
15 | wire [14:0] font_address;
16 | wire [15:0] char_row_bitmap;
17 |
18 | wire [63:0] pixels;
19 | wire enable;
20 |
21 | vp_pipeline vp_pipeline (
22 | // Base signals
23 | .clk (clk),
24 | .reset (reset),
25 |
26 | // Inputs
27 | .charattr (charattr),
28 | .char_row_in (char_row_in),
29 | .ypos (ypos),
30 | .enabled (enabled),
31 |
32 | // Intermediate inputs/outputs
33 | .txt_font_address (font_address),
34 | .txt_char_row_bitmap (char_row_bitmap),
35 |
36 | // Outputs
37 | .pixels (pixels),
38 | .enable (enable)
39 | );
40 |
41 | font font (
42 | .clk (clk),
43 |
44 | .font_address (font_address),
45 | .char_row_bitmap (char_row_bitmap)
46 | );
47 |
48 | always #10 clk <= ~clk;
49 |
50 | reg [15:0] ticks = 'd0;
51 | always @(posedge clk) ticks <= ticks + 'd1;
52 |
53 | always @(posedge clk)
54 | case (ticks)
55 | 'd1: begin
56 | charattr <= {
57 | 4'd00, // Background
58 | 4'd15, // Foreground
59 | 4'b1111, // Pattern/border
60 | 2'd11, // Function = BORDER
61 | FALSE, // Underline
62 | FALSE, // Invert
63 | 2'd00, // Blink
64 | 2'd00, // Part
65 | 2'b01, // Size
66 | 10'h040 // Character '@'
67 | };
68 | char_row_in <= 'd00;
69 | ypos <= 'd00;
70 | enabled <= TRUE;
71 | end
72 |
73 | 'd02: begin char_row_in <= 'd01; ypos <= 'd01; enabled <= TRUE; end
74 | 'd03: begin char_row_in <= 'd02; ypos <= 'd02; enabled <= TRUE; end
75 | 'd04: begin char_row_in <= 'd03; ypos <= 'd03; enabled <= TRUE; end
76 | 'd05: begin char_row_in <= 'd04; ypos <= 'd04; enabled <= TRUE; end
77 | 'd06: begin char_row_in <= 'd05; ypos <= 'd05; enabled <= TRUE; end
78 | 'd07: begin char_row_in <= 'd06; ypos <= 'd06; enabled <= TRUE; end
79 | 'd08: begin char_row_in <= 'd07; ypos <= 'd07; enabled <= TRUE; end
80 | 'd09: begin char_row_in <= 'd08; ypos <= 'd08; enabled <= TRUE; end
81 | 'd10: begin char_row_in <= 'd09; ypos <= 'd09; enabled <= TRUE; end
82 | 'd11: begin char_row_in <= 'd10; ypos <= 'd10; enabled <= TRUE; end
83 | 'd12: begin char_row_in <= 'd11; ypos <= 'd11; enabled <= TRUE; end
84 | 'd13: begin char_row_in <= 'd12; ypos <= 'd12; enabled <= TRUE; end
85 | 'd14: begin char_row_in <= 'd13; ypos <= 'd13; enabled <= TRUE; end
86 | 'd15: begin char_row_in <= 'd14; ypos <= 'd14; enabled <= TRUE; end
87 | 'd16: begin char_row_in <= 'd15; ypos <= 'd15; enabled <= TRUE; end
88 | 'd17: begin char_row_in <= 'd16; ypos <= 'd16; enabled <= TRUE; end
89 | 'd18: begin char_row_in <= 'd17; ypos <= 'd17; enabled <= TRUE; end
90 | 'd19: begin char_row_in <= 'd18; ypos <= 'd18; enabled <= TRUE; end
91 | 'd20: begin char_row_in <= 'd19; ypos <= 'd19; enabled <= TRUE; end
92 |
93 | 'd31: begin
94 | charattr <= {
95 | 4'b00, // Background
96 | 4'd15, // Foreground
97 | 4'b1010, // First 10 bits
98 | 4'b0101,
99 | 2'b11__,
100 | 2'b01, // Part
101 | 2'd00, // Size
102 | 2'b11, // Last 10 bits
103 | 4'b1001,
104 | 4'b0110
105 | };
106 | char_row_in <= 'd00;
107 | ypos <= 'd00;
108 | enabled <= TRUE;
109 | end
110 |
111 | 'd32: begin char_row_in <= 'd01; ypos <= 'd01; enabled <= TRUE; end
112 | 'd33: begin char_row_in <= 'd02; ypos <= 'd02; enabled <= TRUE; end
113 | 'd34: begin char_row_in <= 'd03; ypos <= 'd03; enabled <= TRUE; end
114 | 'd35: begin char_row_in <= 'd04; ypos <= 'd04; enabled <= TRUE; end
115 | 'd36: begin char_row_in <= 'd05; ypos <= 'd05; enabled <= TRUE; end
116 | 'd37: begin char_row_in <= 'd06; ypos <= 'd06; enabled <= TRUE; end
117 | 'd38: begin char_row_in <= 'd07; ypos <= 'd07; enabled <= TRUE; end
118 | 'd39: begin char_row_in <= 'd08; ypos <= 'd08; enabled <= TRUE; end
119 | 'd40: begin char_row_in <= 'd09; ypos <= 'd09; enabled <= TRUE; end
120 | 'd41: begin char_row_in <= 'd10; ypos <= 'd10; enabled <= TRUE; end
121 | 'd42: begin char_row_in <= 'd11; ypos <= 'd11; enabled <= TRUE; end
122 | 'd43: begin char_row_in <= 'd12; ypos <= 'd12; enabled <= TRUE; end
123 | 'd44: begin char_row_in <= 'd13; ypos <= 'd13; enabled <= TRUE; end
124 | 'd45: begin char_row_in <= 'd14; ypos <= 'd14; enabled <= TRUE; end
125 | 'd46: begin char_row_in <= 'd15; ypos <= 'd15; enabled <= TRUE; end
126 | 'd47: begin char_row_in <= 'd16; ypos <= 'd16; enabled <= TRUE; end
127 | 'd48: begin char_row_in <= 'd17; ypos <= 'd17; enabled <= TRUE; end
128 | 'd49: begin char_row_in <= 'd18; ypos <= 'd18; enabled <= TRUE; end
129 | 'd50: begin char_row_in <= 'd19; ypos <= 'd19; enabled <= TRUE; end
130 |
131 | 'd64: $finish;
132 |
133 | default:
134 | enabled <= FALSE;
135 | endcase
136 |
137 | always @(posedge clk)
138 | if (enable) begin
139 | $display($time, " ticks=%d, pixels=%b", ticks, pixels);
140 | end else begin
141 | $display($time, " ticks=%d", ticks);
142 | end
143 |
144 | initial begin
145 | clk <= 1'b0;
146 | reset <= TRUE;
147 |
148 | #10 reset <= FALSE;
149 | end
150 |
151 | endmodule
--------------------------------------------------------------------------------
/src/vp_text_delay.v:
--------------------------------------------------------------------------------
1 | module vp_text_delay (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Inputs
6 | input wire [3:0] foreground,
7 | input wire [3:0] background,
8 | input wire horz_size,
9 | input wire horz_part,
10 | input wire [15:0] pattern,
11 | input wire [15:0] border,
12 | input wire [1:0] func,
13 | input wire blink,
14 | input wire invert,
15 | input wire underline,
16 | input wire enabled,
17 |
18 | // Text output
19 | output reg [3:0] txt_foreground,
20 | output reg [3:0] txt_background,
21 | output reg txt_horz_size,
22 | output reg txt_horz_part,
23 | output reg [15:0] txt_pattern,
24 | output reg [15:0] txt_border,
25 | output reg [1:0] txt_func,
26 | output reg txt_blink,
27 | output reg txt_invert,
28 | output reg txt_underline,
29 | output reg txt_enable
30 | );
31 |
32 | `include "constant.v"
33 |
34 | reg [47:0] fifo;
35 | always @(posedge clk) begin
36 | fifo <= {
37 | background,
38 | foreground,
39 | horz_size,
40 | horz_part,
41 | pattern,
42 | border,
43 | func,
44 | blink,
45 | invert,
46 | underline,
47 | enabled
48 | };
49 |
50 | { txt_background,
51 | txt_foreground,
52 | txt_horz_size,
53 | txt_horz_part,
54 | txt_pattern,
55 | txt_border,
56 | txt_func,
57 | txt_blink,
58 | txt_invert,
59 | txt_underline,
60 | txt_enable } <= fifo;
61 | end
62 | endmodule
--------------------------------------------------------------------------------
/src/vp_text_pattern.v:
--------------------------------------------------------------------------------
1 | module vp_text_pattern (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Inputs
6 | input wire [3:0] foreground,
7 | input wire [3:0] background,
8 | input wire [15:0] char_row_bitmap,
9 | input wire [15:0] pattern,
10 | input wire [15:0] border,
11 | input wire [1:0] func,
12 | input wire blink,
13 | input wire invert,
14 | input wire enabled,
15 |
16 | // Outputs
17 | output reg [3:0] txt_foreground,
18 | output reg [3:0] txt_background,
19 | output reg [15:0] txt_bitmap,
20 | output reg enable
21 | );
22 |
23 | `include "constant.v"
24 | `include "video_controller/apply_pattern.v"
25 |
26 | always @(posedge clk) begin
27 | enable <= enabled;
28 | txt_bitmap <= border | apply_pattern(func, char_row_bitmap, pattern);
29 |
30 | if (invert) begin
31 | txt_foreground <= blink ? foreground : background;
32 | txt_background <= foreground;
33 | end else begin
34 | txt_foreground <= blink ? background : foreground;
35 | txt_background <= background;
36 | end
37 | end
38 | endmodule
--------------------------------------------------------------------------------
/src/vp_text_resize.v:
--------------------------------------------------------------------------------
1 | module vp_text_resize (
2 | // Base signals
3 | input wire clk,
4 |
5 | // Inputs
6 | input wire [3:0] foreground,
7 | input wire [3:0] background,
8 | input wire [15:0] char_row_bitmap,
9 | input wire horz_size,
10 | input wire horz_part,
11 | input wire [15:0] pattern,
12 | input wire [15:0] border,
13 | input wire [1:0] func,
14 | input wire blink,
15 | input wire invert,
16 | input wire underline,
17 | input wire enabled,
18 |
19 | // Outputs
20 | output reg [3:0] txt_foreground,
21 | output reg [3:0] txt_background,
22 | output reg [15:0] txt_char_row_bitmap,
23 | output reg [15:0] txt_pattern,
24 | output reg [15:0] txt_border,
25 | output reg [1:0] txt_func,
26 | output reg txt_blink,
27 | output reg txt_invert,
28 | output reg enable
29 | );
30 |
31 | `include "constant.v"
32 | `include "video_controller/horizontal_resize.v"
33 |
34 | always @(posedge clk) begin
35 | enable <= enabled;
36 |
37 | if (enabled) begin
38 | if (underline) begin
39 | txt_char_row_bitmap <= 16'b1111111111111111;
40 | end else begin
41 | txt_char_row_bitmap <= horizontal_resize(
42 | horz_size, horz_part, char_row_bitmap
43 | );
44 | end
45 |
46 | txt_foreground <= foreground;
47 | txt_background <= background;
48 | txt_pattern <= pattern;
49 | txt_border <= border;
50 | txt_func <= func;
51 | txt_blink <= blink;
52 | txt_invert <= invert;
53 | end
54 | end
55 | endmodule
--------------------------------------------------------------------------------
/terminfo/Makefile:
--------------------------------------------------------------------------------
1 | ALL:
2 | tic myterminal.ti
3 |
--------------------------------------------------------------------------------
/terminfo/bug_scroll_up.myt:
--------------------------------------------------------------------------------
1 | # https://github.com/Zigazou/myterminal/issues/2
2 | reset
3 | foreground white
4 | background black
5 | cursor visible
6 | clearscreen
7 | locate 37 0
8 | print "ROW 00"
9 | locate 37 1
10 | print "ROW 01"
11 | locate 37 2
12 | print "ROW 02"
13 | locate 37 48
14 | print "ROW 48"
15 | locate 37 49
16 | print "ROW 49"
17 | locate 37 50
18 | print "ROW 50"
19 | locate 37 25
20 | print "AAA"
21 | scroll down
22 | print "BBB"
23 | scroll down
24 | print "CCC"
25 |
--------------------------------------------------------------------------------
/terminfo/dircolors:
--------------------------------------------------------------------------------
1 | # Configuration file for dircolors, a utility to help you set the
2 | # LS_COLORS environment variable used by GNU ls with the --color option.
3 | # Copyright (C) 1996-2016 Free Software Foundation, Inc.
4 | # Copying and distribution of this file, with or without modification,
5 | # are permitted provided the copyright notice and this notice are preserved.
6 | # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
7 | # slackware version of dircolors) are recognized but ignored.
8 | # Below are TERM entries, which can be a glob patterns, to match
9 | # against the TERM environment variable to determine if it is colorizable.
10 |
11 | TERM myterminal
12 | LEFTCODE \000
13 | RIGHTCODE \000
14 | ENDCODE ^E*^BG^BP
15 |
16 | # Below are the color init strings for the basic file types. A color init
17 | # string consists of one or more of the following numeric codes:
18 | RESET O\005*^BP # reset to "normal" color
19 | DIR ^B\114 # directory
20 | LINK ^B\116 # symbolic link. (If you set this to 'target' instead of a
21 | # numerical value, the color is as for the file pointed to.)
22 | MULTIHARDLINK O\005* # regular file with more than one link
23 | NORMAL ^BP^BG^E*
24 | FIFO ^B\120^B\103 # pipe
25 | SOCK ^B\115 # socket
26 | DOOR ^B\115 # door
27 | BLK ^B\120^B\113 # block device driver
28 | CHR ^B\120^B\113 # character device driver
29 | ORPHAN ^B\120^B\111 # symlink to nonexistent file, or non-stat'able file ...
30 | MISSING ^BG^E* # ... and the files they point to
31 | SETUID ^B\107^B\121 # file that is setuid (u+s)
32 | SETGID ^B\100^B\123 # file that is setgid (g+s)
33 | CAPABILITY ^B\100^B\121 # file with capability
34 | STICKY_OTHER_WRITABLE ^B\100^B\122 # dir that is sticky and other-writable (+t,o+w)
35 | OTHER_WRITABLE ^B\104^B\122 # dir that is other-writable (o+w) and not sticky
36 | STICKY ^B\107^B\124 # dir with the sticky bit set (+t) and not other-writable
37 |
38 | # This is for files with execute permission:
39 | EXEC ^B\112
40 |
41 | # List any file extensions like '.gz' or '.tar' that you would like ls
42 | # to colorize below. Put the extension, a space, and the color init string.
43 | # (and any comments you want to add after a '#')
44 | # archives or compressed (bright red)
45 | .tar ^B\111
46 | .tgz ^B\111
47 | .arc ^B\111
48 | .arj ^B\111
49 | .taz ^B\111
50 | .lha ^B\111
51 | .lz4 ^B\111
52 | .lzh ^B\111
53 | .lzma ^B\111
54 | .tlz ^B\111
55 | .txz ^B\111
56 | .tzo ^B\111
57 | .t7z ^B\111
58 | .zip ^B\111
59 | .z ^B\111
60 | .Z ^B\111
61 | .dz ^B\111
62 | .gz ^B\111
63 | .lrz ^B\111
64 | .lz ^B\111
65 | .lzo ^B\111
66 | .xz ^B\111
67 | .zst ^B\111
68 | .tzst ^B\111
69 | .bz2 ^B\111
70 | .bz ^B\111
71 | .tbz ^B\111
72 | .tbz2 ^B\111
73 | .tz ^B\111
74 | .deb ^B\111
75 | .rpm ^B\111
76 | .jar ^B\111
77 | .war ^B\111
78 | .ear ^B\111
79 | .sar ^B\111
80 | .rar ^B\111
81 | .alz ^B\111
82 | .ace ^B\111
83 | .zoo ^B\111
84 | .cpio ^B\111
85 | .7z ^B\111
86 | .rz ^B\111
87 | .cab ^B\111
88 |
89 | # image formats
90 | .jpg ^B\115
91 | .jpeg ^B\115
92 | .mjpg ^B\115
93 | .mjpeg ^B\115
94 | .gif ^B\115
95 | .bmp ^B\115
96 | .pbm ^B\115
97 | .pgm ^B\115
98 | .ppm ^B\115
99 | .tga ^B\115
100 | .xbm ^B\115
101 | .xpm ^B\115
102 | .tif ^B\115
103 | .tiff ^B\115
104 | .png ^B\115
105 | .svg ^B\115
106 | .svgz ^B\115
107 | .mng ^B\115
108 | .pcx ^B\115
109 | .mov ^B\115
110 | .mpg ^B\115
111 | .mpeg ^B\115
112 | .m2v ^B\115
113 | .mkv ^B\115
114 | .webm ^B\115
115 | .ogm ^B\115
116 | .mp4 ^B\115
117 | .m4v ^B\115
118 | .mp4v ^B\115
119 | .vob ^B\115
120 | .qt ^B\115
121 | .nuv ^B\115
122 | .wmv ^B\115
123 | .asf ^B\115
124 | .rm ^B\115
125 | .rmvb ^B\115
126 | .flc ^B\115
127 | .avi ^B\115
128 | .fli ^B\115
129 | .flv ^B\115
130 | .gl ^B\115
131 | .dl ^B\115
132 | .xcf ^B\115
133 | .xwd ^B\115
134 | .yuv ^B\115
135 | .cgm ^B\115
136 | .emf ^B\115
137 |
138 | # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
139 | .ogv ^B\115
140 | .ogx ^B\115
141 |
142 | # audio formats
143 | .aac ^B\106
144 | .au ^B\106
145 | .flac ^B\106
146 | .m4a ^B\106
147 | .mid ^B\106
148 | .midi ^B\106
149 | .mka ^B\106
150 | .mp3 ^B\106
151 | .mpc ^B\106
152 | .ogg ^B\106
153 | .ra ^B\106
154 | .wav ^B\106
155 |
156 | # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
157 | .oga ^B\106
158 | .opus ^B\106
159 | .spx ^B\106
160 | .xspf ^B\106
161 |
--------------------------------------------------------------------------------
/terminfo/hello-world.myt:
--------------------------------------------------------------------------------
1 | # Hello, World!
2 | reset
3 | foreground lightyellow
4 | background black
5 | cursor visible
6 | clearscreen
7 | size double
8 | locate 30 24
9 | print "MyTerminal"
10 | locate 20 26
11 | size normal
12 | foreground blue
13 | charpage 3
14 | print "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"
15 | charpage 0
16 | locate 30 27
17 | foreground white
18 | print "par Frédéric BISSON"
--------------------------------------------------------------------------------
/terminfo/hello-world.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zigazou/myterminal/11da0a573a0928bc2425e0fe9faa69b3b7dbc075/terminfo/hello-world.raw
--------------------------------------------------------------------------------
/terminfo/mouse_enable.myt:
--------------------------------------------------------------------------------
1 | mouse enable
2 | print "Mouse events enabled"
--------------------------------------------------------------------------------
/terminfo/myterminal.ti:
--------------------------------------------------------------------------------
1 | myterminal|MyTerminal,
2 | # == Boolean/Numeric capabilities ==============================================
3 | # MyTerminal is 80x51
4 | cols#80,
5 | lines#51,
6 | # MyTerminal can display any combination of 16 colors
7 | colors#16,
8 | pairs#256,
9 | # Automatic right margins wrap
10 | am,
11 | sam,
12 | # Wide char size
13 | widcs#2,
14 | # Screen erased with background color
15 | bce,
16 | # mir,
17 | # msgr,
18 | # == String capabilities =======================================================
19 | # Clear screen, home cursor
20 | clear=^A!,
21 | # Clear to beginning of line/to end of line/to end of screen/delete line/n chars
22 | el1=^A),
23 | el=^A(,
24 | ed=^A*,
25 | dl=^A-,
26 | ech=^A%p1%'0'%+%c,
27 | # Bell
28 | bel=^G,
29 | # Carriage return
30 | cr=^M,
31 | # Newline
32 | nel=^J,
33 | # Scroll text up/down
34 | ri=^K,
35 | ind=^L,
36 | # Set foreground/background color
37 | setaf=^B%p1%'@'%+%c,
38 | setab=^B%p1%'P'%+%c,
39 | # Set default foreground and background colors
40 | op=^BG^BP,
41 | # Reset attributes
42 | sgr0=^E*,
43 | sgr=^E*%?%p1%t^EH^ER%;
44 | %?%p2%t^EU%;
45 | %?%p3%t^ER%;
46 | %?%p4%t^EB%;
47 | %?%p5%t^Eh%;
48 | %?%p6%t^EH%;
49 | %?%p9%t^U%e^S%;,
50 | # Cursor movement with no auto-margins (up/down/left/right)
51 | cuu1=^N,
52 | cud1=^O,
53 | cub1=^P,
54 | cuf1=^Q,
55 | # Absolute positionning
56 | home=^D00,
57 | cup=^D%p1%'0'%+%c%p2%'0'%+%c,
58 | # Absolute column positionning
59 | hpa=^D#%p1%'0'%+%c,
60 | # Absolute row positionning
61 | vpa=^D%p1%'0'%+%c#,
62 | # Cursor visibility (visible/very visible/hidden)
63 | cnorm=^FC,
64 | cvvis=^FV,
65 | civis=^Fc,
66 | # Bold
67 | bold=^EH,
68 | # Blinking
69 | blink=^EB,
70 | # Reverse video mode
71 | rev=^ER,
72 | smso=^ER,
73 | rmso=^Er,
74 | # rrev=^Er,
75 | # Underline mode enter/end
76 | smul=^EU,
77 | rmul=^Eu,
78 | # Character size
79 | swidm=^E1,
80 | rwidm=^E0,
81 | # List of superscriptable characters
82 | supcs=aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz,
83 | # Superscript mode enter/end
84 | ssupm=^FS,
85 | rsupm=^Fs,
86 | # Alternate character set enter/end
87 | smacs=^U,
88 | rmacs=^S,
89 | # List of graphical characters
90 | acsc=+\315\,\317-\314.\316j\051k\054l\046m\043n\057q\052t\047u\055v\053w\056x\045,
91 | # Repeat char
92 | # rep=%p1%c^R%p2%'0'%+%c,
93 | # Backspace
94 | kbs=\376,
95 | # Cursor keys
96 | kcuu1=^_@\346,
97 | kcub1=^_@\347, kLFT=^_A\351,
98 | kcud1=^_@\350,
99 | kcuf1=^_@\351, kRIT=^_A\351,
100 | # Insert, home, page up, delete, end, page down
101 | kich1=^_@\340, kIC=^_A\340,
102 | khome=^_@\341, kHOM=^_A\341,
103 | kpp=^_@\342,
104 | kdch1=^_@\343, kDC=^_A\343,
105 | kend=^_@\344, kEND=^_A\344,
106 | knp=^_@\345,
107 | # Special keys
108 | kopt=^_@\352, kOPT=^_A\352,
109 | kprt=^_@\377,
110 | # The 12 function keys
111 | kf1=^_@\361,
112 | kf2=^_@\362,
113 | kf3=^_@\363,
114 | kf4=^_@\364,
115 | kf5=^_@\365,
116 | kf6=^_@\366,
117 | kf7=^_@\367,
118 | kf8=^_@\370,
119 | kf9=^_@\371,
120 | kf10=^_@\372,
121 | kf11=^_@\373,
122 | kf12=^_@\374,
123 | # The same 12 function keys shifted
124 | kf13=^_A\361,
125 | kf14=^_A\362,
126 | kf15=^_A\363,
127 | kf16=^_A\364,
128 | kf17=^_A\365,
129 | kf18=^_A\366,
130 | kf19=^_A\367,
131 | kf20=^_A\370,
132 | kf21=^_A\371,
133 | kf22=^_A\372,
134 | kf23=^_A\373,
135 | kf24=^_A\374,
136 | # The same 12 function keys ctrl'ed
137 | kf25=^_B\361,
138 | kf26=^_B\362,
139 | kf27=^_B\363,
140 | kf28=^_B\364,
141 | kf29=^_B\365,
142 | kf30=^_B\366,
143 | kf31=^_B\367,
144 | kf32=^_B\370,
145 | kf33=^_B\371,
146 | kf34=^_B\372,
147 | kf35=^_B\373,
148 | kf36=^_B\374,
149 | # The same 12 function keys alt'ed
150 | kf37=^_D\361,
151 | kf38=^_D\362,
152 | kf39=^_D\363,
153 | kf40=^_D\364,
154 | kf41=^_D\365,
155 | kf42=^_D\366,
156 | kf43=^_D\367,
157 | kf44=^_D\370,
158 | kf45=^_D\371,
159 | kf46=^_D\372,
160 | kf47=^_D\373,
161 | kf48=^_D\374,
162 |
--------------------------------------------------------------------------------
/terminfo/myterminal_agetty:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if [ "$USER" != "root" ]
3 | then
4 | printf "This script needs to be run as root or with sudo\n"
5 | exit 1
6 | fi
7 |
8 | export TTY_DEVICE=ttyUSB0
9 |
10 | export TERM=myterminal
11 | export LANG="fr_FR.iso885915@euro"
12 | export LANGUAGE=
13 | export LC_CTYPE="fr_FR.iso885915@euro"
14 | export LC_NUMERIC="fr_FR.iso885915@euro"
15 | export LC_TIME="fr_FR.iso885915@euro"
16 | export LC_COLLATE="fr_FR.iso885915@euro"
17 | export LC_MONETARY="fr_FR.iso885915@euro"
18 | export LC_MESSAGES="fr_FR.iso885915@euro"
19 | export LC_PAPER="fr_FR.iso885915@euro"
20 | export LC_NAME="fr_FR.iso885915@euro"
21 | export LC_ADDRESS="fr_FR.iso885915@euro"
22 | export LC_TELEPHONE="fr_FR.iso885915@euro"
23 | export LC_MEASUREMENT="fr_FR.iso885915@euro"
24 | export LC_IDENTIFICATION="fr_FR.iso885915@euro"
25 | export LC_ALL=
26 | export INPUTRC=/home/fred/Documents/dev/FPGA/myterminal-backport/terminfo/myterminal_inputrc
27 |
28 | # Run terminal
29 | setsid agetty \
30 | --8bits \
31 | --flow-control \
32 | --keep-baud \
33 | --nohints \
34 | --local-line \
35 | --login-options "-p -- \\u" \
36 | $TTY_DEVICE \
37 | 3000000 \
38 | myterminal
39 |
--------------------------------------------------------------------------------
/terminfo/myterminal_inputrc:
--------------------------------------------------------------------------------
1 | # myterminal_inputrc - inputrc for myterminal
2 | # See readline(3readline) for more information.
3 |
4 | set input-meta on
5 | set output-meta on
6 | set bell-style none
7 | set convert-meta off
8 |
9 | # allow the use of the cursor keys
10 | "\037@\347": backward-char
11 | "\037@\351": forward-char
12 | "\037@\346": previous-history
13 | "\037@\350": next-history
14 |
15 | # allow the use of the Home/End keys
16 | "\037@\341": beginning-of-line
17 | "\037@\344": end-of-line
18 |
19 | # allow the use of the Delete/Insert keys
20 | "\037@\343": delete-char
21 | "\037@\340": quoted-insert
22 |
23 | # mappings for "page up" and "page down" to step to the beginning/end
24 | # of the history
25 | "\037@\342": beginning-of-history
26 | "\037@\345": end-of-history
27 |
28 | # alternate mappings for "page up" and "page down" to search the history
29 | # "\037@\342": history-search-backward
30 | # "\037@\345": history-search-forward
31 |
32 | # mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving
33 | "\037B\347": backward-word
34 | "\037B\351": forward-word
35 |
--------------------------------------------------------------------------------