├── .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 | OMyTerminal 2 |   0 3 |   1 4 |   2 5 |   3 6 |   4 7 |   5 8 |   6 9 |   7 10 |   8 11 |   9 12 |   10 13 |   11 14 |   12 15 |   13 16 |   14 17 |   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 | OMyTerminal 2 |  3 | MyTerminal is a serial terminal implemented on an FPGA. 4 | 5 | NCharacteristics 6 |  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 | NRequirements 21 |  22 | - Tang SiPeed Primer (Anlogic Eagle EG4S20BG256) 23 | - Tang Dynasty 4.6 24 | - Icarus Verilog 25 | - Python 3 26 | 27 | NNotes 28 |  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 | --------------------------------------------------------------------------------