├── .gitignore ├── 74138.v ├── 74139.v ├── 74151.v ├── 74161.v ├── 74251.v ├── 74574.v ├── 74593.v ├── Docs ├── CSCvon8_design.md ├── Figs │ ├── 151_wire1.jpg │ ├── 151_wire2.jpg │ ├── 20190607_board.jpg │ ├── 555_astable.jpg │ ├── 555_board1.jpg │ ├── 555_board2.jpg │ ├── 555_board3.jpg │ ├── CSCvon8_overview.dia │ ├── CSCvon8_overview.png │ ├── PC_circuit.png │ ├── UM245R.jpg │ ├── UM245R_vertical.png │ ├── alu_design.dia │ ├── alu_design.png │ ├── breadboard_20190426.jpg │ ├── breadboard_20190502.jpg │ ├── breadboard_20190504.jpg │ ├── breadboard_20190505.jpg │ ├── breadboard_20190506.jpg │ ├── clk_pulse_reset.jpg │ ├── dbwriter.png │ ├── dip28_not_socket.jpg │ ├── dip28_socket.jpg │ ├── example_aload.png │ ├── ir_decode_etc.png │ ├── jump_glitch.png │ ├── led_array.jpg │ ├── pcb_20190517a.jpg │ ├── pcb_20190518.jpg │ ├── pcb_20190601.jpg │ ├── reader_demux.png │ ├── usequencer.png │ └── waveforms-tim58a.gif ├── bom_20190601.csv ├── building_the_CSCvon8.md ├── cas_assembler.md ├── clc_compiler.md ├── getgoing_instructions.md └── implementation_notes.md ├── Examples ├── example01.s ├── example02.s ├── example03.s ├── example04.s ├── example05.s ├── example06.s ├── example07.s ├── example08.s ├── example09.s ├── example10.s ├── example11.s ├── himinsky.cl ├── hiprhex.cl ├── legetests.cl ├── minsky.s ├── monitor.s ├── print_indir_str.s ├── print_str.s ├── signedprint.cl ├── triangle.cl ├── ttt.s ├── tttmoves.s └── wktlife.s ├── LICENSE ├── Makefile ├── README.md ├── ROMs ├── aluread ├── aluwrite ├── decread ├── decwrite ├── iread └── iwrite ├── Schematic ├── ALU_DataRegs.bak ├── ALU_DataRegs.sch ├── Addressing.bak ├── Addressing.sch ├── Analog.bak ├── Analog.sch ├── IR_Decode.bak ├── IR_Decode.sch ├── Makefile ├── MemoryIO.bak ├── MemoryIO.sch ├── Schematic-cache.bak ├── Schematic-cache.bck ├── Schematic-cache.dcm ├── Schematic-cache.lib ├── Schematic-rescue.lib ├── Schematic.bak ├── Schematic.jpg ├── Schematic.kicad_pcb ├── Schematic.pro ├── Schematic.sch ├── fp-lib-table ├── gui_defaults.par ├── library │ ├── 7400-ic.lib │ ├── 74LS139.bak │ ├── 74LS139.bck │ ├── 74LS139.dcm │ ├── 74LS139.lib │ ├── 74LS153.dcm │ ├── 74LS153.lib │ ├── 74LS161.bak │ ├── 74LS161.bck │ ├── 74LS161.dcm │ ├── 74LS161.lib │ ├── 74LS241.bak │ ├── 74LS241.bck │ ├── 74LS241.dcm │ ├── 74LS241.lib │ ├── 74LS574.dcm │ ├── 74LS574.lib │ ├── 74LS593.bak │ ├── 74LS593.bck │ ├── 74LS593.dcm │ ├── 74LS593.lib │ ├── AT27C1024-70PU.bak │ ├── AT27C1024-70PU.bck │ ├── AT27C1024-70PU.dcm │ ├── AT27C1024-70PU.lib │ ├── AT27C1024-70PU.mod │ ├── HM62256.dcm │ ├── HM62256.lib │ ├── M27C322-100F1.bak │ ├── M27C322-100F1.bck │ ├── M27C322-100F1.dcm │ ├── M27C322-100F1.lib │ ├── M27C322-100F1.mod │ ├── QX14T50B1.843200B50TT.bak │ ├── QX14T50B1.843200B50TT.bck │ ├── QX14T50B1.843200B50TT.dcm │ ├── QX14T50B1.843200B50TT.lib │ ├── QX14T50B1.843200B50TT.mod │ ├── SN74LS273NE4.dcm │ ├── SN74LS273NE4.lib │ ├── SN74LS273NE4.mod │ ├── UM245R.bak │ ├── UM245R.bck │ ├── UM245R.dcm │ ├── UM245R.lib │ ├── UM245R.mod │ ├── memory.bak │ ├── memory.bck │ ├── memory.dcm │ └── memory.lib └── schematic.pdf ├── cas ├── clc ├── csim ├── disasm ├── empty.ram ├── gen_alu ├── gen_ucode ├── icarus_tb.v ├── journal.md ├── microcode ├── opcodes ├── ram.v ├── rom.v ├── tbhelper.v ├── ttlcsvon8.v └── uart.v /.gitignore: -------------------------------------------------------------------------------- 1 | RCS 2 | *.out 3 | *.rom 4 | *.vcd 5 | *.gtkw 6 | alu.hex 7 | Schematic/Schematic.bin 8 | Schematic/Schematic.dsn 9 | Schematic/Schematic.kicad_pcb-bak 10 | Schematic/Schematic.net 11 | Schematic/Schematic.rules 12 | Schematic/Schematic.ses 13 | Schematic/bom.csv 14 | Schematic/fp-info-cache 15 | Schematic/rescue-backup 16 | Schematic/sym-lib-table 17 | Schematic/Gerber 18 | Schematic/Schematic.xml 19 | Schematic/newbom.csv 20 | Schematic/oldbom.csv 21 | Misc 22 | -------------------------------------------------------------------------------- /74138.v: -------------------------------------------------------------------------------- 1 | // 3-line to 8-line decoder/demultiplexer (inverted outputs) 2 | // (c) Tim Rudy, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74138 #(parameter WIDTH_OUT = 8, WIDTH_IN = $clog2(WIDTH_OUT), 6 | DELAY_RISE = 21, DELAY_FALL = 21) 7 | ( 8 | input Enable1_bar, 9 | input Enable2_bar, 10 | input Enable3, 11 | input [WIDTH_IN-1:0] A, 12 | output [WIDTH_OUT-1:0] Y 13 | ); 14 | 15 | //------------------------------------------------// 16 | reg [WIDTH_OUT-1:0] computed; 17 | integer i; 18 | 19 | always @(*) 20 | begin 21 | for (i = 0; i < WIDTH_OUT; i++) 22 | begin 23 | /* verilator lint_off WIDTH */ 24 | if (!Enable1_bar && !Enable2_bar && Enable3 && i == A) 25 | /* verilator lint_on WIDTH */ 26 | computed[i] = 1'b0; 27 | else 28 | computed[i] = 1'b1; 29 | end 30 | end 31 | //------------------------------------------------// 32 | 33 | /* verilator lint_off ASSIGNDLY */ 34 | assign #(DELAY_RISE, DELAY_FALL) Y = computed; 35 | /* verilator lint_on ASSIGNDLY */ 36 | 37 | endmodule 38 | /* verilator lint_on DECLFILENAME */ 39 | -------------------------------------------------------------------------------- /74139.v: -------------------------------------------------------------------------------- 1 | // Dual 2-line to 4-line decoder/demultiplexer (inverted outputs) 2 | // (c) Tim Rudy, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74139 #(parameter BLOCKS = 2, WIDTH_OUT = 4, 6 | WIDTH_IN = $clog2(WIDTH_OUT), 7 | DELAY_RISE = 25, DELAY_FALL = 25) 8 | ( 9 | input [BLOCKS-1:0] Enable_bar, 10 | input [WIDTH_IN*BLOCKS-1:0] A_2D, 11 | output [WIDTH_OUT*BLOCKS-1:0] Y_2D 12 | ); 13 | 14 | //------------------------------------------------// 15 | wire [WIDTH_IN-1:0] A [0:BLOCKS-1]; 16 | reg [WIDTH_OUT-1:0] computed [0:BLOCKS-1]; 17 | wire [WIDTH_OUT*BLOCKS-1:0] computed_2D; 18 | integer i; 19 | integer j; 20 | 21 | always @(*) 22 | begin 23 | for (i = 0; i < BLOCKS; i++) 24 | begin 25 | for (j = 0; j < WIDTH_OUT; j++) 26 | begin 27 | /* verilator lint_off WIDTH */ 28 | if (!Enable_bar[i] && j == A[i]) 29 | /* verilator lint_on WIDTH */ 30 | computed[i][j] = 1'b0; 31 | else 32 | computed[i][j] = 1'b1; 33 | end 34 | end 35 | end 36 | //------------------------------------------------// 37 | 38 | `ASSIGN_UNPACK(WIDTH_IN, BLOCKS, A, A_2D) 39 | `ASSIGN_PACK(WIDTH_OUT, BLOCKS, computed, computed_2D) 40 | /* verilator lint_off ASSIGNDLY */ 41 | assign #(DELAY_RISE, DELAY_FALL) Y_2D = computed_2D; 42 | /* verilator lint_on ASSIGNDLY */ 43 | 44 | endmodule 45 | /* verilator lint_on DECLFILENAME */ 46 | -------------------------------------------------------------------------------- /74151.v: -------------------------------------------------------------------------------- 1 | // 8-input multiplexer; low output when disabled 2 | // (c) Warren Toomey, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74151 #(parameter DELAY_RISE = 20, DELAY_FALL = 20) 6 | ( 7 | input Output_bar, 8 | input [7:0] I, 9 | input [2:0] S, 10 | output Y, 11 | output Y_bar 12 | ); 13 | 14 | //------------------------------------------------// 15 | wire internal_Y; 16 | wire internal_Y_bar; 17 | 18 | assign internal_Y = (S== 3'b000) ? I[0] : 19 | (S== 3'b001) ? I[1] : 20 | (S== 3'b010) ? I[2] : 21 | (S== 3'b011) ? I[3] : 22 | (S== 3'b100) ? I[4] : 23 | (S== 3'b101) ? I[5] : 24 | (S== 3'b110) ? I[6] : I[7]; 25 | assign internal_Y_bar= ~internal_Y; 26 | 27 | //------------------------------------------------// 28 | 29 | /* verilator lint_off ASSIGNDLY */ 30 | assign #(DELAY_RISE, DELAY_FALL) Y = (!Output_bar) ? internal_Y : 1'b0; 31 | assign #(DELAY_RISE, DELAY_FALL) Y_bar = (!Output_bar) ? internal_Y_bar : 1'b1; 32 | /* verilator lint_on ASSIGNDLY */ 33 | 34 | endmodule 35 | /* verilator lint_on DECLFILENAME */ 36 | -------------------------------------------------------------------------------- /74161.v: -------------------------------------------------------------------------------- 1 | // 4-bit modulo 16 binary counter with parallel load, asynchronous clear 2 | // (c) Tim Rudy, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74161 #(parameter WIDTH = 4, DELAY_RISE = 22, DELAY_FALL = 22) 6 | ( 7 | input Clear_bar, 8 | input Load_bar, 9 | input ENT, 10 | input ENP, 11 | input [WIDTH-1:0] D, 12 | input Clk, 13 | output RCO, 14 | output [WIDTH-1:0] Q 15 | ); 16 | 17 | //------------------------------------------------// 18 | wire RCO_current; 19 | reg [WIDTH-1:0] Q_current; 20 | wire [WIDTH-1:0] Q_next; 21 | 22 | assign Q_next = Q_current + 1; 23 | 24 | always @(posedge Clk or negedge Clear_bar) 25 | begin 26 | if (!Clear_bar) 27 | begin 28 | Q_current <= {WIDTH{1'b0}}; 29 | end 30 | else 31 | begin 32 | if (!Load_bar) 33 | begin 34 | Q_current <= D; 35 | end 36 | 37 | if (Load_bar && ENT && ENP) 38 | begin 39 | Q_current <= Q_next; 40 | end 41 | end 42 | end 43 | 44 | // outputs 45 | assign RCO_current = ENT && (&Q_current); 46 | 47 | //------------------------------------------------// 48 | 49 | /* verilator lint_off ASSIGNDLY */ 50 | assign #(DELAY_RISE, DELAY_FALL) RCO = RCO_current; 51 | assign #(DELAY_RISE, DELAY_FALL) Q = Q_current; 52 | /* verilator lint_on ASSIGNDLY */ 53 | 54 | endmodule 55 | /* verilator lint_on DECLFILENAME */ 56 | -------------------------------------------------------------------------------- /74251.v: -------------------------------------------------------------------------------- 1 | // 8-input multiplexer; 3-state 2 | // (c) Warren Toomey, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74251 #(parameter DELAY_RISE = 20, DELAY_FALL = 20) 6 | ( 7 | input Output_bar, 8 | input [7:0] I, 9 | input [2:0] S, 10 | output Y, 11 | output Y_bar 12 | ); 13 | 14 | //------------------------------------------------// 15 | wire internal_Y; 16 | wire internal_Y_bar; 17 | 18 | assign internal_Y = (S== 3'b000) ? I[0] : 19 | (S== 3'b001) ? I[1] : 20 | (S== 3'b010) ? I[2] : 21 | (S== 3'b011) ? I[3] : 22 | (S== 3'b100) ? I[4] : 23 | (S== 3'b101) ? I[5] : 24 | (S== 3'b110) ? I[6] : I[7]; 25 | assign internal_Y_bar= ~internal_Y; 26 | 27 | //------------------------------------------------// 28 | 29 | /* verilator lint_off ASSIGNDLY */ 30 | assign #(DELAY_RISE, DELAY_FALL) Y = (!Output_bar) ? internal_Y : 1'bz; 31 | assign #(DELAY_RISE, DELAY_FALL) Y_bar = (!Output_bar) ? internal_Y_bar : 1'bz; 32 | /* verilator lint_on ASSIGNDLY */ 33 | 34 | endmodule 35 | /* verilator lint_on DECLFILENAME */ 36 | -------------------------------------------------------------------------------- /74574.v: -------------------------------------------------------------------------------- 1 | // Octal Transparent D-type Flip-Flops with 3-state Output 2 | // (c) Warren Toomey, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74574 #(parameter WIDTH = 8, DELAY_RISE = 7, DELAY_FALL = 7) 6 | ( 7 | input Output_bar, 8 | input clk, 9 | input [WIDTH-1:0] D, 10 | output [WIDTH-1:0] Q 11 | ); 12 | 13 | //------------------------------------------------// 14 | reg [WIDTH-1:0] Q_current=0; 15 | 16 | always @(posedge clk) 17 | Q_current <= D; 18 | 19 | //------------------------------------------------// 20 | 21 | /* verilator lint_off ASSIGNDLY */ 22 | assign #(DELAY_RISE, DELAY_FALL) Q = (!Output_bar) ? Q_current : {WIDTH{1'bz}}; 23 | /* verilator lint_on ASSIGNDLY */ 24 | 25 | endmodule 26 | /* verilator lint_on DECLFILENAME */ 27 | -------------------------------------------------------------------------------- /74593.v: -------------------------------------------------------------------------------- 1 | // 8-bit Binary Counter with Input Register (3-State) 2 | // (c) Warren Toomey, GPL3 3 | 4 | /* verilator lint_off DECLFILENAME */ 5 | module ttl_74593 #(parameter WIDTH = 8, DELAY_RISE = 30, DELAY_FALL = 30) 6 | ( 7 | input G, 8 | input G_bar, 9 | input CCK, 10 | input CCKEN, 11 | input CCKEN_bar, 12 | input CLOAD_bar, 13 | input CCLR_bar, 14 | input RCK, 15 | input RCKEN_bar, 16 | output RCO_bar, 17 | output [WIDTH-1:0] Q, 18 | input [WIDTH-1:0] inQ 19 | ); 20 | 21 | //------------------------------------------------// 22 | reg [WIDTH-1:0] R; // Register 23 | reg [WIDTH-1:0] Cntr; // Counter 24 | reg prev_CLOAD_bar=1'b1; // Previous CLOAD_bar value 25 | reg prev_CCK=1'b1; // Previous CCK value 26 | 27 | wire RCO_current; 28 | assign RCO_current= ~(&Q); // Goes high when all of Q is zero 29 | 30 | wire [WIDTH-1:0] Cntr_next; 31 | assign Cntr_next = Cntr + 1; 32 | 33 | // As I'm driving some of the inputs from 34 | // a ROM, there are times when there is no 35 | // input for CLOAD_bar. I remember if there 36 | // was a real drop in CLOAD_bar to later 37 | // confirm a real rise in CLOAD_bar. 38 | always @(negedge CLOAD_bar) 39 | begin 40 | if (CLOAD_bar === 1'b0) 41 | prev_CLOAD_bar <= 1'b0; // Save this value for next time 42 | end 43 | 44 | always @(posedge CLOAD_bar) 45 | begin 46 | if (!CCLR_bar) 47 | Cntr <= {WIDTH{1'b0}}; // Reset the counter when CCLR_bar is low 48 | else if (prev_CLOAD_bar === 1'b0) 49 | Cntr <= R; // Copy R -> counter when CLOAD_bar was low 50 | prev_CLOAD_bar <= 1'b1; // Save this value for next time 51 | end 52 | 53 | always @(negedge CCK) 54 | begin 55 | if (CCK === 1'b0) 56 | prev_CCK <= 1'b0; // Save this value for next time 57 | end 58 | 59 | always @(posedge CCK) 60 | begin 61 | if (!CCLR_bar) 62 | Cntr <= {WIDTH{1'b0}}; // Reset the counter when CCLR_bar is low 63 | else if (~prev_CCK && CCK && (CCKEN || ~CCKEN_bar)) 64 | Cntr <= Cntr_next; // Increment counter on rising CCK with 65 | // either enable lines in their correct state 66 | prev_CCK <= 1'b1; // Save this value for next time 67 | end 68 | 69 | always @(posedge RCK) 70 | begin 71 | // Load R with the input on a rising RCK 72 | // when RCKEN_bar is low 73 | if (RCK && !RCKEN_bar) 74 | R <= inQ; 75 | end 76 | 77 | //------------------------------------------------// 78 | 79 | // Our Q output is valid only when 80 | // G is high, G_bar is low. Otherwise hi-Z 81 | /* verilator lint_off ASSIGNDLY */ 82 | assign #(DELAY_RISE, DELAY_FALL) RCO_bar = RCO_current; 83 | assign #(DELAY_RISE, DELAY_FALL) Q= (G && ~G_bar) ? Cntr : {WIDTH{1'bz}}; 84 | /* verilator lint_on ASSIGNDLY */ 85 | 86 | endmodule 87 | /* verilator lint_on DECLFILENAME */ 88 | -------------------------------------------------------------------------------- /Docs/CSCvon8_design.md: -------------------------------------------------------------------------------- 1 | # Overview of the *CSCvon8* Design and Architecture 2 | 3 | This is a description of the architecture of the *CSCvon8* CPU, which 4 | is my attempt to design an 8-bit CPU with a crazy small number of 7400-style 5 | chips. 6 | 7 | ![High-level Architecture](Figs/CSCvon8_overview.png) 8 | 9 | The *CSCvon8* CPU, as shown above, has a von Neumann architecture with 10 | both instructions and data being fetched across the 8-bit data bus into the 11 | CPU registers. 12 | 13 | There are two data registers, A and B which can be loaded and which 14 | provide inputs to the ALU. The ALU's output can then be delivered 15 | across the data bus into these data registers, stored in the RAM, or output on the UART. 16 | 17 | Main memory is provided by a 32K ROM and a 32K RAM device. Instructions and 18 | static data can be stored in the ROM. The RAM can store data and 19 | instructions. This allows programs to be downloaded over the UART link. 20 | 21 | The 16-bit address bus provides the memory access address to the ROM and ROM. 22 | This can be provided either by the 16-bit program counter (*PC*) or from an 23 | address register (*AR*) which is split into two 8-bit registers. 24 | 25 | The PC normally increments but there is a jump logic device which allows 26 | the PC to jump to a new instruction location as required. 27 | 28 | # Microcoded Instructions 29 | 30 | The *CSCvon8* CPU uses microcoding to perform its instructions. Each instruction 31 | is eight bits long. This value, along with the current phase number from the 32 | microsequencer (*uSeq*) indexes into the instruction decode device to generate 33 | the control lines for this phase of the instruction. 34 | 35 | Instructions are performed as a sequence of microinstructions over a number 36 | of phases. The microsequencer increments its 4-bit phase counter on each clock 37 | cycle until it is reset to zero. Thus, a single instruction can be composed of from one 38 | up to sixteen microinstructions. 39 | 40 | On phase zero, regardless of the current contents of the IR, the PC identifies 41 | a location in memory (RAM or ROM) and the contents of this location is fetched 42 | and stored into the IR; the PC is also incremented. This is the "fetch" microinstruction for each 43 | high-level instruction. 44 | 45 | Phase one and onwards for each high-level instruction runs the relevant 46 | "execute" microinstructions. These may, for example, load a value into 47 | a data register, perform an ALU instruction and store the result into a 48 | memory location. 49 | 50 | On the last microinstruction in a sequence, the microsequencer phase is 51 | reset back to zero, so that the next high-level instruction will be fetched 52 | from memory on the next clock cycle. 53 | 54 | # Data Bus Writers 55 | 56 | Three components can write on the 8-bit data bus: the ALU, the memory devices 57 | and the UART. Each one requires a line to control when it can output a value. 58 | When one device is outputting a value, all other devices generate a floating 59 | "high-Z" value. 60 | 61 | # Data Bus Readers 62 | 63 | There are several components which can read from the data bus: the RAM, the 64 | UART, the two Address registers, the instruction register (*IR*) and the A & B 65 | data registers. Although it is electrically possible to allow any or all 66 | to do this at the same time, the CPU cannot generate enough control lines 67 | to permit this. Instead, only one component can read from the data bus 68 | at any time. 69 | 70 | # Address Bus Writers 71 | 72 | There are two devices that can write on the address bus: the PC and 73 | the Address register. A single control line is used to select one or the other. 74 | 75 | # Absolute and Indexed RAM Addressing 76 | 77 | The Address register's value is loaded over the data bus. It can get its 78 | values from RAM and the ALU. As the ALU can perform addition, this allows 79 | for both absolute and indexed addressing. 80 | 81 | For example, the address $2000 can be stored as two separate bytes in RAM. 82 | Each byte can be loaded, in turn, into *ARhi* and *ARlo* to perform absolute 83 | addressing. 84 | 85 | To do indexed addressing, address values and offsets are loaded through the A and B registers so that addition can be done. For example, consider how to calculate the indexed address $2000,B. Firstly, 86 | the $00 is loaded into the A register. A+B is then be 87 | calculated and stored into *ARlo*. Then the $20 is loaded into the A 88 | register and incremented if there was a carry on the previous addition. 89 | The result is then stored into *ARhi*. The effect is to calculate the indexed 90 | address $2000,B. 91 | 92 | # TTL Style Chips 93 | 94 | The diagram above shows fourteen logical components in the CPU design. In 95 | reality, each logical component is constructed from one or more physical chips. 96 | Seventeen chips and one oscillator are needed to build this CPU. All chips 97 | use the 0V/5V TTL levels for logic zero and one, respectively. 98 | 99 | The following table identifies each component and the physical chips that 100 | construct it. 101 | 102 | | Component | Chip(s) | 103 | |-----------------|-----------| 104 | | RAM | LY62256 32Kx8 SRAM | 105 | | ROM | 28C256 32Kx8 EEPROM | 106 | | UART | UM245R | 107 | | ALU | M27C322 2Mx16 EPROM | 108 | | ARhi | 74HCT574 | 109 | |ARlo | 74HCT574 | 110 | | IR | 74HCT574 | 111 | | A reg | 74HCT574 | 112 | | Breg | 74HCT574 | 113 | | PC | Two 74LS593 | 114 | | Jump Logic | 74HCT151 | 115 | | Decode Logic | M27C1024 64Kx16 EEPROM | 116 | | Microsequencer | 74HCT161 | 117 | | Other chips | 74HCT138, 74HTC139 | 118 | 119 | A 74HCT138 3:8 demux and a 74HCT139 2:4 demux are needed for some decode logic. 120 | 121 | ## The ALU and Its Operations 122 | 123 | The ALU is built using a 2Mx16 M27C322 EPROM. The two 8-bit inputs are input to 124 | the ALU as shown in the following diagram. The 5-bit ALUop control lines select the ALU operation. 125 | 126 | ![](Figs/alu_design.png) 127 | 128 | The contents of the ALU ROM essentially defines what calculations the CPU 129 | can perform. Below is the current list of ALU operations. 130 | 131 | |0-7 ALU Ops|8-15 ALU Ops |16-23 ALU Ops|24-31 ALU Ops| 132 | |----------------|-------------------|--------------------|--------------------| 133 | | 0 | B-1 | A*B (low bits) | A ROR B | 134 | | A | A+B | A*B (high bits) | A AND B | 135 | | B | A+B+1 | A/B | A OR B | 136 | | -A | A-B | A%B | A XOR B | 137 | | -B | A-B (special) | A << B | NOT A | 138 | | A+1 | B-A | A >> B logical | NOT B | 139 | | B+1 | A-B-1 | A >> B arithmetic | A+B (BCD) | 140 | | A-1 | B-A-1 | A ROL B | A-B (BCD) | 141 | 142 | 143 | To do 16-bit and higher addition and subtraction, you can load the low 8 bits of the inputs into A and B and do A+B. If there is a carry, then on the following instructions you load the next highest 8 bits of the inputs into A and B and do A+B+1. 144 | 145 | ### Conditional Operations 146 | 147 | The *CSCvon8* CPU, unlike its [CSCv2 predecessor](https://minnie.tuhs.org/Programs/CrazySmallCPU/), does not have a Flags 148 | register. However, the CPU still needs the ability to change the flow of 149 | instruction execution based on data comparisons. 150 | 151 | This is done by the ALU outputting both an 8-bit result and five flag values: 152 | a (D)ivide by zero, a negative result (N), an overflow (V), a carry (C) 153 | and/or a zero result (Z). 154 | 155 | The D, N, Z, V and C bits are sent to the Jump logic along with two 156 | UART status lines: UART is ready to send a character, UART has a character 157 | ready to be received. The Jump logic is a 74HCT151 8:1 multiplexer. 158 | This is controlled by three *Jumpsel* bits using this table: 159 | 160 | | Jumpsel | PCjump (active low) is set to | 161 | |-------------|-----------------------| 162 | | 0 | No jump | 163 | | 1 | C, i.e. jump if carry | 164 | | 2 | V, i.e. jump if overflow | 165 | | 3 | Z, i.e jump if negative | 166 | | 4 | N, i.e jump if negative | 167 | | 5 | D, i.e jump if divide by zero | 168 | | 6 | Jump if not ready to transmit | 169 | | 7 | Jump if not ready to receive | 170 | 171 | The CPU can thus conditionally jump based on the flags calculated on the ALU's result. The ALU also provides several operations (see above) to assist with the types of 172 | conditional jumps that a CPU is expected to provide: 173 | 174 | | ALU operation | Jumpsel | Action peformed | 175 | |--------------------|-------------|-----------------------| 176 | | 0 | 3 (Z) | Always jump | 177 | | A - B | 3 (Z) | Jump if A == B | 178 | | A - B (special) | 3 (Z) | Jump if A != B | 179 | | B - A | 1 (C) | Jump if A > B | 180 | | A - B | 1 (C) | Jump if B > A | 181 | | B - A - 1 | 1 (C) | Jump if A >= B | 182 | | A - B - 1 | 1 (C) | Jump if B >= A | 183 | 184 | 185 | The special "A - B" ALU operation still produces the result of A - B, but the Zero flag is inverted to allow the not equals comparison. 186 | 187 | ## Microcoded Instructions 188 | 189 | The Decode Logic ROM outputs 16 bits of control lines for each 190 | microinstruction. The lowest 5 bits are the ALU operation (0x00 to 0x1F) 191 | described previously. Above that, the lines are mnemonically known as: 192 | 193 | ``` 194 | # Loads from the data bus 195 | IRload = 0020 196 | Aload = 0040 197 | Bload = 0060 198 | MEMload = 0080 199 | AHload = 00A0 200 | ALload = 00C0 201 | IOload = 00E0 202 | 203 | # Writers on the data bus 204 | MEMresult = 0000 205 | ALUresult = 0100 206 | UARTresult = 0200 207 | 208 | # Jump operations 209 | NoJump = 0000 210 | JumpCarry = 0400 211 | JumpOflow = 0800 212 | JumpZero = 0C00 213 | JumpNeg = 1000 214 | JumpDivZero = 1400 215 | JumpNoTx = 1800 216 | JumpNoRx = 1C00 217 | 218 | # Address bus writers: if no ARena then 219 | # the PC is writing on the address bus 220 | ARena# = 2000 (active low) 221 | 222 | # Other control lines 223 | PCincr = 4000 (active high) 224 | uSreset# = 8000 (active low) 225 | ``` 226 | 227 | A high-level instruction is encoded as one instruction byte followed by zero or more bytes. For example, the instruction to increment B is one byte long. 228 | 229 | An instruction to load an 8-bit constant into a register is two bytes long: the instruction followed by the constant. 230 | 231 | An instruction to reference a memory location is three bytes long: the instruction followed by the 16-bit address stored in two high-endian bytes. 232 | 233 | Each high-level instruction is encoded as one or more microinstructions in a microsequence. 234 | Every microsequence starts with the following microinstruction to load the IR from memory and increment the PC: 235 | 236 | ``` 237 | START := MEMresult IRload PCincr 238 | ``` 239 | 240 | Some microsequences are quite short. For example, here is the sequence to load A with a constant: 241 | 242 | ``` 243 | # Load A with constant $XX 244 | 60 LCA: MEMresult Aload PCincr 245 | uSreset 246 | ``` 247 | 248 | The 60 is instruction byte 0x60 with menmonic *LCA*. 249 | Other microsequences are longer, for example: 250 | 251 | ``` 252 | # Store A at absolute location $HHLL 253 | 41 STO_A: MEMresult AHload PCincr 254 | MEMresult ALload PCincr 255 | ALUresult A ARena MEMload 256 | uSreset 257 | ``` 258 | 259 | ALU operations that store results in the A and B registers are quite short: 260 | 261 | ``` 262 | 01 LDA_0: ALUresult 0 Aload 263 | uSreset 264 | 02 LDA_B: ALUresult B Aload 265 | uSreset 266 | 03 LDA_-A: ALUresult -A Aload 267 | uSreset 268 | 04 LDA_-B: ALUresult -B Aload 269 | uSreset 270 | 05 LDA_A+1: ALUresult A+1 Aload 271 | uSreset 272 | ``` 273 | 274 | 275 | Here is an example of an indexed instruction to load A from the $HH00,B location: 276 | 277 | ``` 278 | 90 LDA_,B: MEMresult AHload PCincr 279 | ALUresult B ALload ARena 280 | ARena MEMresult Aload 281 | uSreset 282 | ``` 283 | 284 | In terms of design, microcoding gives you more flexibility with the design of the instruction set architecture, but this comes at a cost of a large ROM to store the microcode. 285 | -------------------------------------------------------------------------------- /Docs/Figs/151_wire1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/151_wire1.jpg -------------------------------------------------------------------------------- /Docs/Figs/151_wire2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/151_wire2.jpg -------------------------------------------------------------------------------- /Docs/Figs/20190607_board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/20190607_board.jpg -------------------------------------------------------------------------------- /Docs/Figs/555_astable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/555_astable.jpg -------------------------------------------------------------------------------- /Docs/Figs/555_board1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/555_board1.jpg -------------------------------------------------------------------------------- /Docs/Figs/555_board2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/555_board2.jpg -------------------------------------------------------------------------------- /Docs/Figs/555_board3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/555_board3.jpg -------------------------------------------------------------------------------- /Docs/Figs/CSCvon8_overview.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/CSCvon8_overview.dia -------------------------------------------------------------------------------- /Docs/Figs/CSCvon8_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/CSCvon8_overview.png -------------------------------------------------------------------------------- /Docs/Figs/PC_circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/PC_circuit.png -------------------------------------------------------------------------------- /Docs/Figs/UM245R.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/UM245R.jpg -------------------------------------------------------------------------------- /Docs/Figs/UM245R_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/UM245R_vertical.png -------------------------------------------------------------------------------- /Docs/Figs/alu_design.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/alu_design.dia -------------------------------------------------------------------------------- /Docs/Figs/alu_design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/alu_design.png -------------------------------------------------------------------------------- /Docs/Figs/breadboard_20190426.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/breadboard_20190426.jpg -------------------------------------------------------------------------------- /Docs/Figs/breadboard_20190502.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/breadboard_20190502.jpg -------------------------------------------------------------------------------- /Docs/Figs/breadboard_20190504.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/breadboard_20190504.jpg -------------------------------------------------------------------------------- /Docs/Figs/breadboard_20190505.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/breadboard_20190505.jpg -------------------------------------------------------------------------------- /Docs/Figs/breadboard_20190506.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/breadboard_20190506.jpg -------------------------------------------------------------------------------- /Docs/Figs/clk_pulse_reset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/clk_pulse_reset.jpg -------------------------------------------------------------------------------- /Docs/Figs/dbwriter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/dbwriter.png -------------------------------------------------------------------------------- /Docs/Figs/dip28_not_socket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/dip28_not_socket.jpg -------------------------------------------------------------------------------- /Docs/Figs/dip28_socket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/dip28_socket.jpg -------------------------------------------------------------------------------- /Docs/Figs/example_aload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/example_aload.png -------------------------------------------------------------------------------- /Docs/Figs/ir_decode_etc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/ir_decode_etc.png -------------------------------------------------------------------------------- /Docs/Figs/jump_glitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/jump_glitch.png -------------------------------------------------------------------------------- /Docs/Figs/led_array.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/led_array.jpg -------------------------------------------------------------------------------- /Docs/Figs/pcb_20190517a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/pcb_20190517a.jpg -------------------------------------------------------------------------------- /Docs/Figs/pcb_20190518.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/pcb_20190518.jpg -------------------------------------------------------------------------------- /Docs/Figs/pcb_20190601.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/pcb_20190601.jpg -------------------------------------------------------------------------------- /Docs/Figs/reader_demux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/reader_demux.png -------------------------------------------------------------------------------- /Docs/Figs/usequencer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/usequencer.png -------------------------------------------------------------------------------- /Docs/Figs/waveforms-tim58a.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Docs/Figs/waveforms-tim58a.gif -------------------------------------------------------------------------------- /Docs/bom_20190601.csv: -------------------------------------------------------------------------------- 1 | Source:,/home/wkt/ownCloud/CSCvon8/Schematic/Schematic.sch, 2 | Date:,Thu 09 May 2019 13:39:52 AEST, 3 | Tool:,Eeschema 5.1.2-f72e74a~84~ubuntu18.04.1, 4 | Component Count:,55, 5 | ,, 6 | Ref,Value,Footprint 7 | C1,10uF,Capacitors_THT:CP_Radial_D5.0mm_P2.00mm 8 | C3,220uF,Capacitors_THT:CP_Radial_D8.0mm_P5.00mm 9 | C4,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 10 | C5,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 11 | C6,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 12 | C7,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 13 | C8,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 14 | C9,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 15 | C10,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 16 | C11,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 17 | C12,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 18 | C13,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 19 | C14,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 20 | C15,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 21 | C16,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 22 | C17,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 23 | C18,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 24 | C19,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 25 | C20,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 26 | C21,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 27 | C22,0.1uF,Capacitors_THT:C_Disc_D4.7mm_W2.5mm_P5.00mm 28 | D1,1N4148,Diodes_THT:D_DO-35_SOD27_P2.54mm_Vertical_AnodeUp 29 | IC1,AS6C62256,Housings_DIP:DIP-28_W15.24mm_Socket 30 | IC2,28C256,Housings_DIP:DIP-28_W15.24mm_Socket 31 | IC3,UM245R,Housings_DIP:DIP-24_W15.24mm_Socket 32 | IC4,74HCT574,Housings_DIP:DIP-20_W7.62mm_Socket 33 | IC5,74HCT574,Housings_DIP:DIP-20_W7.62mm_Socket 34 | IC6,M27C322-100F1,Housings_DIP:DIP-42_W15.24mm_Socket 35 | IC7,74HCT574,Housings_DIP:DIP-20_W7.62mm_Socket 36 | IC8,74HCT574,Housings_DIP:DIP-20_W7.62mm_Socket 37 | IC9,74LS593,Housings_DIP:DIP-20_W7.62mm_Socket 38 | IC10,74LS593,Housings_DIP:DIP-20_W7.62mm_Socket 39 | IC11,74HCT151,Package_DIP:DIP-16_W7.62mm_Socket 40 | IC12,74HCT574,Housings_DIP:DIP-20_W7.62mm_Socket 41 | IC13,74HCT161,Housings_DIP:DIP-16_W7.62mm_Socket 42 | IC14,AT27C1024-70PU,Housings_DIP:DIP-40_W15.24mm_Socket 43 | IC15,74HCT139,Package_DIP:DIP-16_W7.62mm_Socket 44 | IC16,74HCT138,Housings_DIP:DIP-16_W7.62mm_Socket 45 | IC17,74HCT04,Housings_DIP:DIP-14_W7.62mm_Socket 46 | IC18,NE555,Housings_DIP:DIP-8_W7.62mm_Socket 47 | J1,Jumper_3_Bridged12,Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical 48 | J2,Data Bus Pin Header,Connector_PinSocket_2.54mm:PinSocket_1x10_P2.54mm_Vertical 49 | J3,Address Bus Pin Header,Connector_PinSocket_2.54mm:PinSocket_1x18_P2.54mm_Vertical 50 | J4,uSeq Pin Header,Connector_PinSocket_2.54mm:PinSocket_1x06_P2.54mm_Vertical 51 | J5,IR Pin Header,Connector_PinSocket_2.54mm:PinSocket_1x10_P2.54mm_Vertical 52 | J6,Areg Pin Header,Connector_PinSocket_2.54mm:PinSocket_1x10_P2.54mm_Vertical 53 | J7,Breg Pin Header,Connector_PinSocket_2.54mm:PinSocket_1x10_P2.54mm_Vertical 54 | R1,20K,Resistors_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P1.90mm_Vertical 55 | R2,1K,Resistors_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P1.90mm_Vertical 56 | R4,1M,Resistors_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P1.90mm_Vertical 57 | R5,10K,Resistors_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P1.90mm_Vertical 58 | R6,10K,Resistors_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P1.90mm_Vertical 59 | SW1,SW_Push_Dual,Buttons_Switches_THT:Push_E-Switch_KS01Q01 60 | SW2,SW_Push_Dual,Buttons_Switches_THT:Push_E-Switch_KS01Q01 61 | U1,ECS-100A-035,QX14T50B1.843200B50TT:QX14T50B1.843200B50TT 62 | -------------------------------------------------------------------------------- /Docs/cas_assembler.md: -------------------------------------------------------------------------------- 1 | 2 | # CSCvon8 Assembler Documentation 3 | 4 | Warren Toomey, 8th Jun 2019 5 | 6 | ## Introduction 7 | 8 | >*As the CSCvon8 CPU is still under development, this document may deviate 9 | from the current status of the assembler cas and the simulator csim.* 10 | 11 | The *cas* assembler reads a single text file with CSCvon8 assembly 12 | source, and assembles it into the file to load into the Instruction ROM, 13 | *instr.rom*. This file can then be copied into the *Verilog* folder to be 14 | simulated with the Verilog version of the CSCvon8 CPU. 15 | 16 | The current command-line syntax to run *cas* is: 17 | 18 | cas [-d] [-r] inputfile 19 | 20 | The *-d* flag enables debugging output. The *-r* flag assembles the program 21 | to run from RAM and not from ROM. It also tells the assembler to create 22 | a "hex" version of the output which you can upload to the Monitor ROM. 23 | 24 | ## Assembly Syntax 25 | 26 | The assembler ignores blank lines, and discards text from a hash character 27 | '#' onwards. Otherwise, each line from the input file has one or more 28 | space-separated words on it. The general syntax is an optional label 29 | followed by an instruction and additional arguments. Then, optionally a 30 | semicolon and another instruction and additional arguments. 31 | 32 | >[label:] instruction [additional operands] [; instruction [ [additional operands] ] ; ... 33 | 34 | You can also have a label on a line by itself with no instructions. 35 | 36 | ## Labels 37 | 38 | The optional label is a single alphanumeric word terminated by a colon 39 | ':'. If the instruction is the pseudo-op EQU, then the label is set to 40 | the value of the literal constant in the additional operands (or 0 if 41 | there is no literal constant on the line). 42 | 43 | If the instruction is not the pseudo-op EQU, then the label is set to 44 | the value of the Program Counter (PC) for this line of code. 45 | 46 | The assembler supports relative forward and backward labels, which 47 | do not pollute the global namespace. These are numeric labels like 48 | _1:_, _2:_, _3:_ etc. In an instruction, the label _1f_ jumps forward to 49 | the nearest _1:_ label; the label _2b_ jumps backwards to the nearest _2:_ label. 50 | 51 | ## Instructions 52 | 53 | Because CSCvon8 is a microcoded architecture, the list of high-level 54 | instructions depends upon the contents of the Decode ROM and the 55 | microinstruction sequences therein. You should look at the file *opcodes* 56 | which lists the current high-level instructions defined by the 57 | *microcode* file. Each line in *opcodes* has the opcode number, the number of 58 | bytes in memory that the instruction occupies, and the opcode name for 59 | the instruction. 60 | 61 | ## Additional Operand: Literal Values 62 | 63 | A literal value can be expressed in several ways: 64 | - four hex digits preceded by a dollar sign, e.g. $23AB. This represents 65 | an unsigned 16-bit value. 66 | - two hex digits preceded by a dollar sign, e.g. $4D. This is used to express 67 | an 8-bit unsigned value which can be loaded into a register. 68 | - a single ASCII character surrounded by single quotes, e.g. 'F'. There is 69 | support for '\n', '\t' and '\r'. 70 | - a previously defined label name. The value of the label is substitued for its name. 71 | - an indexed address of the format "$XX00,B" where XX are two hex 72 | digits. The other two hex digits must be zero characters. 73 | 74 | The assembler supports the "." syntax as a label that means "the current address". 75 | A common instruction to wait until there is input available on the UART is: 76 | 77 | ``` 78 | JIU . # Jump to this instruction if input unavailable 79 | ``` 80 | 81 | The assembler supports the "label,A" and "label,B" syntax. This uses 82 | the top byte of the label as a base, and indexes at this base with the 83 | given register. Note: the bottom byte of the label is treated as zero! 84 | Note: not all instructions support indexing; read the file *opcodes* 85 | to determine which instructions support indexing. 86 | 87 | The assembler also supports the "label+num" and "label-num" syntax. 88 | This adds or subtracts a constant decimal value from the label's value. 89 | 90 | ## Pseudo-instructions 91 | 92 | The assembler defines some other pseudo-instructions (one so far): 93 | 94 | | Pseudoinstruction | Meaning | 95 | |--------------------------|-------------| 96 | | EQU | give a value to a label | 97 | | ORG | set the address of the next input line to a specific value | 98 | | STR | Define a NUL-terminated string in memory | 99 | | LHA | Load the high byte of an address or label into A | 100 | | LHB | Load the high byte of an address or label into B | 101 | | PAG | Set the next address so it will on a 256-byte page alignment | 102 | 103 | Here are some examples of their use: 104 | 105 | ``` 106 | fred: EQU $9000 # Fred is a byte stored at $9000 107 | 108 | ORG $4002 # Move down to middle ROM 109 | mystr: STR "abcdefg" # Store a string at $4002 onwards 110 | PAG 111 | STR "xyz" # Store a string at $4100 onwards 112 | 113 | ORG $0000 # Back to the start of ROM 114 | LHA mystr # Load $40 into A 115 | LCB mystr # Load $02 into B 116 | ``` 117 | 118 | ## Use of the C Pre-processor 119 | 120 | The assembler runs the input file through the C pre-processor 121 | before it is assembled. This allows you to #include other files 122 | amd also create macros. Here are some useful macros: 123 | 124 | ``` 125 | #define getc(x) JIU .; INA; STO A x 126 | #define JOUT(x) JOU .; OUT x 127 | #define JINA JIU .; INA 128 | ``` 129 | 130 | _getc(fred)_ reads a character from the UART and stores it in _fred_. 131 | _JOUT('A')_ waits for the UART to be ready, then outputs an 'A'. 132 | _JINA_ reads a character from the UART into the A register. 133 | 134 | ## Example Code 135 | 136 | Here is at least one example program to help you visualise the CSCvon8 137 | assembly syntax. Note that the _csim_ and Verilog CSCvon8 simulators 138 | will stop when a jump instruction jumps to location $FFFF. 139 | 140 | 141 | ``` 142 | # Fifth program. Store ASCII characters 143 | # in an array in memory, read them back, 144 | # and print them. 145 | # 146 | 147 | LCA $7F # We end when we reach 0x7F 148 | LCB $20 # Start with a space 149 | 1: STO B $9000,B # Store B in $9000+B 150 | LDB B+1 # Increment B 151 | JNE 1b # Loop back until we get to 0x7F 152 | 153 | LCB $20 # Start with a space 154 | 2: LDA $9000,B # Load the stored value back in 155 | JNE nl # Stop when we get something we didn't store 156 | OUT A # Print it out 157 | JOU . # Loop waiting for it to print 158 | LDB B+1 # Increment B 159 | JMP 2b 160 | 161 | nl: LCA $0A 162 | OUT A # Print a newline 163 | L2: JOU L2 # Loop waiting for it to print 164 | end: JMP $FFFF # and stop 165 | ``` 166 | -------------------------------------------------------------------------------- /Docs/clc_compiler.md: -------------------------------------------------------------------------------- 1 | # CSCvon8 Compiler Details 2 | 3 | This is the documentation for the *clc* compiler, which takes a sort of 4 | high level language and converts it into the assembly language understood 5 | by the *cas* assembler. An example usage is 6 | 7 | ``` 8 | ./clc Examples/himinsky.cl 9 | ./cas Examples/himinsky.s 10 | ``` 11 | 12 | and ```Examples/himinsky.cl``` is an example program written in the high-level 13 | language. 14 | 15 | This document covers the *clc* compiler as it existed on March 16, 2019. 16 | 17 | ## Input Structure 18 | 19 | First and foremost, you need to realise that *clc* is not a well-written 20 | robust compiler, so the input that it can recognise is very particular. 21 | 22 | *clc* parses one line at a time: there is no tokenisation. Whitespace is 23 | generally ignored, and the compiler supports C-style // comment lines. 24 | 25 | In the following, *italics* represent an abstraction which you need to 26 | replace with something concrete. 27 | 28 | ## Variable Declaration. 29 | 30 | Variables in the language are 8-bit and signed. To declare a variable, 31 | use the syntax: 32 | 33 | > var *name*; 34 | 35 | Technically, *name* can be any non-whitespace characters, but I would 36 | stick with the C-style variable naming conventions. Example: 37 | 38 | ``` 39 | var x; 40 | var y; 41 | var i; 42 | var tmp; 43 | ``` 44 | 45 | ## Expressions and Variable Assignment 46 | 47 | The language only supports one operator on the right-hand side of an 48 | assignment operation. Here is the available syntax: 49 | 50 |
51 | name= name2;
52 | name= constant;
53 | name= constant op constant;
54 | name= name2 op constant;
55 | name= constant op name2;
56 | name= name2 op name3; 57 |
58 | 59 | where the names are variables names and the constants are decimal constants; 60 | The available operators are ```+```, ```-```, ```&```, ```|``` and ```^``` 61 | and are the same as the C operators. There are no multiply or divide operators. Not yet, anyway. The CSCvon8 architecture supports quite a lot of operators, but I haven't added them all to the *clc* compiler yet. 62 | 63 | ## Arithmetic Right Shift Operation 64 | 65 | Because I needed a right shift and this is easy to do on a CSCvon8, 66 | there is this syntax: 67 | 68 | > *name*= *name2* >> num; 69 | 70 | ## Postincrement Operation 71 | 72 | This syntax is supported: 73 | 74 | > *name*++; 75 | 76 | ## Exiting the Program 77 | 78 | If you want your program to stop in the *csim* simulator, or go into an 79 | infinite loop on the real hardware, use this line: 80 | 81 | > exit; 82 | 83 | which inserts an infinite loop into the output. 84 | 85 | ## If Statement 86 | 87 | The language supports if statements that are on one line: 88 | 89 | > if (*name1* *op* *name2*) { 90 | 91 | where the names are variables or numeric constants and the operations 92 | include ```==```, ```!=```, ```<```, ```>```, ```<=``` and ```>=```. 93 | 94 | ## Else Statement 95 | 96 | This has the syntax: 97 | 98 | > } else { 99 | 100 | and obviously must come after an if statement. 101 | 102 | ## While Loop 103 | 104 | There is a while loop with the syntax: 105 | 106 | > while (*name1* *op* *name2*) { 107 | 108 | where the names are variables or numeric constants and the operations 109 | include ```==```, ```!=```, ```<```, ```>```, ```<=``` and ```>=```. 110 | There is a second syntax for an infinite loop: 111 | 112 | > while (1) { 113 | 114 | ## Ending Loops and If Statements 115 | 116 | A closed curly bracket on a line by itself ends the most recent if 117 | statement or while loop: 118 | 119 | > } 120 | 121 | The compiler keeps a stack of if statements and while loops, so that you 122 | can nest them. 123 | 124 | ## Breaking Out of a Loop 125 | 126 | To break out of a loop, use the syntax: 127 | 128 | > break; 129 | 130 | just like the C command. 131 | 132 | ## Printing out Characters 133 | 134 | The *putchar()* syntax allows you to print out an ASCII character: 135 | 136 | 137 |
138 | putchar(69);
139 | putchar(name);
140 | putchar('x');
141 | putchar('\n'); 142 |
143 | 144 | where *name* is a variable and *x* is a single character. Example: 145 | 146 | ``` 147 | var x; 148 | x= 65; 149 | putchar(x); 150 | ``` 151 | 152 | will print out an uppercase 'A'. 153 | 154 | ## Printing out Numbers 155 | 156 | The *prhex()* and *prhexn()* syntax allows you to print out a variable as 157 | two hex digits: 158 | 159 |
160 | prhex(name); // Two hex digits, nothing else
161 | prhexn(name); // Two hex digits and a newline character 162 |
163 | 164 | Note that *prhex()* takes eighteen instructions and *prhexn()* takes twenty 165 | instructions, so use these operations sparingly! 166 | 167 | ## Function Declaration 168 | 169 | A function is declared with the syntax: 170 | 171 | > function *name*(*param*) { 172 | 173 | where the name is compulsory, but the single parameter is optional. 174 | 175 | A function is ended with a closed curly bracket on a line by itself: 176 | 177 | > } 178 | 179 | There is no recursion in the language: you can only call a function once 180 | at a time. There must be a function called *main* in your program, as the 181 | compiler insert a JSR to *main* as the first instruction in the assembly 182 | output. Due to the CPU's architecture, there can no more than 256 183 | different calls to one function. 184 | 185 | The parameter named in the function declaration is visible as a local 186 | variable with that name in the function. 187 | 188 | ## Returning from a Function 189 | 190 | Returning from a function is done with one of these two lines: 191 | 192 |
193 | return;
194 | return(name); 195 |
196 | 197 | where *name* is a variable defined in the function. 198 | 199 | ## An Example Function 200 | 201 | Here is a full example function: 202 | 203 | ``` 204 | function increment(x) { 205 | x= x + 1; 206 | return(x); 207 | } 208 | ``` 209 | 210 | ## Calling a Function 211 | 212 | A function call can be done with an optional argument which is copied into 213 | the function parameter, and optionally with an assignment statement to save 214 | the return value. Thus, there are four possible syntax variants: 215 | 216 |
217 | function();
218 | function(arg);
219 | name= function();
220 | name= function(arg); 221 |
222 | 223 | and *arg* has to be a variable not a constant. 224 | 225 | 226 | ## No Optimisations 227 | 228 | Finally, the compiler is very stupid one-pass compiler. It doesn't do any 229 | optimisations, so there will be some space inefficiency in the code that 230 | it produces. 231 | -------------------------------------------------------------------------------- /Docs/getgoing_instructions.md: -------------------------------------------------------------------------------- 1 | # How to Get Going with the CSCvon8 CPU 2 | 3 | There are two versions of the CSCvon8 CPU: the *csim* simulator written 4 | in Perl, and the Verilog version in the top-level folder. To use the Verilog 5 | version you will need to install [Icarus Verliog](http://iverilog.icarus.com/). 6 | 7 | You will also need a system with Perl install. Yes, I know I should have 8 | upgraded my brain to Python or some other newer language. It hasn't happened 9 | yet. 10 | 11 | ## Build the Microcode ROM 12 | 13 | Before you can run any CSCvon8 CPU program, you first need to generate the 14 | contents of the ALU rom, and also the microcode for the Decode ROM. To do 15 | this, first make sure that these programs are executable: 16 | 17 | ``` 18 | $ chmod +x cas clc disasm gen_alu gen_ucode 19 | ``` 20 | 21 | Now run the *Makefile* to generate both ROM's contents: 22 | 23 | ``` 24 | $ make alu.rom ucode.rom 25 | ``` 26 | 27 | *gen_alu* generates the *alu.rom* file which has the contents of the ALU ROM. 28 | *gen_ucode* reads the description of the microcode from the *microcode* file, 29 | and creates two files: the Decode ROM itself, *ucode.rom* and a summary of the 30 | high-level instructions in the file *opcodes*. 31 | 32 | Now you can assemble one of the example programs: 33 | 34 | ``` 35 | $ ./cas Examples/example05.s 36 | ``` 37 | 38 | This will assemble the source code and create the contents of the instruction 39 | ROM, *instr.rom*. 40 | 41 | To run this assembled program with the Verilator version of the CPU, just 42 | run *make*: 43 | 44 | ``` 45 | $ make 46 | ``` 47 | 48 | Assuming that you have Icarus Verilog installed, you should see this output: 49 | 50 | ``` 51 | vvp icarus_tb.out 52 | VCD info: dumpfile test.vcd opened for output. 53 | !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 54 | ``` 55 | 56 | The line with all the printable ASCII characters is the output from the 57 | *example05.s* assembly program. 58 | 59 | ## Using the Perl Simulator 60 | 61 | Once you have assembled a program to create the *instr.rom*, you can run 62 | this program with the Perl simulator of the CPU: 63 | 64 | ``` 65 | $ ./csim 66 | !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 67 | ``` 68 | 69 | ## What to Read Next? 70 | 71 | I would recommend: 72 | 73 | * [the *cas* assembler manual](cas_assembler.md) 74 | * [the *clc* compiler manual](clc_compiler.md) 75 | * [the overview of the CSCvon8 architecture](CSCvon8_design.md) 76 | -------------------------------------------------------------------------------- /Docs/implementation_notes.md: -------------------------------------------------------------------------------- 1 | # Implementation Notes for the CSCvon8 CPU 2 | 3 | The CVCvon8 design has been implemented in three ways. One is the Perl 4 | simulator, *csim*. The second is the Verilog implementation. The third 5 | is the PCB layout using physical chips. This document covers the last two. 6 | 7 | ## Verilog Implementation of the CSCvon8 CPU 8 | 9 | I built the TTL-modelled version of the CSCvon8 CPU because I was seeing 10 | events with the real chips when I was building my breadboard version of 11 | the CPU, and I realised that they were being caused by the different 12 | propagation delays through the various components. 13 | 14 | I decided to try and model these delays in Verilog, and luckily I came across 15 | [this set of 7400 chips modelled in Verilog](https://github.com/TimRudy/ice-chips-verilog) 16 | by Tim Rudy. They had rise and fall delay parameters set by default to zero. 17 | I had to build a few 7400 chip models along the way. 18 | 19 | I've browsed the datasheets for the chips that I'm using, and here are the 20 | propagation delays that I've set in this design. 21 | 22 | | Component(s) | Chip| Propagation Delay | 23 | |--------------|:---:|:-----------------:| 24 | | Databus reader demux | 74HCT138 | 21nS | 25 | | Databus writer demux | 74HCT139 | 25nS | 26 | | Microsequencer | 74HCT161 | 22nS | 27 | | Jump logic | 74HCT151 | 20nS | 28 | | Several registers | 74HCT574 | 30nS | 29 | | Program counter | 74LS593 | 30nS | 30 | | RAM memory | AS6C62256 | 55nS | 31 | | ALU ROM | M27C322 | 45nS | 32 | | Decode ROM | AT27C1024 | 45nS | 33 | | Instruction ROM | 28C256 | 150nS | 34 | 35 | These delays cause a whole bunch of complications to the design of the CPU. 36 | Here are just a few examples of the complications caused by the delays and 37 | by the design choices that I've made. 38 | 39 | Firstly, all of the control lines get generated 40 | by the Decode ROM with a delay of 45nS after the microsequencer and/or IR 41 | changes its value. Therefore, it's guaranteed that all of the control lines 42 | will change *after* a rising edge of the system clock. Thus, it would be 43 | impossible for the system clock to provide the rising edge signal for 44 | those chips like the 74HCT574 and 74LS593 which load values on a rising edge: 45 | the system clock's edge occurs well before the control lines arrive to say 46 | what has to be done on that rising edge. 47 | 48 | Secondly, the 28C256 instruction ROM has a significant delay between an 49 | address change and the new data value being output by the ROM. Consider 50 | the *LCA* instruction to load the A register from a byte in ROM immediately 51 | following the LCA instruction byte. The microcode sequence looks a bit like: 52 | 53 | + load the IR from the ROM at the address supplied by the PC. Then increment the PC. 54 | + load the A register from the ROM at the new address supplied by the PC. Then increment the PC. 55 | 56 | Assume that the *Aload* rising edge control line to tell A to load a value 57 | comes out from the decode ROM delayed by 45nS compared to the system clock. 58 | That still is too early if the address bus value has changed but it takes the 59 | ROM 150nS to output the new value onto the data bus. By this time, the A 60 | register will have loaded the old value on the data bus. 61 | 62 | Finally, as mentioned, several chips require a rising edge to perform an 63 | action. The program counter (PC), as an example, needs a rising edge *CCK* 64 | signal to increment its value. Given that we can't use the system clock to 65 | do this, this rising edge must be generated by the Decode ROM. But for the 66 | ROM to do this, it has to cycle a line low, high, low etc. 67 | 68 | Consider the microinstructions in the *LCA* instruction shown previously. 69 | In both microinstructions, the PC has to be incremented. If the Decode ROM 70 | generated a line called *PCincr* to do this, then it cannot be asserted in 71 | both of these microinstructions because there would never be a low value 72 | and at least one of the PC increments would never occur. 73 | 74 | ## Building the Physical CSCvon8 CPU 75 | 76 | I built both the Verilog and the breadboard version of the CSCvon8 CPU 77 | in parallel. This allowed me to work out the effects of the propagation 78 | delays and the rising edge issue noted above. 79 | Due to thes issues, I've had to resort to some subtle wiring in the CSCvon8. 80 | 81 | Several components need to load the current value on the data bus: the A and 82 | B registers, the instruction register, the address registers, RAM and the UART. 83 | The load control lines are generated from the 3-bit LoadOp value from the 84 | Decode ROM being demultiplexed by a 74HCT138 3:8 demux. 85 | 86 | ![](Figs/reader_demux.png) 87 | 88 | It would be useful to allow a component to load its value on successive 89 | microinstructions, but if the same LoadOp value occurs on both 90 | microinstructions then there will not be a rising edge on the load signal. 91 | 92 | To enforce a rising edge on the load signal, the system clock is wired to the 93 | one of the 74HCT138 active low enable lines. This causes two things to happen. 94 | 95 | Firstly, when the system clock goes low, one load output line is asserted. 96 | Therefore the loading is done halfway through the clock cycle when the 97 | value on the data bus has settled, as shown below. 98 | 99 | ![](Figs/example_aload.png) 100 | 101 | Secondly, when the system clock rises, the 74HCT138 is disabled. All 102 | outputs from the 74HCT138 go high and (via the inverters) de-assert all the 103 | load lines, also shown above. 104 | 105 | ## Rising Edges and PC Increment Delays 106 | 107 | The program counter (PC) must be able to load its value from the address 108 | registers on a jump, increment on consecutive microinstructions and 109 | sometimes keep its value unchanged. 110 | 111 | The PC load line (active low) is generated by a 74HCT151 multiplexer 112 | and is determined by the Jump control lines and the status lines from the 113 | ALU and UART. The PC increment line (active high) is generated from the 114 | Decode ROM. 115 | 116 | We need a rising edge for PC increments, and this has to be delayed until the 117 | middle of the clock cycle due to the ROM propagation delays. 118 | 119 | To create this rising edge in the middle of the clock cycle, an inverted 120 | clock signal *clkbar* is generated using an inverter. This is connected 121 | to both the *CCK* and *RCK* inputs of the 74LS593 used as the low half 122 | of the PC. *CCK*, when enabled, increments the PC; *RCK*, when enabled, 123 | causes the counter to load a new value. 124 | 125 | ![](Figs/PC_circuit.png) 126 | 127 | The 74LS593 is wired so that the PC load line enables *RCK* causes the 128 | PC load to load the value on the address bus halfway through the clock cycle. 129 | Similarly, the PC increment line enables *CCK* so that the PC increments its 130 | value halfway through the clock cycle. 131 | -------------------------------------------------------------------------------- /Examples/example01.s: -------------------------------------------------------------------------------- 1 | # First working program! 2 | # 3 | hello: NOP 4 | LCA $34 5 | LCB $23 6 | fred: LDA A+B 7 | OUT A 8 | L1: JOU L1 9 | LCA $0A 10 | OUT A 11 | L2: JOU L2 12 | end: JMP $FFFF 13 | -------------------------------------------------------------------------------- /Examples/example02.s: -------------------------------------------------------------------------------- 1 | # Second working program. 2 | # 3 | hello: NOP 4 | LCA 'H' 5 | OUT A 6 | L1: JOU L1 7 | LCA 'e' 8 | OUT A 9 | L2: JOU L2 10 | LCA 'l' 11 | OUT A 12 | L3: JOU L3 13 | OUT A 14 | L4: JOU L4 15 | LCA 'o' 16 | OUT A 17 | L5: JOU L5 18 | LCA $0A 19 | OUT A 20 | L6: JOU L6 21 | end: JMP $FFFF 22 | -------------------------------------------------------------------------------- /Examples/example03.s: -------------------------------------------------------------------------------- 1 | # Third program. Store a two-digit BCD value 2 | # into a RAM location. Then print it out as 3 | # two ASCII digits followed by a newline. 4 | 5 | NOP 6 | LCA $35 # Treat this as 35 BCD 7 | STO A $8002 8 | 9 | LDA $8002 # Reload the value 10 | LCB $04 # Shift it right 4 bits 11 | LDA A>>B 12 | LCB $30 # Add on $30: convert to ASCII 13 | LDA A+B 14 | OUT A 15 | L1: JOU L1 16 | 17 | LDA $8002 # Reload the value 18 | LCB $0F # Keep the low nibble 19 | LDA A&B 20 | LCB $30 # Add on $30: convert to ASCII 21 | LDA A+B 22 | OUT A 23 | L2: JOU L2 24 | LCA $0A # Now a newline 25 | OUT A 26 | L3: JOU L3 27 | 28 | end: JMP $FFFF 29 | -------------------------------------------------------------------------------- /Examples/example04.s: -------------------------------------------------------------------------------- 1 | # Fourth program. Print the printable 2 | # ASCII characters and then stop. 3 | 4 | NOP 5 | LCB $7F # We end when we reach 0x7F 6 | LCA $20 # Start with a space 7 | loop: OUT A # Print A out 8 | L1: JOU L1 9 | LDA A+1 # Increment A 10 | JNE loop # Loop back until we get to 0x7F 11 | LCA $0A 12 | OUT A # Print a newline 13 | L2: JOU L2 14 | end: JMP $FFFF # and stop 15 | -------------------------------------------------------------------------------- /Examples/example05.s: -------------------------------------------------------------------------------- 1 | # Fifth program. Store ASCII characters 2 | # in an array in memory, read them back, 3 | # and print them. 4 | # 5 | NOP 6 | LCA $7F # We end when we reach 0x7F 7 | LCB $20 # Start with a space 8 | loop1: STO B $8000,B # Store B in $8000+B 9 | LDB B+1 # Increment B 10 | JNE loop1 # Loop back until we get to 0x7F 11 | 12 | LCB $20 # Start with a space 13 | loop2: LDA $8000,B # Load the stored value back in 14 | JNE nl # Stop when we get something we didn't store 15 | OUT A # Print it out 16 | L1: JOU L1 17 | LDB B+1 # Increment B 18 | JMP loop2 19 | 20 | nl: LCA $0A 21 | OUT A # Print a newline 22 | L2: JOU L2 23 | end: JMP $FFFF # and stop 24 | -------------------------------------------------------------------------------- /Examples/example06.s: -------------------------------------------------------------------------------- 1 | # Sixth example program. This tests that the JSR/RTS 2 | # instructions work. JSR to the printA subroutine to 3 | # print out an 'A' and return. Then print out an 'F' 4 | # and stop. 5 | 6 | NOP 7 | JSR printA 8 | LCA 'F' 9 | OUT A 10 | L1: JOU L1 11 | x: JMP $FFFF 12 | NOP 13 | NOP 14 | NOP 15 | printA: LCA 'A' 16 | OUT A 17 | L2: JOU L2 18 | RTS printA 19 | -------------------------------------------------------------------------------- /Examples/example07.s: -------------------------------------------------------------------------------- 1 | # Seventh program. Add two BCD values and store 2 | # it into a RAM location. Then print it out as 3 | # two ASCII digits followed by a newline. 4 | 5 | NOP 6 | LCA $35 # Treat this as 35 BCD 7 | LCB $47 # Treat this as 47 BCD 8 | LDA A+BCD # Add them to get 82 BCD 9 | STO A $8002 10 | 11 | LDA $8002 # Reload the value 12 | LCB $04 # Shift it right 4 bits 13 | LDA A>>B 14 | LCB $30 # Add on $30: convert to ASCII 15 | LDA A+B 16 | OUT A 17 | L1: JOU L1 18 | 19 | LDA $8002 # Reload the value 20 | LCB $0F # Keep the low nibble 21 | LDA A&B 22 | LCB $30 # Add on $30: convert to ASCII 23 | LDA A+B 24 | OUT A 25 | L2: JOU L2 26 | LCA $0A # Now a newline 27 | OUT A 28 | L3: JOU L3 29 | 30 | end: JMP $FFFF 31 | -------------------------------------------------------------------------------- /Examples/example08.s: -------------------------------------------------------------------------------- 1 | # Eighth program. Doesn't work on Icarus, only Verilator and csim. 2 | # Read from the UART and echo the characters. Also print 3 | # an initial 'A' so you know it's doing something. 4 | 5 | NOP 6 | LCA $41 # Print an A 7 | OUT A 8 | JOU . # Wait until it is printed 9 | L1: JIU . # Loop while no input characters 10 | INA # Read a character in from the UART 11 | OUT A # and echo it back out 12 | JOU . # Wait until it is printed 13 | JMP L1 # and do it all again 14 | -------------------------------------------------------------------------------- /Examples/example09.s: -------------------------------------------------------------------------------- 1 | # Program to do a 16-bit add on two 2 | # values and print out the inputs 3 | # and outputs in hex. 4 | 5 | xlo: EQU $8000 6 | xhi: EQU $8001 7 | ylo: EQU $8002 8 | yhi: EQU $8003 9 | reslo: EQU $8004 10 | reshi: EQU $8005 11 | hexarg: EQU $8006 12 | 13 | main: NOP 14 | LCA $23 # Set X to $2345 15 | STO A xhi 16 | LCA $45 17 | STO A xlo 18 | 19 | LCA $11 # Set Y to $1111 20 | STO A yhi 21 | LCA $FF 22 | STO A ylo 23 | 24 | LDA xhi # Print X out 25 | STO A hexarg 26 | JSR prhex 27 | LDA xlo 28 | STO A hexarg 29 | JSR prhex 30 | 31 | LCA '+' # Print out a '+' 32 | OUT A 33 | L1: JOU L1 34 | 35 | LDA yhi # Print Y out 36 | STO A hexarg 37 | JSR prhex 38 | LDA ylo 39 | STO A hexarg 40 | JSR prhex 41 | 42 | LCA '=' # Print out a '=' 43 | OUT A 44 | L2: JOU L2 45 | 46 | LDA xlo # Calculate low result 47 | LDB ylo # and jump if carry 48 | TST A+B JC acarry 49 | STO A+B reslo 50 | LDA xhi # Calculate high result 51 | LDB yhi 52 | STO A+B reshi 53 | JMP preslt 54 | acarry: STO A+B reslo 55 | LDA xhi # Calc hi result with carry 56 | LDB yhi 57 | STO A+B+1 reshi 58 | preslt: LDA reshi # Print result out 59 | STO A hexarg 60 | JSR prhex 61 | LDA reslo 62 | STO A hexarg 63 | JSR prhex 64 | LCA $0A # and newline 65 | OUT A 66 | L3: JOU L3 67 | 68 | end: JMP $FFFF 69 | 70 | # prhex function: Print the value in A 71 | # out as two hex digits 72 | prhex: LDA hexarg # Load a copy of A 73 | LCB $04 # Get high nibble of A 74 | LDA A>>B 75 | LCB $09 76 | JGT AtoFhi # Skip if in range A to F 77 | LCB $30 # Otherwise add '0' 78 | JMP putchi # and print it 79 | AtoFhi: LCB $37 # Add 55 to get it in 'A' to 'F' 80 | putchi: LDA A+B 81 | OUT A 82 | L4: JOU L4 83 | 84 | LDA hexarg # Get A back again 85 | LCB $0F # Get the low nibble of A 86 | LDA A&B 87 | LCB $09 88 | JGT AtoFlo # Skip if in range A to F 89 | LCB $30 # Otherwise add '0' 90 | JMP putclo # and print it 91 | AtoFlo: LCB $37 # Add 55 to get it in 'A' to 'F' 92 | putclo: LDA A+B 93 | OUT A 94 | L5: JOU L5 95 | # xyz: JMP xyz 96 | RTS prhex 97 | -------------------------------------------------------------------------------- /Examples/example10.s: -------------------------------------------------------------------------------- 1 | # Example program #10. Test that the SIA and SIB 2 | # instructions work. fred and jim are byte pointers. 3 | # Store 'W' through the fred pointer to memory, then 4 | # load directly from memory and print out the letter. 5 | # Ditto with the jim pointer. 6 | 7 | NOP 8 | LCA 'W' # Store a 'W' through the fred 9 | SIA fred # pointer. 10 | LDA $9000 # Load back from $9000 and 11 | OUT A # print out the character 12 | LCB 'T' # Ditto with the jim pointer 13 | SIB jim 14 | LDB $ABCD 15 | OUT B 16 | OUT '\n' 17 | JMP $FFFF 18 | 19 | fred: HEX "90 00" # Pointer to $9000 20 | jim: HEX "AB CD" # Pointer to $ABCD 21 | -------------------------------------------------------------------------------- /Examples/example11.s: -------------------------------------------------------------------------------- 1 | # Example 11 to demonstrate the PPR put pointer instruction 2 | # 3 | # We take one jump, print out a '1'. Then we modify the original jump 4 | # and take it a second time. This time it points to new code which will 5 | # print '2'. 6 | 7 | #define JOUT(x) JOU .; OUT x 8 | 9 | NOP 10 | sm: JMP here # Firstly, jump past the JMP $FFFF 11 | JMP $FFFF 12 | 13 | here: JOUT('1'); JOUT('\n') # Print out a 1 14 | PPR sm+1 there # Change the JMP at label sm 15 | JMP sm # and jump back to it 16 | JMP $FFFF 17 | 18 | there: JOUT('2'); JOUT('\n') # Print out a 2 19 | JMP $FFFF 20 | -------------------------------------------------------------------------------- /Examples/himinsky.cl: -------------------------------------------------------------------------------- 1 | // A working Minsky sine generator 2 | // in a semi-high level language 3 | // (c) 2017 Warren Toomey, GPL3 4 | 5 | function main() { 6 | var x; 7 | var y; 8 | var i; 9 | var tmp; 10 | 11 | x=58; 12 | y=0; 13 | 14 | while (1) { 15 | tmp= x >> 4; 16 | y= y - tmp; // y= y - (x>>4) 17 | tmp= y >> 4; 18 | x= x + tmp; // x= x + (y>>4) 19 | 20 | i=0; 21 | tmp= x + 59; 22 | while( i < tmp) { // print x+59 spaces 23 | putchar(' '); 24 | i++; 25 | } 26 | putchar('*'); // then a "*\n" 27 | putchar('\n'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Examples/hiprhex.cl: -------------------------------------------------------------------------------- 1 | // Example of printing hex output in 2 | // the high-level language. 3 | // (c) 2017 Warren Toomey, GPL3 4 | 5 | function main() { 6 | var i; 7 | i= 0; 8 | 9 | while (i < 100) { 10 | prhexn(i); 11 | i++; 12 | } 13 | exit; 14 | } 15 | -------------------------------------------------------------------------------- /Examples/legetests.cl: -------------------------------------------------------------------------------- 1 | // Program to test that <= and >= operators work 2 | // (c) 2017 Warren Toomey, GPL3 3 | 4 | function main() { 5 | var x; 6 | var y; 7 | 8 | // Print 10 stars 9 | x= 1; 10 | y= 10; 11 | 12 | while (x <= y) { 13 | putchar('*'); 14 | x++; 15 | } 16 | putchar('\n'); 17 | 18 | // Print another 10 stars 19 | x= 40; 20 | y= 31; 21 | 22 | while (x >= y) { 23 | putchar('*'); 24 | x= x - 1; 25 | } 26 | putchar('\n'); 27 | exit; 28 | } 29 | -------------------------------------------------------------------------------- /Examples/minsky.s: -------------------------------------------------------------------------------- 1 | # Drawing a sine wave approximation 2 | # using Minsky's circle algorithm 3 | # Thanks to Chris Baird @Chris_J_Baird 4 | # for the suggestion. 5 | # Set your terminal to 132 columns! 6 | 7 | X: EQU $8000 8 | Y: EQU $8001 9 | 10 | NOP 11 | LCA $3A # Start at X=58 decimal, Y=0 12 | STO A X 13 | LCA $00 14 | STO A Y 15 | 16 | loop: LCB $04 # Do y= y - (x/4) 17 | LDA X 18 | LDA A>>BA # Store X/4 into A 19 | LDB Y 20 | LDA B-A 21 | STO A Y # Store Y-(X/4) into Y 22 | 23 | # Now do x= x + (y/4) 24 | LCB $04 25 | LDA Y 26 | LDA A>>BA 27 | LDB X 28 | LDA A+B 29 | STO A X 30 | # Print X + 59 spaces 31 | LDB X 32 | LCA $3B 33 | LDB A+B # B= X + 59 34 | LCA $20 # Load a ' ' into A 35 | sploop: OUT A 36 | L1: JOU L1 37 | LDB B-1 38 | JBN spend # B--, exit when it's negative 39 | JMP sploop 40 | 41 | spend: LCA '*' # Print out "*\n" 42 | OUT A 43 | L2: JOU L2 44 | LCA $0A 45 | OUT A 46 | L3: JOU L3 47 | JMP loop # and go back & do it all again 48 | -------------------------------------------------------------------------------- /Examples/monitor.s: -------------------------------------------------------------------------------- 1 | # Warren's monitor ROM for the CSCvon8 CPU 2 | # (c) 2019, GPL3 3 | 4 | #define printstr(x) LHA x; STO A strptr; LCA x; STO A strptr+1; JSR puts 5 | #define putc(x) LCA x; JOU .; OUT A 6 | #define getc(x) JIU .; INA; STO A x 7 | #define JOUT(x) JOU .; OUT x 8 | #define JINA JIU .; INA 9 | 10 | main: NOP # Six NOPs are needed for the CPU to 11 | NOP # "settle down" after Reset# goes high 12 | NOP 13 | NOP 14 | NOP 15 | NOP 16 | LCB $00 # Print out the welcome message 17 | 1: LDA welcome,B 18 | JAZ prompt 19 | JOUT(A) 20 | LDB B+1 21 | JMP 1b 22 | 23 | prompt: putc('>') # Print out the prompt 24 | putc(' ') 25 | getc(cmdchar) # Get the command letter and 26 | JOUT(A) # echo it out to the user 27 | LCB '\n' # Loop when we get a newline 28 | JEQ prompt 29 | LCB '\r' # Loop when we get a carriage return 30 | JEQ prompt 31 | 32 | STO 0 hexcnt # Set count of hex chars to zero 33 | sploop: JINA # Get further characters and echo them 34 | JOUT(A) 35 | LCB ' ' # Skip spaces 36 | JEQ sploop 37 | LCB '\n' # Exit when we get a newline 38 | JEQ docmd 39 | LCB '\r' # Exit when we get a carriage return 40 | JEQ docmd 41 | 42 | LDB hexcnt # Assume it's a hex digit, store it 43 | STO A hexchar,B 44 | STO B+1 hexcnt # Increment the counter 45 | LCA $03 46 | JEQ waitnl # Exit loop when B==3 (highest offset) 47 | JMP sploop # Otherwise loop back 48 | 49 | waitnl: JINA # Echo chars until a '\n' or '\r' 50 | JOUT(A) 51 | LCB '\n' 52 | JEQ cvtaddr 53 | LCB '\r' 54 | JEQ cvtaddr 55 | JMP waitnl 56 | 57 | cvtaddr: JSR hexcvt # Convert the four characters into an address 58 | 59 | docmd: JOUT('\n') 60 | 61 | LDA cmdchar # Get the command character 62 | LCB '?' # ?, print the usage 63 | JEQ printusage 64 | LCB 'D' # D and d, dump memory 65 | JEQ dump 66 | LCB 'd' 67 | JEQ dump 68 | LCB 'R' # R and r, run code at addr 69 | JEQ run 70 | LCB 'r' 71 | JEQ run 72 | LCB 'C' # C and c, change memory 73 | JEQ change 74 | LCB 'c' 75 | JEQ change 76 | LCB 'X' # X and x, exit csim 77 | JEQ terminate 78 | LCB 'x' 79 | JEQ terminate 80 | newprompt: 81 | JOUT('\r') 82 | JOUT('\n') 83 | JMP prompt 84 | 85 | terminate: 86 | JMP $FFFF 87 | 88 | printusage: 89 | printstr(usage) 90 | JMP prompt 91 | 92 | run: LCB $70 # Set a JMP instruction 93 | STO B jmpaddr # at the jmpaddr and go there 94 | JMP jmpaddr 95 | JMP prompt 96 | 97 | dump: LCB $0F # Set a count of 15, which will be 16 98 | STO B count 99 | LDB addr # Print out the address in hex 100 | STO B hexchar 101 | JSR prhex 102 | LDB addr+1 103 | STO B hexchar 104 | JSR prhex 105 | JOUT(':') 106 | JOUT(' ') 107 | 1: LIA addr # Get a byte through the pointer 108 | STO A hexchar 109 | JSR prhex # Print it in hex 110 | JOUT(' ') # followed by a space 111 | LDB count # Decrement the count 112 | LDB B-1 113 | JBN 2f # Exit when we get to $FF 114 | STO B count 115 | LDB addr+1 # Keep going, so move the pointer up 116 | STO B+1 addr+1 117 | JMP 1b # and loop back 118 | 119 | 2: JOUT('\r') 120 | JOUT('\n') # End of loop, print a newline 121 | LDB addr+1 # Also bump up the address for the next dump 122 | STO B+1 addr+1 123 | TST B+1 JC 3f 124 | JMP prompt 125 | 3: LDB addr 126 | STO B+1 addr 127 | JMP prompt 128 | 129 | change: 130 | printstr(setstr) 131 | changeloop: 132 | JINA # Get a character and echo it 133 | JOUT(A) 134 | LCB ' ' 135 | JEQ changeloop # Start afresh for spaces and newlines 136 | LCB '\n' 137 | JEQ changeloop 138 | LCB '\r' 139 | JEQ changeloop 140 | LCB 'Z' # If we get a 'Z' or 'z', end of changes 141 | JEQ newprompt 142 | LCB 'z' 143 | JEQ newprompt 144 | STO A hexchar # Store first hex nibble, do it again 145 | JINA # Get a character and echo it 146 | JOUT(A) 147 | LCB ' ' 148 | JEQ changeloop # Start afresh for spaces and newlines 149 | LCB '\n' 150 | JEQ changeloop 151 | LCB '\r' 152 | JEQ changeloop 153 | LCB 'Z' # If we get a 'Z' or 'z', end of changes 154 | JEQ newprompt 155 | LCB 'z' 156 | JEQ newprompt 157 | STO A hexchar2 # Store second hex nibble 158 | 159 | JSR bytecvt # Convert to a single byte in cmdchar 160 | LDA cmdchar 161 | SIA addr # Store the byte through the addr pointer 162 | 163 | LDB addr+1 # Increment the addr pointer 164 | STO B+1 addr+1 165 | TST B+1 JC 1f 166 | JMP changeloop 167 | 1: LDB addr 168 | STO B+1 addr 169 | JMP changeloop 170 | 171 | 172 | ## puts subroutine 173 | ## 174 | puts: LIA strptr # Get character through the ptr 175 | JAZ 1f # Exit when we get the NUL character 176 | JOU . # Print out the character 177 | OUT A 178 | LDB strptr+1 # Increment the low byte of the pointer 179 | STO B+1 strptr+1 180 | JMP puts # and loop back 181 | 1: RTS puts 182 | 183 | ## hexcvt subroutine. Given four hex digits stored in the hexchar 184 | # buffer, convert them into a 16-bit big endian address 185 | # stored in addr. 186 | hexcvt: LDB hexchar # Get the first character 187 | LCA $3F # Add on $3F 188 | LDA A+B 189 | JAN 1f # If -ve, was A-F 190 | LDA B 191 | JMP 2f # Otherwise, was a 0-9 char 192 | 1: LCB $0A # Add on $0A to convert char to nibble 193 | LDA A+B 194 | 2: LCB $04 195 | STO addr A<>B 268 | LCB $09 269 | JGT 1f # Skip if in range A to F 270 | LCB $30 # Otherwise add '0' 271 | JMP 2f # and print it 272 | 1: LCB $37 # Add 55 to get it in 'A' to 'F' 273 | 2: LDA A+B 274 | JOUT(A) 275 | 276 | LDA hexchar # Get A back again 277 | LCB $0F # Get the low nibble of A 278 | LDA A&B 279 | LCB $09 280 | JGT 1f # Skip if in range A to F 281 | LCB $30 # Otherwise add '0' 282 | JMP 2f # and print it 283 | 1: LCB $37 # Add 55 to get it in 'A' to 'F' 284 | 2: LDA A+B 285 | JOUT(A) 286 | RTS prhex 287 | 288 | # String constants 289 | PAG 290 | welcome: STR "CSCvon8 Monitor, $Revision: 1.15 $, type ? for help\n\n" 291 | usage: STR "Usage: D dump, C change, R run, ? help, X exit\n" 292 | setstr: STR "Enter space separated hex digits, end with Z\n\n" 293 | 294 | ORG $FF00 295 | hexchar: HEX "00" # Place to store four hex chars, page aligned 296 | hexchar2: HEX "00" 297 | hexchar3: HEX "00" 298 | hexchar4: HEX "00" 299 | strptr: HEX "00" # String pointer for puts 300 | HEX "00" 301 | cmdchar: HEX "00" # Command character 302 | hexcnt: HEX "00" # Count of hex chars left to store 303 | jmpaddr: HEX "00" 304 | addr: HEX "80" # Address used by all commands 305 | HEX "00" 306 | count: HEX "00" # 16-bit counter, used when loading a program 307 | HEX "00" 308 | -------------------------------------------------------------------------------- /Examples/print_indir_str.s: -------------------------------------------------------------------------------- 1 | # Example program to store the address of a string in a pointer, 2 | # then access all the characters of the string through the pointer, 3 | # i.e. address indirection. 4 | 5 | NOP 6 | LHA string # Fill in the pointer 7 | STO A hiptr 8 | LCA string 9 | STO A loptr 10 | JSR puts # Print out the string and stop 11 | JMP $FFFF 12 | 13 | # Given a string pointer in hiptr/loptr, print out the string. 14 | # This will destroy loptr in the process. 15 | 16 | puts: LIA hiptr # Get character through the ptr 17 | JAZ endputs # Exit when we get the NUL character 18 | JOU . # Print out the character 19 | OUT A 20 | LDB loptr # Increment the low byte of the pointer 21 | STO B+1 loptr 22 | JMP puts # and loop back 23 | endputs: RTS puts 24 | 25 | string: STR "ABC\tDEF\"G\nHIJK\n" # Test the escaped characters, too 26 | 27 | ORG $8000 28 | hiptr: HEX "00" # These to be filled in later 29 | loptr: HEX "00" 30 | -------------------------------------------------------------------------------- /Examples/print_str.s: -------------------------------------------------------------------------------- 1 | # An example of how to store a string in ROM memory, 2 | # get the index to its base and then print it out. 3 | 4 | NOP 5 | LCB hello # Start at the base of hello 6 | loop: LDA hello,B # Get a character 7 | JAZ end # Exit if NUL 8 | OUT A # Print it out 9 | JOU . # Wait for UART 10 | LDB B+1 11 | JMP loop 12 | end: LCA $0A # Finally print a newline 13 | OUT A 14 | JOU . 15 | JMP $FFFF 16 | hello: STR "ABCDEFGH" 17 | # 18 | # This is just a test of the HEX pseudo-op 19 | fred: HEX "01 02 03 04 AB AC AD AE AF" 20 | -------------------------------------------------------------------------------- /Examples/signedprint.cl: -------------------------------------------------------------------------------- 1 | // Program to print out all signed 8-bit numbers 2 | // in decimal. (c) 2017 Warren Toomey, GPL3. 3 | 4 | // Print out the parameter in decimal 5 | function printdec(x) { 6 | var tencount; 7 | var asciizero; 8 | var hundredormore; 9 | 10 | tencount= 48; // ASCII '0' 11 | asciizero= 48; // ASCII '0' 12 | hundredormore= 0; // Will be !0 if x >= 100 13 | 14 | 15 | // Print out sign 16 | if (x < 0) { 17 | putchar('-'); 18 | x= 0 - x; 19 | } 20 | 21 | // Print out any hundred digit 22 | if (x >= 100) { 23 | putchar('1'); 24 | x= x - 100; 25 | hundredormore= 1; // "Boolean" flag :) 26 | } 27 | 28 | // Count number of ten digits 29 | while (x >= 10) { 30 | tencount++; 31 | x= x - 10; 32 | } 33 | 34 | // What we want: print out the tencount 35 | // if it is bigger than '0' or if x was 36 | // originally 100 or more. But we don't 37 | // have an OR operator. So, use nested if 38 | // statements and print in the right places! 39 | if (hundredormore == 1) { 40 | putchar(tencount); 41 | } else { 42 | if (tencount > asciizero) { 43 | putchar(tencount); 44 | } 45 | } 46 | 47 | // Convert remaining count to ASCII 48 | x= x + asciizero; 49 | putchar(x); 50 | putchar('\n'); 51 | } 52 | 53 | function main() { 54 | var num; 55 | 56 | num= -128; 57 | while (1) { 58 | printdec(num); 59 | num++; 60 | if (num == -128) { 61 | break; 62 | } 63 | } 64 | exit; 65 | } 66 | -------------------------------------------------------------------------------- /Examples/triangle.cl: -------------------------------------------------------------------------------- 1 | // Print a triangle of stars. An example of function 2 | // calling in the high level language. 3 | // (c) 2017 Warren Toomey, GPL3. 4 | 5 | function newline() { 6 | putchar('\n'); 7 | } 8 | 9 | // Print a line of stars and a newline 10 | function starline(count) { 11 | var x; 12 | 13 | x=1; 14 | while (x < count) { 15 | putchar('*'); 16 | x++; 17 | } 18 | newline(); 19 | } 20 | 21 | // Print the triangle 22 | function main() { 23 | var start; 24 | var end; 25 | start=1; 26 | 27 | while (start < 70) { 28 | starline(start); 29 | start++; 30 | } 31 | exit; 32 | } 33 | -------------------------------------------------------------------------------- /Examples/ttt.s: -------------------------------------------------------------------------------- 1 | # An implementation of a Tic Tac Toe game in CSCvon8 assembly. 2 | # Human plays against the computer. Computer will either win or draw. 3 | # 4 | # (c) 2019 Warren Toomey, GPL3 5 | 6 | # The board is stored as a 10-byte page-aligned array so that we can 7 | # index into it. Values are either spaces, 'O' or 'X'. Index position 8 | # zero is not used, but it's there so the human can enter numbers 9 | # 1 to 9. 10 | 11 | #define JOUT(x) JOU .; OUT x 12 | #define JINA JIU .; INA 13 | 14 | # Initialise the board and the boolean flags iswin and istie 15 | init: LCA '1'; STO A board+1 16 | LCA '2'; STO A board+2 17 | LCA '3'; STO A board+3 18 | LCA '4'; STO A board+4 19 | LCA '5'; STO A board+5 20 | LCA '6'; STO A board+6 21 | LCA '7'; STO A board+7 22 | LCA '8'; STO A board+8 23 | LCA '9'; STO A board+9 24 | LCA $00; STO A istie; STO A iswin 25 | 26 | # Also reset the initial jump destination. See notes below 27 | LHA S_________-11 28 | STO A smjump+1 29 | LCA S_________-11 30 | STO A smjump+2 31 | 32 | # Print out the top row of the board 33 | printboard: JOUT('\n'); 34 | JOUT(' '); LDA board+1; JOUT(A); JOUT(' '); JOUT('|') 35 | JOUT(' '); LDA board+2; JOUT(A); JOUT(' '); JOUT('|') 36 | JOUT(' '); LDA board+3; JOUT(A); 37 | 38 | # Print out the line separating the rows 39 | LCB rowsepstr 40 | 1: LDA rowsepstr,B 41 | JAZ 2f 42 | JOUT(A) 43 | LDB B+1 44 | JMP 1b 45 | 46 | # Print out the second row of the board 47 | 2: JOUT(' '); LDA board+4; JOUT(A); JOUT(' '); JOUT('|') 48 | JOUT(' '); LDA board+5; JOUT(A); JOUT(' '); JOUT('|') 49 | JOUT(' '); LDA board+6; JOUT(A); 50 | 51 | # Print out the line separating the rows 52 | LCB rowsepstr 53 | 1: LDA rowsepstr,B 54 | JAZ 2f 55 | JOUT(A) 56 | LDB B+1 57 | JMP 1b 58 | 59 | # Print out the last row of the board 60 | 2: JOUT(' '); LDA board+7; JOUT(A); JOUT(' '); JOUT('|') 61 | JOUT(' '); LDA board+8; JOUT(A); JOUT(' '); JOUT('|') 62 | JOUT(' '); LDA board+9; JOUT(A); JOUT('\n'); JOUT('\n') 63 | 64 | # Is there a tie? If so, print out the tie string 65 | LDA istie 66 | JAN printtie 67 | 68 | # Did the computer win? if so, print out the win string 69 | LDA iswin 70 | JAN printwin 71 | 72 | # Print out the "enter a move" string 73 | getmove: LCB movestring 74 | 1: LDA movestring,B 75 | JAZ 2f 76 | JOUT(A) 77 | LDB B+1 78 | JMP 1b 79 | 80 | # Set an initial dummy move 81 | LCA ' ' 82 | STO A usermove 83 | 84 | # Get a key from the user and echo it back out 85 | 2: JINA 86 | JOUT(A) 87 | 88 | # Break out when they hit the Enter key: either CR or LF 89 | LCB '\n' 90 | JEQ 3f 91 | LCB '\r' 92 | JEQ 3f 93 | 94 | # Otherwise store the move and loop back to get the Enter key 95 | STO A usermove 96 | JMP 2b 97 | 98 | # We get here when the user has entered a move. It's an illegal move if 99 | # it's below '1' or above '9' 100 | 3: LDA usermove 101 | LCB '1' 102 | JLT printillegal 103 | LCB '9' 104 | JGT printillegal 105 | 106 | # So, the move is between 1 to 9. AND off the top ASCII bits to get it in 107 | # the 1 to 9 range 108 | LCB $0F 109 | LDB A&B 110 | STO B usermove 111 | 112 | # Now load that position from the board and see if that position is 113 | # empty: not a 'O' and not a 'X' 114 | LDA board,B 115 | LCB 'O' 116 | JEQ printillegal 117 | LCB 'X' 118 | JEQ printillegal 119 | 120 | # Yes, the move is legal, so store a 'O' at that position 121 | LDB usermove 122 | LCA 'O' 123 | STO A board,B 124 | 125 | 126 | # Now we get to the fun part where the computer makes a move. 127 | # This is done as follows. Just before the human makes a move, 128 | # the nine board values combined make the current state of the game. 129 | # Based on this state and the human's move, there is an optimal 130 | # move that the computer can make to answer it. 131 | # 132 | # Below is a single JMP instruction. This is going to be modified in 133 | # two ways. Firstly, we add on a multiple of the user move, so that 134 | # we jump to the code that deals with that specific user move. 135 | # 136 | # Secondly, in the code that we jump to, we know both the user's move 137 | # and the computer's move, so we know what the board state will be 138 | # after the computer's move. Therefore, we can _modify_ the JMP destination 139 | # to point to the code to deal with the next user's move based on this 140 | # next board state. 141 | # 142 | # So, at the actual JMP destination, the code does these things: 143 | # 1. Make the best computer move, or set istie, or set iswin 144 | # 2. Update the JMP destination to reflect the new board state 145 | # 3. Jump back here to print the board out and get the next user move 146 | # 147 | # We can set A to the value 'X' and B (to raise istie or iswin flags) before 148 | # we take the jump. So, the above actions can be done with these lines of code: 149 | # 150 | # STO A or STO B istie or STO B iswin 151 | # PPR sm+1 152 | # JMP printboard 153 | # 154 | # That's 11 bytes for each action, so we multiply the usermove by 11 155 | # and add this to the jump destination. 156 | # 157 | # Now, there could be up to nine possible user moves for each board 158 | # state, but only when the board is empty. Yes, we could encode 99 bytes 159 | # to deal with each board state, but that's wasteful of RAM. Instead 160 | # we encode enough instructions to deal with the lowest AND highest 161 | # valid user move for this board state. Example: 162 | # 163 | # Say the user can only make valid moves 3, 4, 6 and 7. We would encode 164 | # handling for move 3, move 4, empty, move 6 and move 7. We would then 165 | # calculate a jump destination 33 bytes below the move 3 destination 166 | # so that B*11 is a minimum of 33 and it will find the first hander. 167 | # 168 | # All of the handling code is generated automatically. Behind the 169 | # scenes there is a script to generate all board states, the user 170 | # move, the best computer move and the result: next board or win or draw. 171 | # A second script parses this and generates the handling code below. 172 | 173 | # B still has the user's move. Multiply it by 11 decimal. It will now 174 | # be 11, 22, 33 ... 99 175 | LCA $0B 176 | LDB A*B 177 | LDA smjump+2 178 | STO A+B smjump+2 # Add B to smjump+2 179 | TST A+B JC 1f # Carry, so do the carry code 180 | JMP 2f # Otherwise skip it 181 | 1: LDA smjump+1 182 | STO A+1 smjump+1 # Ripple carry to high dest byte 183 | 184 | 2: 185 | 186 | # Before we do the jump, set B to $80 so we can toggle the iswin or istie 187 | # flags. Also set A to the character 'X' to be stored on the board 188 | LCA 'X' 189 | LCB $80 190 | 191 | # And finally, here is the self-modifying jump which takes us to the 192 | # specific code to handle the last user move. Changed by the above code. 193 | # It initially points at the code for an empty board. The -11 is there to 194 | # offset the base so that the lowest move, 1, hits the base correctly. 195 | 196 | smjump: JMP S_________-11 197 | 198 | # We include the generated code from a second file 199 | #include "tttmoves.s" 200 | 201 | 202 | # The rest of the code below has the small snippets of code 203 | # to print out messages to the user 204 | 205 | # Print out the "illegal move" message and 206 | # go back to get another move 207 | printillegal: 208 | LCB illegalstr 209 | 1: LDA illegalstr,B 210 | JAZ getmove 211 | JOUT(A) 212 | LDB B+1 213 | JMP 1b 214 | 215 | # Print out the "is a tie" message 216 | printtie: 217 | LCB tiestring 218 | 1: LDA tiestring,B 219 | JAZ getenter 220 | JOUT(A) 221 | LDB B+1 222 | JMP 1b 223 | 224 | # Print out the "computer win" message 225 | printwin: 226 | LCB winstring 227 | 1: LDA winstring,B 228 | JAZ getenter 229 | JOUT(A) 230 | LDB B+1 231 | JMP 1b 232 | 233 | # Get the enter key from the user, could be a CR or a NL 234 | getenter: JINA 235 | LCB '\n' 236 | JEQ init 237 | LCB '\r' 238 | JEQ init 239 | JMP getenter 240 | 241 | 242 | # Variables and strings below 243 | 244 | PAG 245 | board: HEX "30 31 32 33 34 35 36 37 38 39" 246 | iswin: HEX "00" 247 | istie: HEX "00" 248 | usermove: HEX "00" 249 | rowsepstr: STR "\n---+---+---\n" 250 | tiestring: STR "The game is a tie.\nHit Enter to start a new game: " 251 | winstring: STR "The computer has won.\nHit Enter to start a new game: " 252 | movestring: STR "Enter a move (1-9): " 253 | illegalstr: STR "That is not a legal move, try again\n" 254 | -------------------------------------------------------------------------------- /Examples/wktlife.s: -------------------------------------------------------------------------------- 1 | # Conway's Game of Life for the CSCvon8 CPU. 2 | # (c) 2019 Warren Toomey, GPL3 3 | # 4 | # We have a board of 32 rows by 128 columns. The edges are set to zero. 5 | # We iterate across rows 1 to 31, and columns 1 to 127 within eah row. 6 | # For some efficiency, we keep a cache of the sum of the three neighbours 7 | # to our right and to our left; there is also a cache of our cell's value 8 | # and the sum of the two neighbours above and below us. As we walk right 9 | # along a row, these cache values get propagated down. 10 | # 11 | # Also for efficiency, we self-modify the addresses of the three rows 12 | # that we are working on each time through the row loop. The 32 rows live 13 | # in memory at $D000, $D100, $D200 ... $EE00, $EF00. Each row only uses 14 | # the offset values $00 to $7F to have 128 columns. 15 | # 16 | # We modify the RAM version of the midcell with its new value. Therefore, 17 | # we need to keep copies of the original mid row and the row above us 18 | # to get our calculations right. 19 | # 20 | #define JOUT(x) JOU .; OUT x 21 | 22 | # Variables 23 | rightsum: EQU $F000 # Sum of 3 neighbours to our right 24 | leftsum: EQU $F001 # Sum of 3 neighbours to our left 25 | midsum: EQU $F002 # Sum of neighbours above/below us 26 | rightcell: EQU $F003 # Copy of cell to our right 27 | toprightcell: EQU $F004 # Copy of cell to our top-right 28 | botrightcell: EQU $F005 # Copy of cell to our bot-right 29 | midcell: EQU $F006 # Cached copy of our cell value 30 | row: EQU $F007 # Current row number: $D0 .. $EF 31 | col: EQU $F008 # Current column number: $00 .. $7F 32 | 33 | midrowcache: EQU $CF00 # Cache of the previous mid row 34 | toprowcache: EQU $CE00 # Cache of the previous top row 35 | 36 | # Initialisation. Zero both cached rows and the board. Use 37 | # self-modifying code to do this. 38 | LHA toprowcache # A is the row hi-byte 39 | 1: LCB $00 # B is the index 40 | sm1: STO 0 toprowcache,B 41 | LDB B+1 # Increment B and loop 42 | JBN 2f # while we are below $80 43 | JMP sm1 44 | 2: LDA A+1 # Move up to the next row 45 | STO A sm1+1 46 | LCB $F1 # Stop when we get past the 47 | JNE 1b # last row 48 | 49 | # Set up an r-pentomino pattern in the centre of the board 50 | LCA $01 51 | STO A $E040 52 | STO A $E041 53 | STO A $E13F 54 | STO A $E140 55 | STO A $E240 56 | 57 | # Print out ESC [ 2 J to clear the screen 58 | JOUT($1B) 59 | JOUT('[') 60 | JOUT('2') 61 | JOUT('J') 62 | 63 | # Do some set up before we can start work on the first row 64 | # Set up row below us and column we are in. 65 | firstrow: LCA $01 66 | STO A col 67 | LCA $D2 68 | STO A row 69 | 70 | # Clear the two row caches 71 | LCB $00 # B is the index 72 | LCA $80 # A is the exit value 73 | 1: STO 0 toprowcache,B 74 | STO 0 midrowcache,B 75 | LDB B+1 # Increment B and loop 76 | JNE 1b # while we are below $80 77 | 78 | # Self-modify all the row addresses used in the loop below 79 | LCA $D1; STO A sm6+1 80 | LCA $D2; STO A sm5+1 81 | 82 | # Print out ESC [ H to return to the top of the screen 83 | JOUT($1B) 84 | JOUT('[') 85 | JOUT('H') 86 | 87 | # Set up the left and mid sum to zero, and our cell value to zero 88 | firstcolumn: LCA $00 89 | STO A leftsum 90 | STO A midsum 91 | STO A midcell 92 | 93 | # Get the three cells to our right. Also update the 94 | # cached row values 95 | columloop: LDB col 96 | LDB B+1 97 | LDA toprowcache,B 98 | STO A toprightcell 99 | LDA midrowcache,B 100 | STO A rightcell; STO A toprowcache,B 101 | sm5: LDA $D200,B 102 | STO A botrightcell; STO A midrowcache,B 103 | 104 | # Add them to get the three neighbour sum to our right 105 | LDB rightcell 106 | LDA A+B 107 | LDB toprightcell 108 | STO A+B rightsum 109 | 110 | # Add up the neighbours and apply the rules of Conway's Game of Life 111 | calccell: LDA leftsum 112 | LDB midsum 113 | LDA A+B 114 | LDB rightsum 115 | LDA A+B # A has the sum of neighbours 116 | LCB $01 117 | JLE deadcell # 0 or 1 neighbours, dead 118 | LCB $04 119 | JGE deadcell # 4 or more neighbours, dead 120 | LCB $03 121 | JEQ livecell # 3 neighbours, cell is alive 122 | samecell: LDA midcell # Otherwise, same cell value as before 123 | JMP updatecell 124 | 125 | deadcell: LCA $00; JMP updatecell 126 | 127 | livecell: LCA $01 128 | 129 | updatecell: LDB col 130 | sm6: STO A $D100,B # Update the actual cell in RAM 131 | 132 | LCB $01 133 | JEQ pralive # Print either '@' or '.' 134 | prdead: JOUT('.'); JMP 1f 135 | pralive: JOUT('@') 136 | 137 | 1: 138 | 139 | # Now move up to the next column. Break out of the loop when we hit $80 140 | LDB col 141 | STO B+1 col 142 | LCA $80 143 | JEQ rowsend 144 | 145 | # Before we loop back, copy the midsum+midcell to leftsum. 146 | LDA midsum 147 | LDB midcell 148 | STO A+B leftsum 149 | 150 | # Copy rightsum-rightcell to midsum. 151 | LDA rightsum 152 | LDB rightcell 153 | STO A-B midsum 154 | 155 | # Copy rightcell to midcell and loop back 156 | STO B midcell 157 | JMP columloop 158 | 159 | # We've reached the end of a row, move down a line 160 | rowsend: JOUT('\n') 161 | 162 | # Increment the row. If this is the last row, skip some 163 | # code to deal with that fact 164 | # the first row. 165 | LDB row 166 | LCA $F0 167 | JEQ lastrow 168 | STO B+1 row 169 | 170 | # Ripple down the row values and start on the first column of the next row 171 | LDA sm5+1; STO A sm6+1 172 | LDA row; STO A sm5+1 173 | LCA $01 174 | STO A col 175 | JMP firstcolumn 176 | 177 | # We've done the last row. Print out a dummy row of empty cells 178 | # to make the output vertically symmetrical. 179 | lastrow: LCB $00 # B is the index 180 | LCA $80 # A is the exit value 181 | 1: JOUT('.') 182 | LDB B+1 # Increment B and loop 183 | JNE 1b # while we are below $80 184 | JOUT('\n') 185 | JEQ firstrow # Now go back to top of board 186 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # You need to assemble a source code file to make instr.rom before 2 | # you run 'make' to run the Verilog version of the CPU 3 | 4 | # Always run the Verilog simulation 5 | run: a.out instr.rom ucode.rom alu.rom 6 | vvp a.out 7 | 8 | 9 | # Run the Verilog simulation if the assembled program or any of the 10 | # Verilog files have changed 11 | test.vcd: a.out instr.rom ucode.rom alu.rom 12 | 13 | # Build the Verilog simulation 14 | a.out: 74138.v 74139.v 74161.v 74251.v 74574.v 74593.v \ 15 | icarus_tb.v ram.v rom.v tbhelper.v ttlcsvon8.v uart.v 16 | iverilog -g2012 icarus_tb.v 17 | 18 | # Generate the ALU ROM's contents 19 | alu.rom: gen_alu 20 | ./gen_alu 21 | 22 | # Generate the Decode ROM's contents 23 | ucode.rom: microcode gen_ucode 24 | ./gen_ucode 25 | 26 | # Clean out the Verilog simulation and the assembled program 27 | # but keep the ALU and Decode ROMs 28 | clean: 29 | rm -rf a.out *.vcd instr.rom 30 | 31 | # Clean out everything 32 | realclean: clean 33 | rm -rf *.rom 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSCvon8: 8-bit von Neumann Crazy Small CPU 2 | 3 | This repository holds the files for my 8-bit "big brother" CPU to the 4 | [4-bit Crazy Small CPU](https://minnie.tuhs.org/Programs/CrazySmallCPU/). 5 | This is a von Neumann style CPU designed with 7400-style logic chips, 32K of RAM, 32K of ROM and a UART. The CPU requires only seventeen chips, not including the 6 | clock circuitry. 7 | A short video is [here](https://www.youtube.com/watch?v=LJe3Z_fGDhg). 8 | 9 | ![](Docs/Figs/pcb_20190601.jpg) 10 | 11 | The overall design of the CPU is covered in 12 | [Docs/CSCvon8_design.md](Docs/CSCvon8_design.md). Also read the 13 | [getting started guide](Docs/getgoing_instructions.md) and the 14 | [guide to building the PCB version](Docs/building_the_CSCvon8.md). 15 | 16 | As at the 18th May 2019 I have the CPU running solidly at 3.57MHz on 17 | the PCBs that I ordered from the PCB design in the Schematics folder. 18 | I've kept a [journal](journal.md) with details of my progress from the 19 | initial design phase through to the successful build. 20 | 21 | The files and folders in this repository are: 22 | - *Docs*, documents on the design and how to use the tools below 23 | - *Examples*, example programs for the CPU 24 | - *Schematic*, a KiCad schematic of the CPU 25 | - *cas*, the assembler for the CPU 26 | - *clc*, a very crude compiler that outputs assembly that can be given to cas 27 | - *csim*, a simulator of the CPU written in Perl 28 | - *disasm*, a tool to disassemble the instruction ROM contents 29 | - *gen_alu*, a program to generate the contents of the ALU ROM 30 | - *gen_ucode*, a program to generate the contents of the Decode ROM 31 | - *journal.txt*, my running journal of the design and implementation of CSCvon8 32 | 33 | There is also a Verilog version with the top-level file being 34 | *ttlcsvon8.v*, the testbench is *icarus_tb.v* and the *Makefile* will 35 | build and run the Verilog testbench. Some notes on this implementation 36 | are in the 37 | [*Docs/implementation_notes.md*](Docs/implementation_notes.md) file. 38 | -------------------------------------------------------------------------------- /ROMs/aluread: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | for i in 0 1 2 3 4 5 6 7 3 | do echo -n "Put in position $i: " 4 | read fred 5 | minipro -p 'AT27C4096 @DIP40' -y -r newalu$i.bin 6 | bin2hex newalu$i.bin newalu$i.hex 7 | done 8 | -------------------------------------------------------------------------------- /ROMs/aluwrite: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Write each segment of the ALU data out to the ROM 3 | for i in 0 1 2 3 4 5 6 7 4 | do echo -n "Put TL866 Adaptor rotary switch in position $i, hit Enter: " 5 | read fred 6 | minipro -p 'AT27C4096 @DIP40' -y -w alu$i.rom 7 | done 8 | 9 | # Remove temporary files 10 | rm -f alu?.rom 11 | -------------------------------------------------------------------------------- /ROMs/decread: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | minipro -p 'M27C1024 @DIP40' -y -r decode.bin 3 | bin2hex decode.bin decode.hex 4 | rm decode.bin 5 | -------------------------------------------------------------------------------- /ROMs/decwrite: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ ! -f "../27Cucode.rom" ] 3 | then echo ../27Cucode.rom does not exist; exit 1 4 | fi 5 | minipro -p 'M27C1024 @DIP40' -y -w ../27Cucode.rom 6 | -------------------------------------------------------------------------------- /ROMs/iread: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | minipro -p 28C256 -r fred.bin 3 | bin2hex fred.bin fred.hex 4 | rm fred.bin 5 | -------------------------------------------------------------------------------- /ROMs/iwrite: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | hex2bin ../instr.rom fred.bin 3 | minipro -p 28C256 -w fred.bin 4 | rm fred.bin 5 | -------------------------------------------------------------------------------- /Schematic/Makefile: -------------------------------------------------------------------------------- 1 | ci: 2 | ci -u *.kicad_pcb *.lib *.pro *.rules *.sch 3 | 4 | co: 5 | co -l *.kicad_pcb *.lib *.pro *.rules *.sch 6 | -------------------------------------------------------------------------------- /Schematic/Schematic-cache.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /Schematic/Schematic-cache.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /Schematic/Schematic-rescue.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # 74LS251-RESCUE-Schematic 5 | # 6 | DEF 74LS251-RESCUE-Schematic U 0 10 Y Y 1 F N 7 | F0 "U" 0 850 50 H V C CNN 8 | F1 "74LS251-RESCUE-Schematic" 0 750 50 H V C CNN 9 | F2 "" 0 0 50 H I C CNN 10 | F3 "" 0 0 50 H I C CNN 11 | DRAW 12 | S -400 700 400 -700 0 1 0 N 13 | X I3 1 -700 350 300 R 50 50 1 1 I 14 | X I2 2 -700 450 300 R 50 50 1 1 I 15 | X I1 3 -700 550 300 R 50 50 1 1 I 16 | X I0 4 -700 650 300 R 50 50 1 1 I 17 | X Z 5 700 500 300 L 50 50 1 1 T 18 | X ~Z 6 700 400 300 L 50 50 1 1 T I 19 | X ~E 7 -700 -650 300 R 50 50 1 1 I I 20 | X Gnd 8 600 -600 200 L 50 50 1 1 W 21 | X S2 9 -700 -450 300 R 50 50 1 1 I 22 | X S1 10 -700 -350 300 R 50 50 1 1 I 23 | X S0 11 -700 -250 300 R 50 50 1 1 I 24 | X I7 12 -700 -50 300 R 50 50 1 1 I 25 | X I6 13 -700 50 300 R 50 50 1 1 I 26 | X I5 14 -700 150 300 R 50 50 1 1 I 27 | X I4 15 -700 250 300 R 50 50 1 1 I 28 | X Vcc 16 600 -500 200 L 50 50 1 1 W 29 | ENDDRAW 30 | ENDDEF 31 | # 32 | #End Library 33 | -------------------------------------------------------------------------------- /Schematic/Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Schematic/Schematic.jpg -------------------------------------------------------------------------------- /Schematic/Schematic.pro: -------------------------------------------------------------------------------- 1 | update=Fri 07 Jun 2019 17:03:52 AEST 2 | version=1 3 | last_client=kicad 4 | [cvpcb] 5 | version=1 6 | NetIExt=net 7 | [general] 8 | version=1 9 | [eeschema] 10 | version=1 11 | LibDir= 12 | [pcbnew] 13 | version=1 14 | PageLayoutDescrFile= 15 | LastNetListRead=Schematic.net 16 | CopperLayerCount=2 17 | BoardThickness=1.6 18 | AllowMicroVias=0 19 | AllowBlindVias=0 20 | RequireCourtyardDefinitions=0 21 | ProhibitOverlappingCourtyards=1 22 | MinTrackWidth=0.1524 23 | MinViaDiameter=0.508 24 | MinViaDrill=0.3048 25 | MinMicroViaDiameter=0.2 26 | MinMicroViaDrill=0.09999999999999999 27 | MinHoleToHole=0.25 28 | TrackWidth1=0.254 29 | TrackWidth2=0.1524 30 | TrackWidth3=0.254 31 | TrackWidth4=0.381 32 | TrackWidth5=0.508 33 | TrackWidth6=0.8128 34 | ViaDiameter1=0.6 35 | ViaDrill1=0.4 36 | ViaDiameter2=0.508 37 | ViaDrill2=0.3048 38 | ViaDiameter3=0.508 39 | ViaDrill3=0.3048 40 | ViaDiameter4=1.905 41 | ViaDrill4=1.524 42 | dPairWidth1=0.2 43 | dPairGap1=0.25 44 | dPairViaGap1=0.25 45 | SilkLineWidth=0.15 46 | SilkTextSizeV=1 47 | SilkTextSizeH=1 48 | SilkTextSizeThickness=0.15 49 | SilkTextItalic=0 50 | SilkTextUpright=1 51 | CopperLineWidth=0.2 52 | CopperTextSizeV=1.5 53 | CopperTextSizeH=1.5 54 | CopperTextThickness=0.3 55 | CopperTextItalic=0 56 | CopperTextUpright=1 57 | EdgeCutLineWidth=0.15 58 | CourtyardLineWidth=0.05 59 | OthersLineWidth=0.15 60 | OthersTextSizeV=1 61 | OthersTextSizeH=1 62 | OthersTextSizeThickness=0.15 63 | OthersTextItalic=0 64 | OthersTextUpright=1 65 | SolderMaskClearance=0.2 66 | SolderMaskMinWidth=0 67 | SolderPasteClearance=0 68 | SolderPasteRatio=-0 69 | [pcbnew/Layer.F.Cu] 70 | Name=F.Cu 71 | Type=0 72 | Enabled=1 73 | [pcbnew/Layer.In1.Cu] 74 | Name=In1.Cu 75 | Type=0 76 | Enabled=0 77 | [pcbnew/Layer.In2.Cu] 78 | Name=In2.Cu 79 | Type=0 80 | Enabled=0 81 | [pcbnew/Layer.In3.Cu] 82 | Name=In3.Cu 83 | Type=0 84 | Enabled=0 85 | [pcbnew/Layer.In4.Cu] 86 | Name=In4.Cu 87 | Type=0 88 | Enabled=0 89 | [pcbnew/Layer.In5.Cu] 90 | Name=In5.Cu 91 | Type=0 92 | Enabled=0 93 | [pcbnew/Layer.In6.Cu] 94 | Name=In6.Cu 95 | Type=0 96 | Enabled=0 97 | [pcbnew/Layer.In7.Cu] 98 | Name=In7.Cu 99 | Type=0 100 | Enabled=0 101 | [pcbnew/Layer.In8.Cu] 102 | Name=In8.Cu 103 | Type=0 104 | Enabled=0 105 | [pcbnew/Layer.In9.Cu] 106 | Name=In9.Cu 107 | Type=0 108 | Enabled=0 109 | [pcbnew/Layer.In10.Cu] 110 | Name=In10.Cu 111 | Type=0 112 | Enabled=0 113 | [pcbnew/Layer.In11.Cu] 114 | Name=In11.Cu 115 | Type=0 116 | Enabled=0 117 | [pcbnew/Layer.In12.Cu] 118 | Name=In12.Cu 119 | Type=0 120 | Enabled=0 121 | [pcbnew/Layer.In13.Cu] 122 | Name=In13.Cu 123 | Type=0 124 | Enabled=0 125 | [pcbnew/Layer.In14.Cu] 126 | Name=In14.Cu 127 | Type=0 128 | Enabled=0 129 | [pcbnew/Layer.In15.Cu] 130 | Name=In15.Cu 131 | Type=0 132 | Enabled=0 133 | [pcbnew/Layer.In16.Cu] 134 | Name=In16.Cu 135 | Type=0 136 | Enabled=0 137 | [pcbnew/Layer.In17.Cu] 138 | Name=In17.Cu 139 | Type=0 140 | Enabled=0 141 | [pcbnew/Layer.In18.Cu] 142 | Name=In18.Cu 143 | Type=0 144 | Enabled=0 145 | [pcbnew/Layer.In19.Cu] 146 | Name=In19.Cu 147 | Type=0 148 | Enabled=0 149 | [pcbnew/Layer.In20.Cu] 150 | Name=In20.Cu 151 | Type=0 152 | Enabled=0 153 | [pcbnew/Layer.In21.Cu] 154 | Name=In21.Cu 155 | Type=0 156 | Enabled=0 157 | [pcbnew/Layer.In22.Cu] 158 | Name=In22.Cu 159 | Type=0 160 | Enabled=0 161 | [pcbnew/Layer.In23.Cu] 162 | Name=In23.Cu 163 | Type=0 164 | Enabled=0 165 | [pcbnew/Layer.In24.Cu] 166 | Name=In24.Cu 167 | Type=0 168 | Enabled=0 169 | [pcbnew/Layer.In25.Cu] 170 | Name=In25.Cu 171 | Type=0 172 | Enabled=0 173 | [pcbnew/Layer.In26.Cu] 174 | Name=In26.Cu 175 | Type=0 176 | Enabled=0 177 | [pcbnew/Layer.In27.Cu] 178 | Name=In27.Cu 179 | Type=0 180 | Enabled=0 181 | [pcbnew/Layer.In28.Cu] 182 | Name=In28.Cu 183 | Type=0 184 | Enabled=0 185 | [pcbnew/Layer.In29.Cu] 186 | Name=In29.Cu 187 | Type=0 188 | Enabled=0 189 | [pcbnew/Layer.In30.Cu] 190 | Name=In30.Cu 191 | Type=0 192 | Enabled=0 193 | [pcbnew/Layer.B.Cu] 194 | Name=B.Cu 195 | Type=0 196 | Enabled=1 197 | [pcbnew/Layer.B.Adhes] 198 | Enabled=1 199 | [pcbnew/Layer.F.Adhes] 200 | Enabled=1 201 | [pcbnew/Layer.B.Paste] 202 | Enabled=1 203 | [pcbnew/Layer.F.Paste] 204 | Enabled=1 205 | [pcbnew/Layer.B.SilkS] 206 | Enabled=1 207 | [pcbnew/Layer.F.SilkS] 208 | Enabled=1 209 | [pcbnew/Layer.B.Mask] 210 | Enabled=1 211 | [pcbnew/Layer.F.Mask] 212 | Enabled=1 213 | [pcbnew/Layer.Dwgs.User] 214 | Enabled=1 215 | [pcbnew/Layer.Cmts.User] 216 | Enabled=1 217 | [pcbnew/Layer.Eco1.User] 218 | Enabled=1 219 | [pcbnew/Layer.Eco2.User] 220 | Enabled=1 221 | [pcbnew/Layer.Edge.Cuts] 222 | Enabled=1 223 | [pcbnew/Layer.Margin] 224 | Enabled=1 225 | [pcbnew/Layer.B.CrtYd] 226 | Enabled=1 227 | [pcbnew/Layer.F.CrtYd] 228 | Enabled=1 229 | [pcbnew/Layer.B.Fab] 230 | Enabled=1 231 | [pcbnew/Layer.F.Fab] 232 | Enabled=1 233 | [pcbnew/Layer.Rescue] 234 | Enabled=0 235 | [pcbnew/Netclasses] 236 | [pcbnew/Netclasses/Default] 237 | Name=Default 238 | Clearance=0.2 239 | TrackWidth=0.254 240 | ViaDiameter=0.6 241 | ViaDrill=0.4 242 | uViaDiameter=0.3 243 | uViaDrill=0.1 244 | dPairWidth=0.2 245 | dPairGap=0.25 246 | dPairViaGap=0.25 247 | [pcbnew/Netclasses/1] 248 | Name=Power 249 | Clearance=0.3 250 | TrackWidth=0.381 251 | ViaDiameter=0.7 252 | ViaDrill=0.5 253 | uViaDiameter=0.3 254 | uViaDrill=0.1 255 | dPairWidth=0.2 256 | dPairGap=0.25 257 | dPairViaGap=0.25 258 | [schematic_editor] 259 | version=1 260 | PageLayoutDescrFile= 261 | PlotDirectoryName= 262 | SubpartIdSeparator=0 263 | SubpartFirstId=65 264 | NetFmtName= 265 | SpiceAjustPassiveValues=0 266 | LabSize=60 267 | ERC_TestSimilarLabels=1 268 | -------------------------------------------------------------------------------- /Schematic/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name QX14T50B1.843200B50TT)(type Legacy)(uri "$(KIPRJMOD)/library/QX14T50B1.843200B50TT.mod")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /Schematic/gui_defaults.par: -------------------------------------------------------------------------------- 1 | 2 | (gui_defaults 3 | (windows 4 | (board_frame 5 | visible 6 | (bounds 7 | -1 1 1922 1083 8 | ) 9 | ) 10 | (color_manager 11 | visible 12 | (bounds 13 | 0 600 1112 131 14 | ) 15 | ) 16 | (layer_visibility 17 | not_visible 18 | (bounds 19 | 0 450 369 162 20 | ) 21 | ) 22 | (object_visibility 23 | not_visible 24 | (bounds 25 | 0 550 405 396 26 | ) 27 | ) 28 | (display_miscellanious 29 | not_visible 30 | (bounds 31 | 0 350 241 333 32 | ) 33 | ) 34 | (snapshots 35 | not_visible 36 | (bounds 37 | 0 250 230 255 38 | ) 39 | ) 40 | (select_parameter 41 | not_visible 42 | (bounds 43 | 0 0 246 467 44 | ) 45 | ) 46 | (route_parameter 47 | not_visible 48 | (bounds 49 | 0 100 261 542 50 | ) 51 | ) 52 | (manual_rules 53 | not_visible 54 | (bounds 55 | 0 2 315 196 56 | ) 57 | ) 58 | (route_details 59 | not_visible 60 | (bounds 61 | 0 2 263 240 62 | ) 63 | ) 64 | (move_parameter 65 | not_visible 66 | (bounds 67 | 0 50 304 139 68 | ) 69 | ) 70 | (clearance_matrix 71 | not_visible 72 | (bounds 73 | 0 150 570 273 74 | ) 75 | ) 76 | (via_rules 77 | not_visible 78 | (bounds 79 | 50 150 335 450 80 | ) 81 | ) 82 | (edit_vias 83 | not_visible 84 | (bounds 85 | 100 150 413 119 86 | ) 87 | ) 88 | (edit_net_rules 89 | not_visible 90 | (bounds 91 | 100 200 913 119 92 | ) 93 | ) 94 | (assign_net_rules 95 | not_visible 96 | (bounds 97 | 100 250 228 372 98 | ) 99 | ) 100 | (padstack_info 101 | not_visible 102 | (bounds 103 | 100 30 0 0 104 | ) 105 | ) 106 | (package_info 107 | not_visible 108 | (bounds 109 | 200 30 0 0 110 | ) 111 | ) 112 | (component_info 113 | not_visible 114 | (bounds 115 | 300 30 0 0 116 | ) 117 | ) 118 | (net_info 119 | not_visible 120 | (bounds 121 | 350 30 0 0 122 | ) 123 | ) 124 | (incompletes_info 125 | not_visible 126 | (bounds 127 | 400 30 0 0 128 | ) 129 | ) 130 | (violations_info 131 | not_visible 132 | (bounds 133 | 500 30 0 0 134 | ) 135 | ) 136 | ) 137 | (colors 138 | (background 139 | 255 255 255 140 | ) 141 | (hilight 0.8 142 | 230 255 255 143 | ) 144 | (incompletes 1.0 145 | 255 255 255 146 | ) 147 | (outline 148 | 100 150 255 149 | ) 150 | (component_front 151 | 0 0 255 152 | ) 153 | (component_back 154 | 255 0 0 155 | ) 156 | (violations 157 | 255 0 255 158 | ) 159 | (length_matching 0.1 160 | 0 255 0 161 | ) 162 | (traces 0.4 163 | 255 0 0 164 | 0 0 255 165 | ) 166 | (fixed_traces 0.4 167 | 255 0 0 168 | 0 0 255 169 | ) 170 | (vias 0.6 171 | 200 200 0 172 | 200 200 0 173 | ) 174 | (fixed_vias 0.6 175 | 200 200 0 176 | 200 200 0 177 | ) 178 | (pins 0.6 179 | 150 50 0 180 | 160 80 0 181 | ) 182 | (conduction 0.2 183 | 0 150 0 184 | 100 100 0 185 | ) 186 | (keepout 0.2 187 | 0 110 110 188 | 0 100 160 189 | ) 190 | (via_keepout 0.2 191 | 100 100 100 192 | 100 100 100 193 | ) 194 | ) 195 | (parameter 196 | (selection_layers 197 | all_visible 198 | ) 199 | (selectable_items 200 | TRACES VIAS PINS FIXED UNFIXED 201 | ) 202 | (via_snap_to_smd_center 203 | on 204 | ) 205 | (route_mode 206 | dynamic 207 | ) 208 | (shove_enabled 209 | on 210 | ) 211 | (drag_components_enabled 212 | on 213 | ) 214 | (hilight_routing_obstacle 215 | off 216 | ) 217 | (pull_tight_region 218 | 2147483647 219 | ) 220 | (pull_tight_accuracy 221 | 500 222 | ) 223 | (clearance_compensation 224 | off 225 | ) 226 | (ignore_conduction_areas 227 | on 228 | ) 229 | (automatic_layer_dimming 230 | 0.7 231 | ) 232 | (deselected_snapshot_attributes 233 | ) 234 | ) 235 | ) -------------------------------------------------------------------------------- /Schematic/library/7400-ic.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # 74HC238 5 | # 6 | DEF 74HC238 IC 0 40 Y Y 1 F N 7 | F0 "IC" -150 650 60 H V C CNN 8 | F1 "74HC238" 0 -650 60 H V C CNN 9 | F2 "" 0 0 60 H V C CNN 10 | F3 "" 0 0 60 H V C CNN 11 | $FPLIST 12 | DIP16 13 | SOIC16 14 | TSSOP16 15 | $ENDFPLIST 16 | DRAW 17 | S -250 600 250 -600 0 1 0 f 18 | X A 1 -400 100 150 R 50 50 1 1 I 19 | X B 2 -400 0 150 R 50 50 1 1 I 20 | X C 3 -400 -100 150 R 50 50 1 1 I 21 | X ~G2A~ 4 -400 -400 150 R 50 50 1 1 I 22 | X ~G2B~ 5 -400 -500 150 R 50 50 1 1 I 23 | X G1 6 -400 -300 150 R 50 50 1 1 I 24 | X Y7 7 400 -350 150 L 50 50 1 1 O 25 | X GND 8 -400 300 150 R 50 50 1 1 W 26 | X Y6 9 400 -250 150 L 50 50 1 1 O 27 | X Y5 10 400 -150 150 L 50 50 1 1 O 28 | X Y4 11 400 -50 150 L 50 50 1 1 O 29 | X Y3 12 400 50 150 L 50 50 1 1 O 30 | X Y2 13 400 150 150 L 50 50 1 1 O 31 | X Y1 14 400 250 150 L 50 50 1 1 O 32 | X Y0 15 400 350 150 L 50 50 1 1 O 33 | X VCC 16 -400 500 150 R 50 50 1 1 W 34 | ENDDRAW 35 | ENDDEF 36 | # 37 | # 74HC4050 38 | # 39 | DEF 74HC4050 IC 0 40 Y Y 1 F N 40 | F0 "IC" -200 650 60 H V C CNN 41 | F1 "74HC4050" 0 -650 60 H V C CNN 42 | F2 "" -100 0 60 H I C CNN 43 | F3 "" -50 0 60 H I C CNN 44 | $FPLIST 45 | DIP16 46 | SOIC16 47 | SSOP16 48 | TSSOP16 49 | $ENDFPLIST 50 | DRAW 51 | S -250 550 250 -550 0 1 0 f 52 | X VCC 1 -400 450 150 R 50 50 1 1 W 53 | X 1Y 2 400 50 150 L 50 50 1 1 O 54 | X 1A 3 -400 50 150 R 50 50 1 1 I 55 | X 2Y 4 400 -50 150 L 50 50 1 1 O 56 | X 2A 5 -400 -50 150 R 50 50 1 1 I 57 | X 3Y 6 400 -150 150 L 50 50 1 1 O 58 | X 3A 7 -400 -150 150 R 50 50 1 1 I 59 | X GND 8 -400 250 150 R 50 50 1 1 W 60 | X 4A 9 -400 -250 150 R 50 50 1 1 I 61 | X 4Y 10 400 -250 150 L 50 50 1 1 O 62 | X 5A 11 -400 -350 150 R 50 50 1 1 I 63 | X 5Y 12 400 -350 150 L 50 50 1 1 O 64 | X NC 13 400 350 150 L 50 50 1 1 N 65 | X 6A 14 -400 -450 150 R 50 50 1 1 I 66 | X 6Y 15 400 -450 150 L 50 50 1 1 O 67 | X NC 16 400 450 150 L 50 50 1 1 N 68 | ENDDRAW 69 | ENDDEF 70 | # 71 | # 74HC595 72 | # 73 | DEF 74HC595 IC 0 40 Y Y 1 F N 74 | F0 "IC" -150 550 60 H V C CNN 75 | F1 "74HC595" 0 -700 60 H V C CNN 76 | F2 "" 0 0 60 H V C CNN 77 | F3 "" 0 0 60 H V C CNN 78 | $FPLIST 79 | DIP16 80 | SOIC16 81 | TSSOP16 82 | $ENDFPLIST 83 | DRAW 84 | S -250 500 250 -600 0 1 0 f 85 | X QB 1 400 -400 150 L 50 50 1 1 O 86 | X QC 2 400 -300 150 L 50 50 1 1 O 87 | X QD 3 400 -200 150 L 50 50 1 1 O 88 | X QE 4 400 -100 150 L 50 50 1 1 O 89 | X QF 5 400 0 150 L 50 50 1 1 O 90 | X QG 6 400 100 150 L 50 50 1 1 O 91 | X QH 7 400 200 150 L 50 50 1 1 O 92 | X GND 8 -400 200 150 R 50 50 1 1 W 93 | X QH' 9 400 400 150 L 50 50 1 1 O 94 | X ~CLR~ 10 -400 -500 150 R 50 50 1 1 I 95 | X SCK 11 -400 -100 150 R 50 50 1 1 I 96 | X LCK 12 -400 -200 150 R 50 50 1 1 I 97 | X ~OE~ 13 -400 -400 150 R 50 50 1 1 I 98 | X SI 14 -400 0 150 R 50 50 1 1 I 99 | X QA 15 400 -500 150 L 50 50 1 1 O 100 | X VCC 16 -400 400 150 R 50 50 1 1 W 101 | ENDDRAW 102 | ENDDEF 103 | # 104 | #End Library 105 | -------------------------------------------------------------------------------- /Schematic/library/74LS161.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /Schematic/library/74LS161.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /Schematic/library/74LS593.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /Schematic/library/74LS593.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /Schematic/library/AT27C1024-70PU.bak: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # AT27C1024-70PU 5 | # 6 | DEF AT27C1024-70PU IC 0 30 Y Y 1 F N 7 | F0 "IC" 450 250 50 H V L CNN 8 | F1 "AT27C1024-70PU" 200 150 50 H V L CNN 9 | F2 "DIP1556W56P254L5232H483Q40N" -2450 1500 50 H I L CNN 10 | F3 "http://www.atmel.com/images/doc0019.pdf" -2450 1400 50 H I L CNN 11 | F4 "AT27C1024-70PU, OTP EPROM Memory 1Mbit 64K x 16 bit 70ns 4.5 5.5 V 40-Pin PDIP" -2450 1300 50 H I L CNN "Description" 12 | F5 "4.826" -2450 1200 50 H I L CNN "Height" 13 | F6 "Microchip" -2450 1100 50 H I L CNN "Manufacturer_Name" 14 | F7 "AT27C1024-70PU" -2450 1000 50 H I L CNN "Manufacturer_Part_Number" 15 | F8 "556-AT27C102470PU" -2450 900 50 H I L CNN "Mouser Part Number" 16 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=556-AT27C102470PU" -2450 800 50 H I L CNN "Mouser Price/Stock" 17 | F10 "6962768" -2450 700 50 H I L CNN "RS Part Number" 18 | F11 "http://uk.rs-online.com/web/p/products/6962768" -2450 600 50 H I L CNN "RS Price/Stock" 19 | DRAW 20 | X VPP 1 0 0 200 R 50 50 0 0 I 21 | X ~CE 2 0 -300 200 R 50 50 0 0 I 22 | X O15 3 1100 -450 200 L 50 50 0 0 B 23 | X O14 4 1100 -550 200 L 50 50 0 0 B 24 | X O13 5 1100 -650 200 L 50 50 0 0 B 25 | X O12 6 1100 -750 200 L 50 50 0 0 B 26 | X O11 7 1100 -850 200 L 50 50 0 0 B 27 | X O10 8 1100 -950 200 L 50 50 0 0 B 28 | X O9 9 1100 -1050 200 L 50 50 0 0 B 29 | X O8 10 1100 -1150 200 L 50 50 0 0 B 30 | X ~OE 20 1100 -300 200 L 50 50 0 0 I 31 | X GND_1 30 1100 -200 200 L 50 50 0 0 W 32 | X VCC 40 1100 0 200 L 50 50 0 0 W 33 | X GND 11 1100 -100 200 L 50 50 0 0 W 34 | X A0 21 0 -1950 200 R 50 50 0 0 B 35 | X A9 31 0 -1050 200 R 50 50 0 0 B 36 | X O7 12 1100 -1250 200 L 50 50 0 0 B 37 | X A1 22 0 -1850 200 R 50 50 0 0 B 38 | X A10 32 0 -950 200 R 50 50 0 0 B 39 | X O6 13 1100 -1350 200 L 50 50 0 0 B 40 | X A2 23 0 -1750 200 R 50 50 0 0 B 41 | X A11 33 0 -850 200 R 50 50 0 0 B 42 | X O5 14 1100 -1450 200 L 50 50 0 0 B 43 | X A3 24 0 -1650 200 R 50 50 0 0 B 44 | X A12 34 0 -750 200 R 50 50 0 0 I 45 | X O4 15 1100 -1550 200 L 50 50 0 0 B 46 | X A4 25 0 -1550 200 R 50 50 0 0 B 47 | X A13 35 0 -650 200 R 50 50 0 0 I 48 | X O3 16 1100 -1650 200 L 50 50 0 0 B 49 | X A5 26 0 -1450 200 R 50 50 0 0 B 50 | X A14 36 0 -550 200 R 50 50 0 0 I 51 | X O2 17 1100 -1750 200 L 50 50 0 0 B 52 | X A6 27 0 -1350 200 R 50 50 0 0 B 53 | X A15 37 0 -450 200 R 50 50 0 0 I 54 | X O1 18 1100 -1850 200 L 50 50 0 0 B 55 | X A7 28 0 -1250 200 R 50 50 0 0 B 56 | X NC 38 0 -200 200 R 50 50 0 0 B 57 | X O0 19 1100 -1950 200 L 50 50 0 0 B 58 | X A8 29 0 -1150 200 R 50 50 0 0 B 59 | X ~PGM 39 0 -100 200 R 50 50 0 0 I 60 | P 5 0 1 6 200 100 900 100 900 -2000 200 -2000 200 100 N 61 | ENDDRAW 62 | ENDDEF 63 | # 64 | #End Library 65 | -------------------------------------------------------------------------------- /Schematic/library/AT27C1024-70PU.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP AT27C1024-70PU 4 | D AT27C1024-70PU, OTP EPROM Memory 1Mbit 64K x 16 bit 70ns 4.5 5.5 V 40-Pin PDIP 5 | F http://www.atmel.com/images/doc0019.pdf 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /Schematic/library/AT27C1024-70PU.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP AT27C1024-70PU 4 | D AT27C1024-70PU, OTP EPROM Memory 1Mbit 64K x 16 bit 70ns 4.5 5.5 V 40-Pin PDIP 5 | F http://www.atmel.com/images/doc0019.pdf 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /Schematic/library/AT27C1024-70PU.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # AT27C1024-70PU 5 | # 6 | DEF AT27C1024-70PU IC 0 30 Y Y 1 F N 7 | F0 "IC" 450 250 50 H V L CNN 8 | F1 "AT27C1024-70PU" 200 150 50 H V L CNN 9 | F2 "DIP1556W56P254L5232H483Q40N" -2450 1500 50 H I L CNN 10 | F3 "http://www.atmel.com/images/doc0019.pdf" -2450 1400 50 H I L CNN 11 | F4 "AT27C1024-70PU, OTP EPROM Memory 1Mbit 64K x 16 bit 70ns 4.5 5.5 V 40-Pin PDIP" -2450 1300 50 H I L CNN "Description" 12 | F5 "4.826" -2450 1200 50 H I L CNN "Height" 13 | F6 "Microchip" -2450 1100 50 H I L CNN "Manufacturer_Name" 14 | F7 "AT27C1024-70PU" -2450 1000 50 H I L CNN "Manufacturer_Part_Number" 15 | F8 "556-AT27C102470PU" -2450 900 50 H I L CNN "Mouser Part Number" 16 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=556-AT27C102470PU" -2450 800 50 H I L CNN "Mouser Price/Stock" 17 | F10 "6962768" -2450 700 50 H I L CNN "RS Part Number" 18 | F11 "http://uk.rs-online.com/web/p/products/6962768" -2450 600 50 H I L CNN "RS Price/Stock" 19 | DRAW 20 | X VPP 1 0 0 200 R 50 50 0 0 I 21 | X ~CE 2 0 -300 200 R 50 50 0 0 I I 22 | X O15 3 1100 -450 200 L 50 50 0 0 B 23 | X O14 4 1100 -550 200 L 50 50 0 0 B 24 | X O13 5 1100 -650 200 L 50 50 0 0 B 25 | X O12 6 1100 -750 200 L 50 50 0 0 B 26 | X O11 7 1100 -850 200 L 50 50 0 0 B 27 | X O10 8 1100 -950 200 L 50 50 0 0 B 28 | X O9 9 1100 -1050 200 L 50 50 0 0 B 29 | X O8 10 1100 -1150 200 L 50 50 0 0 B 30 | X ~OE 20 1100 -300 200 L 50 50 0 0 I I 31 | X GND_1 30 1100 -200 200 L 50 50 0 0 W 32 | X VCC 40 1100 0 200 L 50 50 0 0 W 33 | X GND 11 1100 -100 200 L 50 50 0 0 W 34 | X A0 21 0 -1950 200 R 50 50 0 0 B 35 | X A9 31 0 -1050 200 R 50 50 0 0 B 36 | X O7 12 1100 -1250 200 L 50 50 0 0 B 37 | X A1 22 0 -1850 200 R 50 50 0 0 B 38 | X A10 32 0 -950 200 R 50 50 0 0 B 39 | X O6 13 1100 -1350 200 L 50 50 0 0 B 40 | X A2 23 0 -1750 200 R 50 50 0 0 B 41 | X A11 33 0 -850 200 R 50 50 0 0 B 42 | X O5 14 1100 -1450 200 L 50 50 0 0 B 43 | X A3 24 0 -1650 200 R 50 50 0 0 B 44 | X A12 34 0 -750 200 R 50 50 0 0 I 45 | X O4 15 1100 -1550 200 L 50 50 0 0 B 46 | X A4 25 0 -1550 200 R 50 50 0 0 B 47 | X A13 35 0 -650 200 R 50 50 0 0 I 48 | X O3 16 1100 -1650 200 L 50 50 0 0 B 49 | X A5 26 0 -1450 200 R 50 50 0 0 B 50 | X A14 36 0 -550 200 R 50 50 0 0 I 51 | X O2 17 1100 -1750 200 L 50 50 0 0 B 52 | X A6 27 0 -1350 200 R 50 50 0 0 B 53 | X A15 37 0 -450 200 R 50 50 0 0 I 54 | X O1 18 1100 -1850 200 L 50 50 0 0 B 55 | X A7 28 0 -1250 200 R 50 50 0 0 B 56 | X NC 38 0 -200 200 R 50 50 0 0 B 57 | X O0 19 1100 -1950 200 L 50 50 0 0 B 58 | X A8 29 0 -1150 200 R 50 50 0 0 B 59 | X ~PGM 39 0 -100 200 R 50 50 0 0 I I 60 | P 5 0 1 6 200 100 900 100 900 -2000 200 -2000 200 100 N 61 | ENDDRAW 62 | ENDDEF 63 | # 64 | #End Library 65 | -------------------------------------------------------------------------------- /Schematic/library/AT27C1024-70PU.mod: -------------------------------------------------------------------------------- 1 | PCBNEW-LibModule-V1 2019-03-17 05:51:13 2 | # encoding utf-8 3 | Units mm 4 | $INDEX 5 | DIP1556W56P254L5232H483Q40N 6 | $EndINDEX 7 | $MODULE DIP1556W56P254L5232H483Q40N 8 | Po 0 0 0 15 5c8de051 00000000 ~~ 9 | Li DIP1556W56P254L5232H483Q40N 10 | Cd 40P6 11 | Kw Integrated Circuit 12 | Sc 0 13 | At STD 14 | AR 15 | Op 0 0 0 16 | T0 0 0 1.27 1.27 0 0.254 N V 21 N "IC**" 17 | T1 0 0 1.27 1.27 0 0.254 N I 21 N "DIP1556W56P254L5232H483Q40N" 18 | DS -8.767 -26.539 8.767 -26.539 0.05 24 19 | DS 8.767 -26.539 8.767 26.539 0.05 24 20 | DS 8.767 26.539 -8.767 26.539 0.05 24 21 | DS -8.767 26.539 -8.767 -26.539 0.05 24 22 | DS -6.985 -26.289 6.985 -26.289 0.1 24 23 | DS 6.985 -26.289 6.985 26.289 0.1 24 24 | DS 6.985 26.289 -6.985 26.289 0.1 24 25 | DS -6.985 26.289 -6.985 -26.289 0.1 24 26 | DS -6.985 -25.019 -5.715 -26.289 0.1 24 27 | DS -8.358 -26.289 6.985 -26.289 0.2 21 28 | DS -6.985 26.289 6.985 26.289 0.2 21 29 | $PAD 30 | Po -7.779 -24.13 31 | Sh "1" R 1.159 1.159 0 0 900 32 | Dr 0.759 0 0 33 | At STD N 00E0FFFF 34 | Ne 0 "" 35 | $EndPAD 36 | $PAD 37 | Po -7.779 -21.59 38 | Sh "2" C 1.159 1.159 0 0 900 39 | Dr 0.759 0 0 40 | At STD N 00E0FFFF 41 | Ne 0 "" 42 | $EndPAD 43 | $PAD 44 | Po -7.779 -19.05 45 | Sh "3" C 1.159 1.159 0 0 900 46 | Dr 0.759 0 0 47 | At STD N 00E0FFFF 48 | Ne 0 "" 49 | $EndPAD 50 | $PAD 51 | Po -7.779 -16.51 52 | Sh "4" C 1.159 1.159 0 0 900 53 | Dr 0.759 0 0 54 | At STD N 00E0FFFF 55 | Ne 0 "" 56 | $EndPAD 57 | $PAD 58 | Po -7.779 -13.97 59 | Sh "5" C 1.159 1.159 0 0 900 60 | Dr 0.759 0 0 61 | At STD N 00E0FFFF 62 | Ne 0 "" 63 | $EndPAD 64 | $PAD 65 | Po -7.779 -11.43 66 | Sh "6" C 1.159 1.159 0 0 900 67 | Dr 0.759 0 0 68 | At STD N 00E0FFFF 69 | Ne 0 "" 70 | $EndPAD 71 | $PAD 72 | Po -7.779 -8.89 73 | Sh "7" C 1.159 1.159 0 0 900 74 | Dr 0.759 0 0 75 | At STD N 00E0FFFF 76 | Ne 0 "" 77 | $EndPAD 78 | $PAD 79 | Po -7.779 -6.35 80 | Sh "8" C 1.159 1.159 0 0 900 81 | Dr 0.759 0 0 82 | At STD N 00E0FFFF 83 | Ne 0 "" 84 | $EndPAD 85 | $PAD 86 | Po -7.779 -3.81 87 | Sh "9" C 1.159 1.159 0 0 900 88 | Dr 0.759 0 0 89 | At STD N 00E0FFFF 90 | Ne 0 "" 91 | $EndPAD 92 | $PAD 93 | Po -7.779 -1.27 94 | Sh "10" C 1.159 1.159 0 0 900 95 | Dr 0.759 0 0 96 | At STD N 00E0FFFF 97 | Ne 0 "" 98 | $EndPAD 99 | $PAD 100 | Po -7.779 1.27 101 | Sh "11" C 1.159 1.159 0 0 900 102 | Dr 0.759 0 0 103 | At STD N 00E0FFFF 104 | Ne 0 "" 105 | $EndPAD 106 | $PAD 107 | Po -7.779 3.81 108 | Sh "12" C 1.159 1.159 0 0 900 109 | Dr 0.759 0 0 110 | At STD N 00E0FFFF 111 | Ne 0 "" 112 | $EndPAD 113 | $PAD 114 | Po -7.779 6.35 115 | Sh "13" C 1.159 1.159 0 0 900 116 | Dr 0.759 0 0 117 | At STD N 00E0FFFF 118 | Ne 0 "" 119 | $EndPAD 120 | $PAD 121 | Po -7.779 8.89 122 | Sh "14" C 1.159 1.159 0 0 900 123 | Dr 0.759 0 0 124 | At STD N 00E0FFFF 125 | Ne 0 "" 126 | $EndPAD 127 | $PAD 128 | Po -7.779 11.43 129 | Sh "15" C 1.159 1.159 0 0 900 130 | Dr 0.759 0 0 131 | At STD N 00E0FFFF 132 | Ne 0 "" 133 | $EndPAD 134 | $PAD 135 | Po -7.779 13.97 136 | Sh "16" C 1.159 1.159 0 0 900 137 | Dr 0.759 0 0 138 | At STD N 00E0FFFF 139 | Ne 0 "" 140 | $EndPAD 141 | $PAD 142 | Po -7.779 16.51 143 | Sh "17" C 1.159 1.159 0 0 900 144 | Dr 0.759 0 0 145 | At STD N 00E0FFFF 146 | Ne 0 "" 147 | $EndPAD 148 | $PAD 149 | Po -7.779 19.05 150 | Sh "18" C 1.159 1.159 0 0 900 151 | Dr 0.759 0 0 152 | At STD N 00E0FFFF 153 | Ne 0 "" 154 | $EndPAD 155 | $PAD 156 | Po -7.779 21.59 157 | Sh "19" C 1.159 1.159 0 0 900 158 | Dr 0.759 0 0 159 | At STD N 00E0FFFF 160 | Ne 0 "" 161 | $EndPAD 162 | $PAD 163 | Po -7.779 24.13 164 | Sh "20" C 1.159 1.159 0 0 900 165 | Dr 0.759 0 0 166 | At STD N 00E0FFFF 167 | Ne 0 "" 168 | $EndPAD 169 | $PAD 170 | Po 7.779 24.13 171 | Sh "21" C 1.159 1.159 0 0 900 172 | Dr 0.759 0 0 173 | At STD N 00E0FFFF 174 | Ne 0 "" 175 | $EndPAD 176 | $PAD 177 | Po 7.779 21.59 178 | Sh "22" C 1.159 1.159 0 0 900 179 | Dr 0.759 0 0 180 | At STD N 00E0FFFF 181 | Ne 0 "" 182 | $EndPAD 183 | $PAD 184 | Po 7.779 19.05 185 | Sh "23" C 1.159 1.159 0 0 900 186 | Dr 0.759 0 0 187 | At STD N 00E0FFFF 188 | Ne 0 "" 189 | $EndPAD 190 | $PAD 191 | Po 7.779 16.51 192 | Sh "24" C 1.159 1.159 0 0 900 193 | Dr 0.759 0 0 194 | At STD N 00E0FFFF 195 | Ne 0 "" 196 | $EndPAD 197 | $PAD 198 | Po 7.779 13.97 199 | Sh "25" C 1.159 1.159 0 0 900 200 | Dr 0.759 0 0 201 | At STD N 00E0FFFF 202 | Ne 0 "" 203 | $EndPAD 204 | $PAD 205 | Po 7.779 11.43 206 | Sh "26" C 1.159 1.159 0 0 900 207 | Dr 0.759 0 0 208 | At STD N 00E0FFFF 209 | Ne 0 "" 210 | $EndPAD 211 | $PAD 212 | Po 7.779 8.89 213 | Sh "27" C 1.159 1.159 0 0 900 214 | Dr 0.759 0 0 215 | At STD N 00E0FFFF 216 | Ne 0 "" 217 | $EndPAD 218 | $PAD 219 | Po 7.779 6.35 220 | Sh "28" C 1.159 1.159 0 0 900 221 | Dr 0.759 0 0 222 | At STD N 00E0FFFF 223 | Ne 0 "" 224 | $EndPAD 225 | $PAD 226 | Po 7.779 3.81 227 | Sh "29" C 1.159 1.159 0 0 900 228 | Dr 0.759 0 0 229 | At STD N 00E0FFFF 230 | Ne 0 "" 231 | $EndPAD 232 | $PAD 233 | Po 7.779 1.27 234 | Sh "30" C 1.159 1.159 0 0 900 235 | Dr 0.759 0 0 236 | At STD N 00E0FFFF 237 | Ne 0 "" 238 | $EndPAD 239 | $PAD 240 | Po 7.779 -1.27 241 | Sh "31" C 1.159 1.159 0 0 900 242 | Dr 0.759 0 0 243 | At STD N 00E0FFFF 244 | Ne 0 "" 245 | $EndPAD 246 | $PAD 247 | Po 7.779 -3.81 248 | Sh "32" C 1.159 1.159 0 0 900 249 | Dr 0.759 0 0 250 | At STD N 00E0FFFF 251 | Ne 0 "" 252 | $EndPAD 253 | $PAD 254 | Po 7.779 -6.35 255 | Sh "33" C 1.159 1.159 0 0 900 256 | Dr 0.759 0 0 257 | At STD N 00E0FFFF 258 | Ne 0 "" 259 | $EndPAD 260 | $PAD 261 | Po 7.779 -8.89 262 | Sh "34" C 1.159 1.159 0 0 900 263 | Dr 0.759 0 0 264 | At STD N 00E0FFFF 265 | Ne 0 "" 266 | $EndPAD 267 | $PAD 268 | Po 7.779 -11.43 269 | Sh "35" C 1.159 1.159 0 0 900 270 | Dr 0.759 0 0 271 | At STD N 00E0FFFF 272 | Ne 0 "" 273 | $EndPAD 274 | $PAD 275 | Po 7.779 -13.97 276 | Sh "36" C 1.159 1.159 0 0 900 277 | Dr 0.759 0 0 278 | At STD N 00E0FFFF 279 | Ne 0 "" 280 | $EndPAD 281 | $PAD 282 | Po 7.779 -16.51 283 | Sh "37" C 1.159 1.159 0 0 900 284 | Dr 0.759 0 0 285 | At STD N 00E0FFFF 286 | Ne 0 "" 287 | $EndPAD 288 | $PAD 289 | Po 7.779 -19.05 290 | Sh "38" C 1.159 1.159 0 0 900 291 | Dr 0.759 0 0 292 | At STD N 00E0FFFF 293 | Ne 0 "" 294 | $EndPAD 295 | $PAD 296 | Po 7.779 -21.59 297 | Sh "39" C 1.159 1.159 0 0 900 298 | Dr 0.759 0 0 299 | At STD N 00E0FFFF 300 | Ne 0 "" 301 | $EndPAD 302 | $PAD 303 | Po 7.779 -24.13 304 | Sh "40" C 1.159 1.159 0 0 900 305 | Dr 0.759 0 0 306 | At STD N 00E0FFFF 307 | Ne 0 "" 308 | $EndPAD 309 | $EndMODULE DIP1556W56P254L5232H483Q40N 310 | $EndLIBRARY 311 | -------------------------------------------------------------------------------- /Schematic/library/M27C322-100F1.bak: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | #SamacSys ECAD Model M27C322-100F1 4 | #/773339/120973/2.37/42/4/Integrated Circuit 5 | DEF M27C322-100F1 IC 0 30 Y Y 1 F N 6 | F0 "IC" 1050 300 50 H V L CNN 7 | F1 "M27C322-100F1" 1050 200 50 H V L CNN 8 | F2 "DIP1724W55P254L5481H571Q42N" 1050 100 50 H I L CNN 9 | F3 "https://componentsearchengine.com/Datasheets/1/M27C322-100F1.pdf" 1050 0 50 H I L CNN 10 | F4 "EPROM 32M (2Mx16) 100ns" 1050 -100 50 H I L CNN "Description" 11 | F5 "5.71" 1050 -200 50 H I L CNN "Height" 12 | F6 "STMicroelectronics" 1050 -300 50 H I L CNN "Manufacturer_Name" 13 | F7 "M27C322-100F1" 1050 -400 50 H I L CNN "Manufacturer_Part_Number" 14 | F8 "511-M27C322-10F" 1050 -500 50 H I L CNN "Mouser Part Number" 15 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=511-M27C322-10F" 1050 -600 50 H I L CNN "Mouser Price/Stock" 16 | F10 "4151455" 1050 -700 50 H I L CNN "RS Part Number" 17 | F11 "http://uk.rs-online.com/web/p/products/4151455" 1050 -800 50 H I L CNN "RS Price/Stock" 18 | DRAW 19 | X A18 1 0 0 200 R 50 50 0 0 B 20 | X A17 2 0 -100 200 R 50 50 0 0 B 21 | X A7 3 0 -200 200 R 50 50 0 0 B 22 | X A6 4 0 -300 200 R 50 50 0 0 B 23 | X A5 5 0 -400 200 R 50 50 0 0 B 24 | X A4 6 0 -500 200 R 50 50 0 0 B 25 | X A3 7 0 -600 200 R 50 50 0 0 B 26 | X A2 8 0 -700 200 R 50 50 0 0 B 27 | X A1 9 0 -800 200 R 50 50 0 0 B 28 | X A0 10 0 -900 200 R 50 50 0 0 B 29 | X ~E 11 0 -1000 200 R 50 50 0 0 B 30 | X VSS_1 12 0 -1100 200 R 50 50 0 0 B 31 | X ~GVPP 13 0 -1200 200 R 50 50 0 0 B 32 | X Q0 14 0 -1300 200 R 50 50 0 0 B 33 | X Q8 15 0 -1400 200 R 50 50 0 0 B 34 | X Q1 16 0 -1500 200 R 50 50 0 0 B 35 | X Q9 17 0 -1600 200 R 50 50 0 0 B 36 | X Q2 18 0 -1700 200 R 50 50 0 0 B 37 | X Q10 19 0 -1800 200 R 50 50 0 0 B 38 | X Q3 20 0 -1900 200 R 50 50 0 0 B 39 | X Q11 21 0 -2000 200 R 50 50 0 0 B 40 | X A19 42 1200 0 200 L 50 50 0 0 B 41 | X A8 41 1200 -100 200 L 50 50 0 0 B 42 | X A9 40 1200 -200 200 L 50 50 0 0 B 43 | X A10 39 1200 -300 200 L 50 50 0 0 B 44 | X A11 38 1200 -400 200 L 50 50 0 0 B 45 | X A12 37 1200 -500 200 L 50 50 0 0 B 46 | X A13 36 1200 -600 200 L 50 50 0 0 B 47 | X A14 35 1200 -700 200 L 50 50 0 0 B 48 | X A15 34 1200 -800 200 L 50 50 0 0 B 49 | X A16 33 1200 -900 200 L 50 50 0 0 B 50 | X A20 32 1200 -1000 200 L 50 50 0 0 B 51 | X VSS_2 31 1200 -1100 200 L 50 50 0 0 B 52 | X Q15 30 1200 -1200 200 L 50 50 0 0 B 53 | X Q7 29 1200 -1300 200 L 50 50 0 0 B 54 | X Q14 28 1200 -1400 200 L 50 50 0 0 B 55 | X Q6 27 1200 -1500 200 L 50 50 0 0 B 56 | X Q13 26 1200 -1600 200 L 50 50 0 0 B 57 | X Q5 25 1200 -1700 200 L 50 50 0 0 B 58 | X Q12 24 1200 -1800 200 L 50 50 0 0 B 59 | X Q4 23 1200 -1900 200 L 50 50 0 0 B 60 | X VCC 22 1200 -2000 200 L 50 50 0 0 B 61 | P 5 0 1 6 200 100 1000 100 1000 -2100 200 -2100 200 100 N 62 | ENDDRAW 63 | ENDDEF 64 | # 65 | #End Library 66 | -------------------------------------------------------------------------------- /Schematic/library/M27C322-100F1.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP M27C322-100F1 4 | D EPROM 32M (2Mx16) 100ns 5 | K 6 | F https://componentsearchengine.com/Datasheets/1/M27C322-100F1.pdf 7 | $ENDCMP 8 | # 9 | #End Doc Library 10 | -------------------------------------------------------------------------------- /Schematic/library/M27C322-100F1.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP M27C322-100F1 4 | D EPROM 32M (2Mx16) 100ns 5 | F https://componentsearchengine.com/Datasheets/1/M27C322-100F1.pdf 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /Schematic/library/M27C322-100F1.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # M27C322-100F1 5 | # 6 | DEF M27C322-100F1 IC 0 30 Y Y 1 F N 7 | F0 "IC" 600 300 50 H V L CNN 8 | F1 "M27C322-100F1" 300 200 50 H V L CNN 9 | F2 "DIP1724W55P254L5481H571Q42N" -3000 250 50 H I L CNN 10 | F3 "https://componentsearchengine.com/Datasheets/1/M27C322-100F1.pdf" -3000 150 50 H I L CNN 11 | F4 "EPROM 32M (2Mx16) 100ns" -3000 50 50 H I L CNN "Description" 12 | F5 "5.71" -3000 -50 50 H I L CNN "Height" 13 | F6 "STMicroelectronics" -3000 -150 50 H I L CNN "Manufacturer_Name" 14 | F7 "M27C322-100F1" -3000 -250 50 H I L CNN "Manufacturer_Part_Number" 15 | F8 "511-M27C322-10F" -3000 -350 50 H I L CNN "Mouser Part Number" 16 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=511-M27C322-10F" -3000 -450 50 H I L CNN "Mouser Price/Stock" 17 | F10 "4151455" -3000 -550 50 H I L CNN "RS Part Number" 18 | F11 "http://uk.rs-online.com/web/p/products/4151455" -3000 -650 50 H I L CNN "RS Price/Stock" 19 | DRAW 20 | X A18 1 0 -200 200 R 50 50 0 0 B 21 | X A17 2 0 -300 200 R 50 50 0 0 B 22 | X A7 3 0 -1300 200 R 50 50 0 0 B 23 | X A6 4 0 -1400 200 R 50 50 0 0 B 24 | X A5 5 0 -1500 200 R 50 50 0 0 B 25 | X A4 6 0 -1600 200 R 50 50 0 0 B 26 | X A3 7 0 -1700 200 R 50 50 0 0 B 27 | X A2 8 0 -1800 200 R 50 50 0 0 B 28 | X A1 9 0 -1900 200 R 50 50 0 0 B 29 | X A0 10 0 -2000 200 R 50 50 0 0 B 30 | X Q3 20 1200 -1700 200 L 50 50 0 0 B 31 | X Q15 30 1200 -500 200 L 50 50 0 0 B 32 | X A9 40 0 -1100 200 R 50 50 0 0 B 33 | X ~E 11 1200 -400 200 L 50 50 0 0 B 34 | X Q11 21 1200 -900 200 L 50 50 0 0 B 35 | X VSS_2 31 1200 -100 200 L 50 50 0 0 B 36 | X VSS_1 12 1200 -200 200 L 50 50 0 0 B 37 | X VCC 22 1200 0 200 L 50 50 0 0 B 38 | X A20 32 0 0 200 R 50 50 0 0 B 39 | X A19 42 0 -100 200 R 50 50 0 0 B 40 | X ~GVPP 13 1200 -300 200 L 50 50 0 0 B 41 | X Q4 23 1200 -1600 200 L 50 50 0 0 B 42 | X A16 33 0 -400 200 R 50 50 0 0 B 43 | X Q0 14 1200 -2000 200 L 50 50 0 0 B 44 | X Q12 24 1200 -800 200 L 50 50 0 0 B 45 | X A15 34 0 -500 200 R 50 50 0 0 B 46 | X Q8 15 1200 -1200 200 L 50 50 0 0 B 47 | X Q5 25 1200 -1500 200 L 50 50 0 0 B 48 | X A14 35 0 -600 200 R 50 50 0 0 B 49 | X Q1 16 1200 -1900 200 L 50 50 0 0 B 50 | X Q13 26 1200 -700 200 L 50 50 0 0 B 51 | X A13 36 0 -700 200 R 50 50 0 0 B 52 | X Q9 17 1200 -1100 200 L 50 50 0 0 B 53 | X Q6 27 1200 -1400 200 L 50 50 0 0 B 54 | X A12 37 0 -800 200 R 50 50 0 0 B 55 | X Q2 18 1200 -1800 200 L 50 50 0 0 B 56 | X Q14 28 1200 -600 200 L 50 50 0 0 B 57 | X A11 38 0 -900 200 R 50 50 0 0 B 58 | X Q10 19 1200 -1000 200 L 50 50 0 0 B 59 | X Q7 29 1200 -1300 200 L 50 50 0 0 B 60 | X A10 39 0 -1000 200 R 50 50 0 0 B 61 | X A8 41 0 -1200 200 R 50 50 1 0 B 62 | P 5 0 1 6 200 100 1000 100 1000 -2100 200 -2100 200 100 N 63 | ENDDRAW 64 | ENDDEF 65 | # 66 | #End Library 67 | -------------------------------------------------------------------------------- /Schematic/library/M27C322-100F1.mod: -------------------------------------------------------------------------------- 1 | PCBNEW-LibModule-V1 2019-03-17 05:45:28 2 | # encoding utf-8 3 | Units mm 4 | $INDEX 5 | DIP1724W55P254L5481H571Q42N 6 | $EndINDEX 7 | $MODULE DIP1724W55P254L5481H571Q42N 8 | Po 0 0 0 15 5c8ddef8 00000000 ~~ 9 | Li DIP1724W55P254L5481H571Q42N 10 | Cd FDIP42W - 42 pin Ceramic Frit-seal DIP, with window 11 | Kw Integrated Circuit 12 | Sc 0 13 | At STD 14 | AR 15 | Op 0 0 0 16 | T0 0 0 1.27 1.27 0 0.254 N V 21 N "IC**" 17 | T1 0 0 1.27 1.27 0 0.254 N I 21 N "DIP1724W55P254L5481H571Q42N" 18 | DS -9.985 -27.655 9.985 -27.655 0.05 24 19 | DS 9.985 -27.655 9.985 27.655 0.05 24 20 | DS 9.985 27.655 -9.985 27.655 0.05 24 21 | DS -9.985 27.655 -9.985 -27.655 0.05 24 22 | DS -7.45 -27.405 7.45 -27.405 0.1 24 23 | DS 7.45 -27.405 7.45 27.405 0.1 24 24 | DS 7.45 27.405 -7.45 27.405 0.1 24 25 | DS -7.45 27.405 -7.45 -27.405 0.1 24 26 | DS -7.45 -26.135 -6.18 -27.405 0.1 24 27 | DS -9.198 -27.405 7.45 -27.405 0.2 21 28 | DS -7.45 27.405 7.45 27.405 0.2 21 29 | $PAD 30 | Po -8.622 -25.4 31 | Sh "1" R 1.15 1.15 0 0 900 32 | Dr 0.75 0 0 33 | At STD N 00E0FFFF 34 | Ne 0 "" 35 | $EndPAD 36 | $PAD 37 | Po -8.622 -22.86 38 | Sh "2" C 1.15 1.15 0 0 900 39 | Dr 0.75 0 0 40 | At STD N 00E0FFFF 41 | Ne 0 "" 42 | $EndPAD 43 | $PAD 44 | Po -8.622 -20.32 45 | Sh "3" C 1.15 1.15 0 0 900 46 | Dr 0.75 0 0 47 | At STD N 00E0FFFF 48 | Ne 0 "" 49 | $EndPAD 50 | $PAD 51 | Po -8.622 -17.78 52 | Sh "4" C 1.15 1.15 0 0 900 53 | Dr 0.75 0 0 54 | At STD N 00E0FFFF 55 | Ne 0 "" 56 | $EndPAD 57 | $PAD 58 | Po -8.622 -15.24 59 | Sh "5" C 1.15 1.15 0 0 900 60 | Dr 0.75 0 0 61 | At STD N 00E0FFFF 62 | Ne 0 "" 63 | $EndPAD 64 | $PAD 65 | Po -8.622 -12.7 66 | Sh "6" C 1.15 1.15 0 0 900 67 | Dr 0.75 0 0 68 | At STD N 00E0FFFF 69 | Ne 0 "" 70 | $EndPAD 71 | $PAD 72 | Po -8.622 -10.16 73 | Sh "7" C 1.15 1.15 0 0 900 74 | Dr 0.75 0 0 75 | At STD N 00E0FFFF 76 | Ne 0 "" 77 | $EndPAD 78 | $PAD 79 | Po -8.622 -7.62 80 | Sh "8" C 1.15 1.15 0 0 900 81 | Dr 0.75 0 0 82 | At STD N 00E0FFFF 83 | Ne 0 "" 84 | $EndPAD 85 | $PAD 86 | Po -8.622 -5.08 87 | Sh "9" C 1.15 1.15 0 0 900 88 | Dr 0.75 0 0 89 | At STD N 00E0FFFF 90 | Ne 0 "" 91 | $EndPAD 92 | $PAD 93 | Po -8.622 -2.54 94 | Sh "10" C 1.15 1.15 0 0 900 95 | Dr 0.75 0 0 96 | At STD N 00E0FFFF 97 | Ne 0 "" 98 | $EndPAD 99 | $PAD 100 | Po -8.622 0 101 | Sh "11" C 1.15 1.15 0 0 900 102 | Dr 0.75 0 0 103 | At STD N 00E0FFFF 104 | Ne 0 "" 105 | $EndPAD 106 | $PAD 107 | Po -8.622 2.54 108 | Sh "12" C 1.15 1.15 0 0 900 109 | Dr 0.75 0 0 110 | At STD N 00E0FFFF 111 | Ne 0 "" 112 | $EndPAD 113 | $PAD 114 | Po -8.622 5.08 115 | Sh "13" C 1.15 1.15 0 0 900 116 | Dr 0.75 0 0 117 | At STD N 00E0FFFF 118 | Ne 0 "" 119 | $EndPAD 120 | $PAD 121 | Po -8.622 7.62 122 | Sh "14" C 1.15 1.15 0 0 900 123 | Dr 0.75 0 0 124 | At STD N 00E0FFFF 125 | Ne 0 "" 126 | $EndPAD 127 | $PAD 128 | Po -8.622 10.16 129 | Sh "15" C 1.15 1.15 0 0 900 130 | Dr 0.75 0 0 131 | At STD N 00E0FFFF 132 | Ne 0 "" 133 | $EndPAD 134 | $PAD 135 | Po -8.622 12.7 136 | Sh "16" C 1.15 1.15 0 0 900 137 | Dr 0.75 0 0 138 | At STD N 00E0FFFF 139 | Ne 0 "" 140 | $EndPAD 141 | $PAD 142 | Po -8.622 15.24 143 | Sh "17" C 1.15 1.15 0 0 900 144 | Dr 0.75 0 0 145 | At STD N 00E0FFFF 146 | Ne 0 "" 147 | $EndPAD 148 | $PAD 149 | Po -8.622 17.78 150 | Sh "18" C 1.15 1.15 0 0 900 151 | Dr 0.75 0 0 152 | At STD N 00E0FFFF 153 | Ne 0 "" 154 | $EndPAD 155 | $PAD 156 | Po -8.622 20.32 157 | Sh "19" C 1.15 1.15 0 0 900 158 | Dr 0.75 0 0 159 | At STD N 00E0FFFF 160 | Ne 0 "" 161 | $EndPAD 162 | $PAD 163 | Po -8.622 22.86 164 | Sh "20" C 1.15 1.15 0 0 900 165 | Dr 0.75 0 0 166 | At STD N 00E0FFFF 167 | Ne 0 "" 168 | $EndPAD 169 | $PAD 170 | Po -8.622 25.4 171 | Sh "21" C 1.15 1.15 0 0 900 172 | Dr 0.75 0 0 173 | At STD N 00E0FFFF 174 | Ne 0 "" 175 | $EndPAD 176 | $PAD 177 | Po 8.622 25.4 178 | Sh "22" C 1.15 1.15 0 0 900 179 | Dr 0.75 0 0 180 | At STD N 00E0FFFF 181 | Ne 0 "" 182 | $EndPAD 183 | $PAD 184 | Po 8.622 22.86 185 | Sh "23" C 1.15 1.15 0 0 900 186 | Dr 0.75 0 0 187 | At STD N 00E0FFFF 188 | Ne 0 "" 189 | $EndPAD 190 | $PAD 191 | Po 8.622 20.32 192 | Sh "24" C 1.15 1.15 0 0 900 193 | Dr 0.75 0 0 194 | At STD N 00E0FFFF 195 | Ne 0 "" 196 | $EndPAD 197 | $PAD 198 | Po 8.622 17.78 199 | Sh "25" C 1.15 1.15 0 0 900 200 | Dr 0.75 0 0 201 | At STD N 00E0FFFF 202 | Ne 0 "" 203 | $EndPAD 204 | $PAD 205 | Po 8.622 15.24 206 | Sh "26" C 1.15 1.15 0 0 900 207 | Dr 0.75 0 0 208 | At STD N 00E0FFFF 209 | Ne 0 "" 210 | $EndPAD 211 | $PAD 212 | Po 8.622 12.7 213 | Sh "27" C 1.15 1.15 0 0 900 214 | Dr 0.75 0 0 215 | At STD N 00E0FFFF 216 | Ne 0 "" 217 | $EndPAD 218 | $PAD 219 | Po 8.622 10.16 220 | Sh "28" C 1.15 1.15 0 0 900 221 | Dr 0.75 0 0 222 | At STD N 00E0FFFF 223 | Ne 0 "" 224 | $EndPAD 225 | $PAD 226 | Po 8.622 7.62 227 | Sh "29" C 1.15 1.15 0 0 900 228 | Dr 0.75 0 0 229 | At STD N 00E0FFFF 230 | Ne 0 "" 231 | $EndPAD 232 | $PAD 233 | Po 8.622 5.08 234 | Sh "30" C 1.15 1.15 0 0 900 235 | Dr 0.75 0 0 236 | At STD N 00E0FFFF 237 | Ne 0 "" 238 | $EndPAD 239 | $PAD 240 | Po 8.622 2.54 241 | Sh "31" C 1.15 1.15 0 0 900 242 | Dr 0.75 0 0 243 | At STD N 00E0FFFF 244 | Ne 0 "" 245 | $EndPAD 246 | $PAD 247 | Po 8.622 0 248 | Sh "32" C 1.15 1.15 0 0 900 249 | Dr 0.75 0 0 250 | At STD N 00E0FFFF 251 | Ne 0 "" 252 | $EndPAD 253 | $PAD 254 | Po 8.622 -2.54 255 | Sh "33" C 1.15 1.15 0 0 900 256 | Dr 0.75 0 0 257 | At STD N 00E0FFFF 258 | Ne 0 "" 259 | $EndPAD 260 | $PAD 261 | Po 8.622 -5.08 262 | Sh "34" C 1.15 1.15 0 0 900 263 | Dr 0.75 0 0 264 | At STD N 00E0FFFF 265 | Ne 0 "" 266 | $EndPAD 267 | $PAD 268 | Po 8.622 -7.62 269 | Sh "35" C 1.15 1.15 0 0 900 270 | Dr 0.75 0 0 271 | At STD N 00E0FFFF 272 | Ne 0 "" 273 | $EndPAD 274 | $PAD 275 | Po 8.622 -10.16 276 | Sh "36" C 1.15 1.15 0 0 900 277 | Dr 0.75 0 0 278 | At STD N 00E0FFFF 279 | Ne 0 "" 280 | $EndPAD 281 | $PAD 282 | Po 8.622 -12.7 283 | Sh "37" C 1.15 1.15 0 0 900 284 | Dr 0.75 0 0 285 | At STD N 00E0FFFF 286 | Ne 0 "" 287 | $EndPAD 288 | $PAD 289 | Po 8.622 -15.24 290 | Sh "38" C 1.15 1.15 0 0 900 291 | Dr 0.75 0 0 292 | At STD N 00E0FFFF 293 | Ne 0 "" 294 | $EndPAD 295 | $PAD 296 | Po 8.622 -17.78 297 | Sh "39" C 1.15 1.15 0 0 900 298 | Dr 0.75 0 0 299 | At STD N 00E0FFFF 300 | Ne 0 "" 301 | $EndPAD 302 | $PAD 303 | Po 8.622 -20.32 304 | Sh "40" C 1.15 1.15 0 0 900 305 | Dr 0.75 0 0 306 | At STD N 00E0FFFF 307 | Ne 0 "" 308 | $EndPAD 309 | $PAD 310 | Po 8.622 -22.86 311 | Sh "41" C 1.15 1.15 0 0 900 312 | Dr 0.75 0 0 313 | At STD N 00E0FFFF 314 | Ne 0 "" 315 | $EndPAD 316 | $PAD 317 | Po 8.622 -25.4 318 | Sh "42" C 1.15 1.15 0 0 900 319 | Dr 0.75 0 0 320 | At STD N 00E0FFFF 321 | Ne 0 "" 322 | $EndPAD 323 | $EndMODULE DIP1724W55P254L5481H571Q42N 324 | $EndLIBRARY 325 | -------------------------------------------------------------------------------- /Schematic/library/QX14T50B1.843200B50TT.bak: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | #SamacSys ECAD Model QX14T50B1.843200B50TT 4 | #/240646/120973/2.37/4/4/Undefined or Miscellaneous 5 | DEF QX14T50B1.843200B50TT U 0 30 Y Y 1 F N 6 | F0 "U" 1050 300 50 H V L CNN 7 | F1 "QX14T50B1.843200B50TT" 1050 200 50 H V L CNN 8 | F2 "QX14T50B1.843200B50TT" 1050 100 50 H I L CNN 9 | F3 "http://docs-emea.rs-online.com/webdocs/127f/0900766b8127fc57.pdf" 1050 0 50 H I L CNN 10 | F4 "QX14T50B1.843200B50TT, Crystal Oscillator, 1.8432 MHz, +/-50ppm HCMOS 50pF, 14-pin PDIP, 20.8 x 13.2 x 5.08mm" 1050 -100 50 H I L CNN "Description" 11 | F5 "" 1050 -200 50 H I L CNN "Height" 12 | F6 "Qantek" 1050 -300 50 H I L CNN "Manufacturer_Name" 13 | F7 "QX14T50B1.843200B50TT" 1050 -400 50 H I L CNN "Manufacturer_Part_Number" 14 | F8 "" 1050 -500 50 H I L CNN "Mouser Part Number" 15 | F9 "" 1050 -600 50 H I L CNN "Mouser Price/Stock" 16 | F10 "1735868" 1050 -700 50 H I L CNN "RS Part Number" 17 | F11 "http://uk.rs-online.com/web/p/products/1735868" 1050 -800 50 H I L CNN "RS Price/Stock" 18 | F12 "70418025" 1050 -900 50 H I L CNN "Allied_Number" 19 | F13 "http://www.alliedelec.com/qantek-qx14t50b18-43200b50tt/70418025/" 1050 -1000 50 H I L CNN "Allied Price/Stock" 20 | DRAW 21 | X NC 1 0 0 200 R 50 50 0 0 B 22 | X GND 7 0 -100 200 R 50 50 0 0 B 23 | X OUTPUT 8 1200 0 200 L 50 50 0 0 B 24 | X +VDD 14 1200 -100 200 L 50 50 0 0 B 25 | P 5 0 1 6 200 100 1000 100 1000 -200 200 -200 200 100 N 26 | ENDDRAW 27 | ENDDEF 28 | # 29 | #End Library 30 | -------------------------------------------------------------------------------- /Schematic/library/QX14T50B1.843200B50TT.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP QX14T50B1.843200B50TT 4 | D QX14T50B1.843200B50TT, Crystal Oscillator, 1.8432 MHz, +/-50ppm HCMOS 50pF, 14-pin PDIP, 20.8 x 13.2 x 5.08mm 5 | K 6 | F http://docs-emea.rs-online.com/webdocs/127f/0900766b8127fc57.pdf 7 | $ENDCMP 8 | # 9 | #End Doc Library 10 | -------------------------------------------------------------------------------- /Schematic/library/QX14T50B1.843200B50TT.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP QX14T50B1.843200B50TT 4 | D QX14T50B1.843200B50TT, Crystal Oscillator, 1.8432 MHz, +/-50ppm HCMOS 50pF, 14-pin PDIP, 20.8 x 13.2 x 5.08mm 5 | F http://docs-emea.rs-online.com/webdocs/127f/0900766b8127fc57.pdf 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /Schematic/library/QX14T50B1.843200B50TT.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # QX14T50B1.843200B50TT 5 | # 6 | DEF QX14T50B1.843200B50TT U 0 30 Y Y 1 F N 7 | F0 "U" 1050 300 50 H V L CNN 8 | F1 "QX14T50B1.843200B50TT" 1050 200 50 H V L CNN 9 | F2 "QX14T50B1.843200B50TT" 1050 100 50 H I L CNN 10 | F3 "http://docs-emea.rs-online.com/webdocs/127f/0900766b8127fc57.pdf" 1050 0 50 H I L CNN 11 | F4 "QX14T50B1.843200B50TT, Crystal Oscillator, 1.8432 MHz, +/-50ppm HCMOS 50pF, 14-pin PDIP, 20.8 x 13.2 x 5.08mm" 1050 -100 50 H I L CNN "Description" 12 | F5 "Qantek" 1050 -300 50 H I L CNN "Manufacturer_Name" 13 | F6 "QX14T50B1.843200B50TT" 1050 -400 50 H I L CNN "Manufacturer_Part_Number" 14 | F7 "1735868" 1050 -700 50 H I L CNN "RS Part Number" 15 | F8 "http://uk.rs-online.com/web/p/products/1735868" 1050 -800 50 H I L CNN "RS Price/Stock" 16 | F9 "70418025" 1050 -900 50 H I L CNN "Allied_Number" 17 | F10 "http://www.alliedelec.com/qantek-qx14t50b18-43200b50tt/70418025/" 1050 -1000 50 H I L CNN "Allied Price/Stock" 18 | DRAW 19 | X NC 1 0 0 200 R 50 50 0 0 B 20 | X GND 7 0 -100 200 R 50 50 0 0 W 21 | X OUTPUT 8 1200 0 200 L 50 50 0 0 B 22 | X +VDD 14 1200 -100 200 L 50 50 0 0 W 23 | P 5 0 1 6 200 100 1000 100 1000 -200 200 -200 200 100 N 24 | ENDDRAW 25 | ENDDEF 26 | # 27 | #End Library 28 | -------------------------------------------------------------------------------- /Schematic/library/QX14T50B1.843200B50TT.mod: -------------------------------------------------------------------------------- 1 | PCBNEW-LibModule-V1 2019-03-19 10:12:25 2 | # encoding utf-8 3 | Units mm 4 | $INDEX 5 | QX14T50B1.843200B50TT 6 | $EndINDEX 7 | $MODULE QX14T50B1.843200B50TT 8 | Po 0 0 0 15 5c90c089 00000000 ~~ 9 | Li QX14T50B1.843200B50TT 10 | Cd QX14T50B1.843200B50TT 11 | Kw Undefined or Miscellaneous 12 | Sc 0 13 | At STD 14 | AR 15 | Op 0 0 0 16 | T0 0 0 1.27 1.27 0 0.254 N V 21 N "U**" 17 | T1 0 0 1.27 1.27 0 0.254 N I 21 N "QX14T50B1.843200B50TT" 18 | DS -2.78 -2.79 -2.78 10.41 0.1 24 19 | DS -2.78 10.41 18.02 10.41 0.1 24 20 | DS 18.02 10.41 18.02 -2.79 0.1 24 21 | DS 18.02 -2.79 -2.78 -2.79 0.1 24 22 | DS -2.78 -2.79 -2.78 10.41 0.1 21 23 | DS -2.78 10.41 18.02 10.41 0.1 21 24 | DS 18.02 10.41 18.02 -2.79 0.1 21 25 | DS 18.02 -2.79 -2.78 -2.79 0.1 21 26 | $PAD 27 | Po 0 0 28 | Sh "14" C 1.12 1.12 0 0 900 29 | Dr 0.72 0 0 30 | At STD N 00E0FFFF 31 | Ne 0 "" 32 | $EndPAD 33 | $PAD 34 | Po 15.24 0 35 | Sh "8" C 1.12 1.12 0 0 900 36 | Dr 0.72 0 0 37 | At STD N 00E0FFFF 38 | Ne 0 "" 39 | $EndPAD 40 | $PAD 41 | Po 0 7.62 42 | Sh "1" C 1.12 1.12 0 0 900 43 | Dr 0.72 0 0 44 | At STD N 00E0FFFF 45 | Ne 0 "" 46 | $EndPAD 47 | $PAD 48 | Po 15.24 7.62 49 | Sh "7" C 1.12 1.12 0 0 900 50 | Dr 0.72 0 0 51 | At STD N 00E0FFFF 52 | Ne 0 "" 53 | $EndPAD 54 | $EndMODULE QX14T50B1.843200B50TT 55 | $EndLIBRARY 56 | -------------------------------------------------------------------------------- /Schematic/library/SN74LS273NE4.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP SN74LS273NE4 4 | D Flip Flops Octal D-Type Flip-Flop w/Clear 5 | K 6 | F http://www.ti.com/lit/ds/sdls090/sdls090.pdf 7 | $ENDCMP 8 | # 9 | #End Doc Library 10 | -------------------------------------------------------------------------------- /Schematic/library/SN74LS273NE4.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | #SamacSys ECAD Model SN74LS273NE4 4 | #/796887/120973/2.37/20/3/Integrated Circuit 5 | DEF SN74LS273NE4 IC 0 30 Y Y 1 F N 6 | F0 "IC" 950 300 50 H V L CNN 7 | F1 "SN74LS273NE4" 950 200 50 H V L CNN 8 | F2 "DIP762W55P254L2642H457Q20N" 950 100 50 H I L CNN 9 | F3 "http://www.ti.com/lit/ds/sdls090/sdls090.pdf" 950 0 50 H I L CNN 10 | F4 "Flip Flops Octal D-Type Flip-Flop w/Clear" 950 -100 50 H I L CNN "Description" 11 | F5 "4.57" 950 -200 50 H I L CNN "Height" 12 | F6 "Texas Instruments" 950 -300 50 H I L CNN "Manufacturer_Name" 13 | F7 "SN74LS273NE4" 950 -400 50 H I L CNN "Manufacturer_Part_Number" 14 | F8 "595-SN74LS273NE4" 950 -500 50 H I L CNN "Mouser Part Number" 15 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=595-SN74LS273NE4" 950 -600 50 H I L CNN "Mouser Price/Stock" 16 | F10 "" 950 -700 50 H I L CNN "RS Part Number" 17 | F11 "" 950 -800 50 H I L CNN "RS Price/Stock" 18 | DRAW 19 | X ~CLR 1 0 0 200 R 50 50 0 0 B 20 | X 1Q 2 0 -100 200 R 50 50 0 0 B 21 | X 1D 3 0 -200 200 R 50 50 0 0 B 22 | X 2D 4 0 -300 200 R 50 50 0 0 B 23 | X 2Q 5 0 -400 200 R 50 50 0 0 B 24 | X 3Q 6 0 -500 200 R 50 50 0 0 B 25 | X 3D 7 0 -600 200 R 50 50 0 0 B 26 | X 4D 8 0 -700 200 R 50 50 0 0 B 27 | X 4Q 9 0 -800 200 R 50 50 0 0 B 28 | X GND 10 0 -900 200 R 50 50 0 0 B 29 | X VCC 20 1100 0 200 L 50 50 0 0 B 30 | X 8Q 19 1100 -100 200 L 50 50 0 0 B 31 | X 8D 18 1100 -200 200 L 50 50 0 0 B 32 | X 7D 17 1100 -300 200 L 50 50 0 0 B 33 | X 7Q 16 1100 -400 200 L 50 50 0 0 B 34 | X 6Q 15 1100 -500 200 L 50 50 0 0 B 35 | X 6D 14 1100 -600 200 L 50 50 0 0 B 36 | X 5D 13 1100 -700 200 L 50 50 0 0 B 37 | X 5Q 12 1100 -800 200 L 50 50 0 0 B 38 | X CLK 11 1100 -900 200 L 50 50 0 0 B 39 | P 5 0 1 6 200 100 900 100 900 -1000 200 -1000 200 100 N 40 | ENDDRAW 41 | ENDDEF 42 | # 43 | #End Library 44 | -------------------------------------------------------------------------------- /Schematic/library/SN74LS273NE4.mod: -------------------------------------------------------------------------------- 1 | PCBNEW-LibModule-V1 2019-03-17 05:48:04 2 | # encoding utf-8 3 | Units mm 4 | $INDEX 5 | DIP762W55P254L2642H457Q20N 6 | $EndINDEX 7 | $MODULE DIP762W55P254L2642H457Q20N 8 | Po 0 0 0 15 5c8ddf94 00000000 ~~ 9 | Li DIP762W55P254L2642H457Q20N 10 | Cd CASE 738–03 11 | Kw Integrated Circuit 12 | Sc 0 13 | At STD 14 | AR 15 | Op 0 0 0 16 | T0 0 0 1.27 1.27 0 0.254 N V 21 N "IC**" 17 | T1 0 0 1.27 1.27 0 0.254 N I 21 N "DIP762W55P254L2642H457Q20N" 18 | DS -4.635 -13.835 4.635 -13.835 0.05 24 19 | DS 4.635 -13.835 4.635 13.835 0.05 24 20 | DS 4.635 13.835 -4.635 13.835 0.05 24 21 | DS -4.635 13.835 -4.635 -13.835 0.05 24 22 | DS -3.3 -13.585 3.3 -13.585 0.1 24 23 | DS 3.3 -13.585 3.3 13.585 0.1 24 24 | DS 3.3 13.585 -3.3 13.585 0.1 24 25 | DS -3.3 13.585 -3.3 -13.585 0.1 24 26 | DS -3.3 -12.315 -2.03 -13.585 0.1 24 27 | DS -4.385 -13.585 3.3 -13.585 0.2 21 28 | DS -3.3 13.585 3.3 13.585 0.2 21 29 | $PAD 30 | Po -3.81 -11.43 31 | Sh "1" R 1.15 1.15 0 0 900 32 | Dr 0.75 0 0 33 | At STD N 00E0FFFF 34 | Ne 0 "" 35 | $EndPAD 36 | $PAD 37 | Po -3.81 -8.89 38 | Sh "2" C 1.15 1.15 0 0 900 39 | Dr 0.75 0 0 40 | At STD N 00E0FFFF 41 | Ne 0 "" 42 | $EndPAD 43 | $PAD 44 | Po -3.81 -6.35 45 | Sh "3" C 1.15 1.15 0 0 900 46 | Dr 0.75 0 0 47 | At STD N 00E0FFFF 48 | Ne 0 "" 49 | $EndPAD 50 | $PAD 51 | Po -3.81 -3.81 52 | Sh "4" C 1.15 1.15 0 0 900 53 | Dr 0.75 0 0 54 | At STD N 00E0FFFF 55 | Ne 0 "" 56 | $EndPAD 57 | $PAD 58 | Po -3.81 -1.27 59 | Sh "5" C 1.15 1.15 0 0 900 60 | Dr 0.75 0 0 61 | At STD N 00E0FFFF 62 | Ne 0 "" 63 | $EndPAD 64 | $PAD 65 | Po -3.81 1.27 66 | Sh "6" C 1.15 1.15 0 0 900 67 | Dr 0.75 0 0 68 | At STD N 00E0FFFF 69 | Ne 0 "" 70 | $EndPAD 71 | $PAD 72 | Po -3.81 3.81 73 | Sh "7" C 1.15 1.15 0 0 900 74 | Dr 0.75 0 0 75 | At STD N 00E0FFFF 76 | Ne 0 "" 77 | $EndPAD 78 | $PAD 79 | Po -3.81 6.35 80 | Sh "8" C 1.15 1.15 0 0 900 81 | Dr 0.75 0 0 82 | At STD N 00E0FFFF 83 | Ne 0 "" 84 | $EndPAD 85 | $PAD 86 | Po -3.81 8.89 87 | Sh "9" C 1.15 1.15 0 0 900 88 | Dr 0.75 0 0 89 | At STD N 00E0FFFF 90 | Ne 0 "" 91 | $EndPAD 92 | $PAD 93 | Po -3.81 11.43 94 | Sh "10" C 1.15 1.15 0 0 900 95 | Dr 0.75 0 0 96 | At STD N 00E0FFFF 97 | Ne 0 "" 98 | $EndPAD 99 | $PAD 100 | Po 3.81 11.43 101 | Sh "11" C 1.15 1.15 0 0 900 102 | Dr 0.75 0 0 103 | At STD N 00E0FFFF 104 | Ne 0 "" 105 | $EndPAD 106 | $PAD 107 | Po 3.81 8.89 108 | Sh "12" C 1.15 1.15 0 0 900 109 | Dr 0.75 0 0 110 | At STD N 00E0FFFF 111 | Ne 0 "" 112 | $EndPAD 113 | $PAD 114 | Po 3.81 6.35 115 | Sh "13" C 1.15 1.15 0 0 900 116 | Dr 0.75 0 0 117 | At STD N 00E0FFFF 118 | Ne 0 "" 119 | $EndPAD 120 | $PAD 121 | Po 3.81 3.81 122 | Sh "14" C 1.15 1.15 0 0 900 123 | Dr 0.75 0 0 124 | At STD N 00E0FFFF 125 | Ne 0 "" 126 | $EndPAD 127 | $PAD 128 | Po 3.81 1.27 129 | Sh "15" C 1.15 1.15 0 0 900 130 | Dr 0.75 0 0 131 | At STD N 00E0FFFF 132 | Ne 0 "" 133 | $EndPAD 134 | $PAD 135 | Po 3.81 -1.27 136 | Sh "16" C 1.15 1.15 0 0 900 137 | Dr 0.75 0 0 138 | At STD N 00E0FFFF 139 | Ne 0 "" 140 | $EndPAD 141 | $PAD 142 | Po 3.81 -3.81 143 | Sh "17" C 1.15 1.15 0 0 900 144 | Dr 0.75 0 0 145 | At STD N 00E0FFFF 146 | Ne 0 "" 147 | $EndPAD 148 | $PAD 149 | Po 3.81 -6.35 150 | Sh "18" C 1.15 1.15 0 0 900 151 | Dr 0.75 0 0 152 | At STD N 00E0FFFF 153 | Ne 0 "" 154 | $EndPAD 155 | $PAD 156 | Po 3.81 -8.89 157 | Sh "19" C 1.15 1.15 0 0 900 158 | Dr 0.75 0 0 159 | At STD N 00E0FFFF 160 | Ne 0 "" 161 | $EndPAD 162 | $PAD 163 | Po 3.81 -11.43 164 | Sh "20" C 1.15 1.15 0 0 900 165 | Dr 0.75 0 0 166 | At STD N 00E0FFFF 167 | Ne 0 "" 168 | $EndPAD 169 | $EndMODULE DIP762W55P254L2642H457Q20N 170 | $EndLIBRARY 171 | -------------------------------------------------------------------------------- /Schematic/library/UM245R.bak: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # UM245R 5 | # 6 | DEF UM245R IC 0 30 Y Y 1 F N 7 | F0 "IC" 550 250 50 H V L CNN 8 | F1 "UM245R" 450 150 50 H V L CNN 9 | F2 "DIPS1500W50P254L3300H1050Q24N" 2100 -300 50 H I L CNN 10 | F3 "http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM245R.pdf" 2100 -400 50 H I L CNN 11 | F4 "Interface Development Tools USB to Parallel FIFO Dev Mod for FT245R" 2100 -500 50 H I L CNN "Description" 12 | F5 "10.5" 2100 -600 50 H I L CNN "Height" 13 | F6 "FTDI Chip" 2100 -700 50 H I L CNN "Manufacturer_Name" 14 | F7 "UM245R" 2100 -800 50 H I L CNN "Manufacturer_Part_Number" 15 | F8 "895-UM245R" 2100 -900 50 H I L CNN "Mouser Part Number" 16 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=895-UM245R" 2100 -1000 50 H I L CNN "Mouser Price/Stock" 17 | F10 "0406584" 2100 -1100 50 H I L CNN "RS Part Number" 18 | F11 "http://uk.rs-online.com/web/p/products/0406584" 2100 -1200 50 H I L CNN "RS Price/Stock" 19 | F12 "70069413" 2100 -1300 50 H I L CNN "Allied_Number" 20 | F13 "http://www.alliedelec.com/ftdi-um245r/70069413/" 2100 -1400 50 H I L CNN "Allied Price/Stock" 21 | DRAW 22 | X DB0 1 0 0 200 R 50 50 0 0 B 23 | X DB4 2 0 -400 200 R 50 50 0 0 B 24 | X DB2 3 0 -200 200 R 50 50 0 0 B 25 | X VIO 4 1200 -300 200 L 50 50 0 0 B 26 | X DB1 5 0 -100 200 R 50 50 0 0 B 27 | X DB7 6 0 -700 200 R 50 50 0 0 B 28 | X GND_1 7 0 -1100 200 R 50 50 0 0 w 29 | X DB5 8 0 -500 200 R 50 50 0 0 B 30 | X DB6 9 0 -600 200 R 50 50 0 0 B 31 | X DB3 10 0 -300 200 R 50 50 0 0 B 32 | X RST# 20 1200 -600 200 L 50 50 0 0 B 33 | X PWE# 11 0 -1000 200 R 50 50 0 0 B 34 | X VCC_2 21 1200 -100 200 L 50 50 0 0 w 35 | X RD# 12 0 -900 200 R 50 50 0 0 B 36 | X TEX# 22 1200 -500 200 L 50 50 0 0 B 37 | X SLD 13 1200 -1000 200 L 50 50 0 0 B 38 | X RXF# 23 1200 -400 200 L 50 50 0 0 B 39 | X USB 14 1200 -900 200 L 50 50 0 0 B 40 | X GND_2 24 1200 -1100 200 L 50 50 0 0 w 41 | X VCC_1 15 1200 0 200 L 50 50 0 0 w 42 | X PU2 16 1200 -800 200 L 50 50 0 0 B 43 | X PU1 17 1200 -700 200 L 50 50 0 0 B 44 | X WR# 18 0 -800 200 R 50 50 0 0 B 45 | X 3V3 19 1200 -200 200 L 50 50 0 0 B 46 | P 5 0 1 6 200 100 1000 100 1000 -1200 200 -1200 200 100 N 47 | ENDDRAW 48 | ENDDEF 49 | # 50 | #End Library 51 | -------------------------------------------------------------------------------- /Schematic/library/UM245R.bck: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP UM245R 4 | D Interface Development Tools USB to Parallel FIFO Dev Mod for FT245R 5 | F http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM245R.pdf 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /Schematic/library/UM245R.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP UM245R 4 | D Interface Development Tools USB to Parallel FIFO Dev Mod for FT245R 5 | F http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM245R.pdf 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /Schematic/library/UM245R.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # UM245R 5 | # 6 | DEF UM245R IC 0 30 Y Y 1 F N 7 | F0 "IC" 550 250 50 H V L CNN 8 | F1 "UM245R" 450 150 50 H V L CNN 9 | F2 "DIPS1500W50P254L3300H1050Q24N" 2100 -300 50 H I L CNN 10 | F3 "http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM245R.pdf" 2100 -400 50 H I L CNN 11 | F4 "Interface Development Tools USB to Parallel FIFO Dev Mod for FT245R" 2100 -500 50 H I L CNN "Description" 12 | F5 "10.5" 2100 -600 50 H I L CNN "Height" 13 | F6 "FTDI Chip" 2100 -700 50 H I L CNN "Manufacturer_Name" 14 | F7 "UM245R" 2100 -800 50 H I L CNN "Manufacturer_Part_Number" 15 | F8 "895-UM245R" 2100 -900 50 H I L CNN "Mouser Part Number" 16 | F9 "https://www.mouser.com/Search/Refine.aspx?Keyword=895-UM245R" 2100 -1000 50 H I L CNN "Mouser Price/Stock" 17 | F10 "0406584" 2100 -1100 50 H I L CNN "RS Part Number" 18 | F11 "http://uk.rs-online.com/web/p/products/0406584" 2100 -1200 50 H I L CNN "RS Price/Stock" 19 | F12 "70069413" 2100 -1300 50 H I L CNN "Allied_Number" 20 | F13 "http://www.alliedelec.com/ftdi-um245r/70069413/" 2100 -1400 50 H I L CNN "Allied Price/Stock" 21 | DRAW 22 | X DB0 1 0 0 200 R 50 50 0 0 B 23 | X DB4 2 0 -400 200 R 50 50 0 0 B 24 | X DB2 3 0 -200 200 R 50 50 0 0 B 25 | X VIO 4 1200 -300 200 L 50 50 0 0 B 26 | X DB1 5 0 -100 200 R 50 50 0 0 B 27 | X DB7 6 0 -700 200 R 50 50 0 0 B 28 | X GND_1 7 0 -1100 200 R 50 50 0 0 w 29 | X DB5 8 0 -500 200 R 50 50 0 0 B 30 | X DB6 9 0 -600 200 R 50 50 0 0 B 31 | X DB3 10 0 -300 200 R 50 50 0 0 B 32 | X RST# 20 1200 -600 200 L 50 50 0 0 B 33 | X PWE# 11 0 -1000 200 R 50 50 0 0 B 34 | X VCC_2 21 1200 -100 200 L 50 50 0 0 W 35 | X RD# 12 0 -900 200 R 50 50 0 0 B 36 | X TEX# 22 1200 -500 200 L 50 50 0 0 B 37 | X SLD 13 1200 -1000 200 L 50 50 0 0 B 38 | X RXF# 23 1200 -400 200 L 50 50 0 0 B 39 | X USB 14 1200 -900 200 L 50 50 0 0 B 40 | X GND_2 24 1200 -1100 200 L 50 50 0 0 W 41 | X VCC_1 15 1200 0 200 L 50 50 0 0 w 42 | X PU2 16 1200 -800 200 L 50 50 0 0 B 43 | X PU1 17 1200 -700 200 L 50 50 0 0 B 44 | X WR# 18 0 -800 200 R 50 50 0 0 B 45 | X 3V3 19 1200 -200 200 L 50 50 0 0 B 46 | P 5 0 1 6 200 100 1000 100 1000 -1200 200 -1200 200 100 N 47 | ENDDRAW 48 | ENDDEF 49 | # 50 | #End Library 51 | -------------------------------------------------------------------------------- /Schematic/library/UM245R.mod: -------------------------------------------------------------------------------- 1 | PCBNEW-LibModule-V1 2019-03-17 05:36:24 2 | # encoding utf-8 3 | Units mm 4 | $INDEX 5 | DIPS1500W50P254L3300H1050Q24N 6 | $EndINDEX 7 | $MODULE DIPS1500W50P254L3300H1050Q24N 8 | Po 0 0 0 15 5c8ddcd8 00000000 ~~ 9 | Li DIPS1500W50P254L3300H1050Q24N 10 | Cd UM245R 11 | Kw Integrated Circuit 12 | Sc 0 13 | At STD 14 | AR 15 | Op 0 0 0 16 | T0 0 0 1.27 1.27 0 0.254 N V 21 N "IC**" 17 | T1 0 0 1.27 1.27 0 0.254 N I 21 N "DIPS1500W50P254L3300H1050Q24N" 18 | DS -1.8 -2.78 16.8 -2.78 0.05 24 19 | DS 16.8 -2.78 16.8 30.72 0.05 24 20 | DS 16.8 30.72 -1.8 30.72 0.05 24 21 | DS -1.8 30.72 -1.8 -2.78 0.05 24 22 | DS -1.55 -2.53 16.55 -2.53 0.1 24 23 | DS 16.55 -2.53 16.55 30.47 0.1 24 24 | DS 16.55 30.47 -1.55 30.47 0.1 24 25 | DS -1.55 30.47 -1.55 -2.53 0.1 24 26 | DS -1.55 -1.26 -0.28 -2.53 0.1 24 27 | DS -1.55 30.47 16.55 30.47 0.2 21 28 | DS 16.55 -2.53 -1.55 -2.53 0.2 21 29 | DS -1.55 -2.53 -1.55 0 0.2 21 30 | $PAD 31 | Po 0 0 32 | Sh "1" R 1.1 1.1 0 0 900 33 | Dr 0.7 0 0 34 | At STD N 00E0FFFF 35 | Ne 0 "" 36 | $EndPAD 37 | $PAD 38 | Po 0 2.54 39 | Sh "2" C 1.1 1.1 0 0 900 40 | Dr 0.7 0 0 41 | At STD N 00E0FFFF 42 | Ne 0 "" 43 | $EndPAD 44 | $PAD 45 | Po 0 5.08 46 | Sh "3" C 1.1 1.1 0 0 900 47 | Dr 0.7 0 0 48 | At STD N 00E0FFFF 49 | Ne 0 "" 50 | $EndPAD 51 | $PAD 52 | Po 0 7.62 53 | Sh "4" C 1.1 1.1 0 0 900 54 | Dr 0.7 0 0 55 | At STD N 00E0FFFF 56 | Ne 0 "" 57 | $EndPAD 58 | $PAD 59 | Po 0 10.16 60 | Sh "5" C 1.1 1.1 0 0 900 61 | Dr 0.7 0 0 62 | At STD N 00E0FFFF 63 | Ne 0 "" 64 | $EndPAD 65 | $PAD 66 | Po 0 12.7 67 | Sh "6" C 1.1 1.1 0 0 900 68 | Dr 0.7 0 0 69 | At STD N 00E0FFFF 70 | Ne 0 "" 71 | $EndPAD 72 | $PAD 73 | Po 0 15.24 74 | Sh "7" C 1.1 1.1 0 0 900 75 | Dr 0.7 0 0 76 | At STD N 00E0FFFF 77 | Ne 0 "" 78 | $EndPAD 79 | $PAD 80 | Po 0 17.78 81 | Sh "8" C 1.1 1.1 0 0 900 82 | Dr 0.7 0 0 83 | At STD N 00E0FFFF 84 | Ne 0 "" 85 | $EndPAD 86 | $PAD 87 | Po 0 20.32 88 | Sh "9" C 1.1 1.1 0 0 900 89 | Dr 0.7 0 0 90 | At STD N 00E0FFFF 91 | Ne 0 "" 92 | $EndPAD 93 | $PAD 94 | Po 0 22.86 95 | Sh "10" C 1.1 1.1 0 0 900 96 | Dr 0.7 0 0 97 | At STD N 00E0FFFF 98 | Ne 0 "" 99 | $EndPAD 100 | $PAD 101 | Po 0 25.4 102 | Sh "11" C 1.1 1.1 0 0 900 103 | Dr 0.7 0 0 104 | At STD N 00E0FFFF 105 | Ne 0 "" 106 | $EndPAD 107 | $PAD 108 | Po 0 27.94 109 | Sh "12" C 1.1 1.1 0 0 900 110 | Dr 0.7 0 0 111 | At STD N 00E0FFFF 112 | Ne 0 "" 113 | $EndPAD 114 | $PAD 115 | Po 15 27.94 116 | Sh "13" C 1.1 1.1 0 0 900 117 | Dr 0.7 0 0 118 | At STD N 00E0FFFF 119 | Ne 0 "" 120 | $EndPAD 121 | $PAD 122 | Po 15 25.4 123 | Sh "14" C 1.1 1.1 0 0 900 124 | Dr 0.7 0 0 125 | At STD N 00E0FFFF 126 | Ne 0 "" 127 | $EndPAD 128 | $PAD 129 | Po 15 22.86 130 | Sh "15" C 1.1 1.1 0 0 900 131 | Dr 0.7 0 0 132 | At STD N 00E0FFFF 133 | Ne 0 "" 134 | $EndPAD 135 | $PAD 136 | Po 15 20.32 137 | Sh "16" C 1.1 1.1 0 0 900 138 | Dr 0.7 0 0 139 | At STD N 00E0FFFF 140 | Ne 0 "" 141 | $EndPAD 142 | $PAD 143 | Po 15 17.78 144 | Sh "17" C 1.1 1.1 0 0 900 145 | Dr 0.7 0 0 146 | At STD N 00E0FFFF 147 | Ne 0 "" 148 | $EndPAD 149 | $PAD 150 | Po 15 15.24 151 | Sh "18" C 1.1 1.1 0 0 900 152 | Dr 0.7 0 0 153 | At STD N 00E0FFFF 154 | Ne 0 "" 155 | $EndPAD 156 | $PAD 157 | Po 15 12.7 158 | Sh "19" C 1.1 1.1 0 0 900 159 | Dr 0.7 0 0 160 | At STD N 00E0FFFF 161 | Ne 0 "" 162 | $EndPAD 163 | $PAD 164 | Po 15 10.16 165 | Sh "20" C 1.1 1.1 0 0 900 166 | Dr 0.7 0 0 167 | At STD N 00E0FFFF 168 | Ne 0 "" 169 | $EndPAD 170 | $PAD 171 | Po 15 7.62 172 | Sh "21" C 1.1 1.1 0 0 900 173 | Dr 0.7 0 0 174 | At STD N 00E0FFFF 175 | Ne 0 "" 176 | $EndPAD 177 | $PAD 178 | Po 15 5.08 179 | Sh "22" C 1.1 1.1 0 0 900 180 | Dr 0.7 0 0 181 | At STD N 00E0FFFF 182 | Ne 0 "" 183 | $EndPAD 184 | $PAD 185 | Po 15 2.54 186 | Sh "23" C 1.1 1.1 0 0 900 187 | Dr 0.7 0 0 188 | At STD N 00E0FFFF 189 | Ne 0 "" 190 | $EndPAD 191 | $PAD 192 | Po 15 0 193 | Sh "24" C 1.1 1.1 0 0 900 194 | Dr 0.7 0 0 195 | At STD N 00E0FFFF 196 | Ne 0 "" 197 | $EndPAD 198 | $EndMODULE DIPS1500W50P254L3300H1050Q24N 199 | $EndLIBRARY 200 | -------------------------------------------------------------------------------- /Schematic/schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoctorWkt/CSCvon8/62e8523368484713b54729f690976b1ae9b1f3cf/Schematic/schematic.pdf -------------------------------------------------------------------------------- /clc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | use Data::Dumper; 5 | 6 | # A very rudimentary compiler for a 7 | # high-ish level language down to 8 | # the CSCvon8 CPU assembly language. 9 | # (c) 2017 Warren Toomey, GPL3. 10 | 11 | my $OUT; 12 | 13 | # Stack of instructions to emit at the end of each if or loop 14 | # Each entry is a 3-element list: type, code and end loop label. 15 | # End loop label is undef for if statements. First element 16 | # is "LOOP", "IF", "FUNC". 17 | my @Loopstack; 18 | 19 | # Function variables: name of current function or undef 20 | my $funcname; 21 | 22 | # Name of defined functions 23 | my %Function; 24 | 25 | # Name of function's parameters 26 | my %Funcparam; 27 | 28 | # Get a new jump label 29 | my $nextlabel = 0; 30 | 31 | sub newlabel { 32 | return ( "L" . $nextlabel++ ); 33 | } 34 | 35 | my $varlocn = 0x8000; # Next location to use for variables 36 | my %Var; # List of known variables 37 | 38 | # Allocate space for a new variable. Prepend the current function name 39 | sub addvar { 40 | my $var = shift; 41 | $var = $funcname . "." . $var; 42 | 43 | die("$var previously defined\n") if ( defined( $Var{$var} ) ); 44 | printf( $OUT "%s:\tEQU \$%02x\n", $var, $varlocn++ ); 45 | $Var{$var} = 1; 46 | } 47 | 48 | # Check if a variable exists. Die if 2nd argument is true 49 | # Return the full variable name or undef 50 | sub checkvar { 51 | my ( $var, $stop ) = @_; 52 | $var = $funcname . "." . $var; 53 | 54 | if ( !defined( $Var{$var} ) ) { 55 | die("$var does not exist\n") if ($stop); 56 | return (undef); 57 | } 58 | return ($var); 59 | } 60 | 61 | # Emit an operation with two operands 62 | sub emit_twoop_operation { 63 | my ( $lvar, $var1, $op, $var2 ) = @_; 64 | 65 | # Work out the lvar name 66 | if ($lvar ne '') { 67 | $lvar = checkvar( $lvar, 1 ); 68 | } 69 | 70 | # Load either a constant or a value at a label 71 | if ($var1=~ m{^-?\d+$}) { 72 | printf( $OUT "\tLCA \$%02x\t\t\t# $lvar = $var1 $op $var2\n", $var1 & 0xff); 73 | } else { 74 | $var1 = checkvar( $var1, 1 ); 75 | printf( $OUT "\tLDA %s\t\t\t# $lvar = $var1 $op $var2\n", $var1); 76 | } 77 | if ($var2=~ m{^-?\d+$}) { 78 | printf( $OUT "\tLCB \$%02x\n", $var2 & 0xff); 79 | } else { 80 | $var2 = checkvar( $var2, 1 ); 81 | printf( $OUT "\tLDB %s\n", $var2); 82 | } 83 | printf( $OUT "\tLDA A%sB\n", $op); 84 | printf( $OUT "\tSTO A $lvar\n"); 85 | } 86 | 87 | # Emit a comparison. Use the hash to convert the op to the 88 | # matching instruction 89 | my %CvtOp= ( 90 | '==' => 'JEQ', 91 | '!=' => 'JNE', 92 | '>' => 'JGT', 93 | '<' => 'JLT', 94 | '>=' => 'JGE', 95 | '<=' => 'JLE' 96 | ); 97 | sub emit_comparison { 98 | my ( $startlabel, $var1, $op, $var2, $endlabel ) = @_; 99 | $var1 = checkvar( $var1, 1 ); 100 | printf( $OUT "$startlabel:\t\t\t# $var1 $op $var2\n" ); 101 | printf( $OUT "\tLDA %s\n", $var1); 102 | if ($var2=~ m{^-?\d+$}) { 103 | printf( $OUT "\tLCB \$%02x\n", $var2 & 0xff); 104 | } else { 105 | $var2 = checkvar( $var2, 1 ); 106 | printf( $OUT "\tLDB %s\n", $var2); 107 | } 108 | printf( $OUT "\t%s $endlabel\n", $CvtOp{$op}); 109 | } 110 | 111 | # Deal with the end of a function 112 | sub end_function { 113 | printf( $OUT "\tRTS $funcname\t\t# return\n"); 114 | $funcname= undef; 115 | } 116 | 117 | # Emit code for a function call 118 | sub do_function_call { 119 | my ( $name, $argument, $lvar ) = @_; 120 | die("function $name not previously declared\n") 121 | if ( !exists( $Function{$name} ) ); 122 | print( $OUT "\t\t\t# Call $name\n" ); 123 | 124 | # If there is an argument, copy it into the function 125 | if ( defined($argument) && ( $argument ne "" ) ) { 126 | die("function $name has no argument\n") 127 | if ( $Funcparam{$name} eq "" ); 128 | $argument = checkvar( $argument, 1 ); 129 | print( $OUT "\tLDA $argument\n" ); 130 | print( $OUT "\tSTO A $Funcparam{$name}\n" ); 131 | } 132 | 133 | # Print out the call 134 | print( $OUT "\tJSR $name\n" ); 135 | 136 | # If we have an lvar, copy from the param back to the lvar 137 | if ( defined($lvar) ) { 138 | print( $OUT "\tLDA $Funcparam{$name}\n" ); 139 | print( $OUT "\tSTO A $lvar\n" ); 140 | } 141 | } 142 | 143 | #### MAIN PROGRAM #### 144 | die("Usage: $0 file.cl\n") if ( @ARGV != 1 ); 145 | my $outfile = $ARGV[0]; 146 | $outfile =~ s{cl$}{s}; 147 | die("output file name same as input file $outfile\n") 148 | if ( $outfile eq $ARGV[0] ); 149 | 150 | open( $OUT, ">", $outfile ) || die("Cannot write $outfile: $!\n"); 151 | open( my $IN, "<", $ARGV[0] ) || die("Cannot open $ARGV[0]: $!\n"); 152 | print( $OUT "\tJSR main\n" ); # Initial function call 153 | print( $OUT "end:\tJMP \$FFFF\n" ); 154 | while (<$IN>) { 155 | chomp; 156 | 157 | # Lose comments 158 | s{\s*//.*}{}; 159 | 160 | # Skip empty lines; 161 | next if (m{^$}); 162 | 163 | # Variable declaration 164 | if (m{var\s+(\S+)\s*;}) { 165 | my $var = $1; 166 | addvar($var); 167 | next; 168 | } 169 | 170 | # Two operand operation 171 | if (m{(\S+)\s*=\s*(\S+)\s*(\+|\-|\&|\||\^)\s*(\S+)\s*;}) { 172 | my ( $lvar, $var1, $op, $var2 ) = ( $1, $2, $3, $4 ); 173 | emit_twoop_operation( $lvar, $var1, $op, $var2 ); 174 | next; 175 | } 176 | 177 | # While loop/If statement 178 | if (m{(if|while)\s*\(\s*(\S+)\s+(\S+)\s+(\S+)\s*\)\s*\{}) { 179 | my ( $keyword, $var1, $op, $var2 ) = ( $1, $2, $3, $4 ); 180 | 181 | # Get a start label and an end label 182 | my $startlabel = newlabel(); 183 | my $endlabel = newlabel(); 184 | if ( $keyword eq "while" ) { 185 | push( @Loopstack, 186 | [ "LOOP", "\tJMP $startlabel\n$endlabel:\n", $endlabel ] ); 187 | } else { 188 | push( @Loopstack, [ "IF", "$endlabel:\n", undef ] ); 189 | } 190 | 191 | if ( $op eq "==" ) { 192 | emit_comparison( $startlabel, $var1, "!=", $var2, $endlabel); 193 | } 194 | if ( $op eq "!=" ) { 195 | emit_comparison( $startlabel, $var1, "==", $var2, $endlabel); 196 | } 197 | if ( $op eq "<" ) { 198 | emit_comparison( $startlabel, $var1, ">=", $var2, $endlabel); 199 | } 200 | if ( $op eq ">=" ) { 201 | emit_comparison( $startlabel, $var1, "<", $var2, $endlabel); 202 | } 203 | if ( $op eq ">" ) { 204 | emit_comparison( $startlabel, $var1, "<=", $var2, $endlabel); 205 | } 206 | if ( $op eq "<=" ) { 207 | emit_comparison( $startlabel, $var1, ">", $var2, $endlabel); 208 | } 209 | next; 210 | } 211 | 212 | # Else statement 213 | if (m{\}\s*else\s*\{}) { 214 | my $endlabel = newlabel(); 215 | my $aryref = pop(@Loopstack); 216 | die("Unbalanced else\n") if ( !defined($aryref) ); 217 | my ( $type, $line, $orignendlabel ) = @{$aryref}; 218 | die("else not after if\n") if ( $type ne "IF" ); 219 | push( @Loopstack, [ "IF", "$endlabel:\n", undef ] ); 220 | print( $OUT "\tJMP $endlabel\t\t# Just before else\n" ); 221 | print( $OUT $line ); 222 | next; 223 | } 224 | 225 | # while (1) statement 226 | if (m{while\s*\(\s*1\s*\)\s*\{}) { 227 | 228 | # Get a start label and an end label 229 | my $startlabel = newlabel(); 230 | my $endlabel = newlabel(); 231 | push( @Loopstack, 232 | [ "LOOP", "\tJMP $startlabel\n$endlabel:\n", $endlabel ] ); 233 | printf( $OUT "$startlabel:\t\t\t# while (1)\n" ); 234 | next; 235 | } 236 | 237 | # End of an if, loop or function 238 | if (m{\}}) { 239 | my $aryref = pop(@Loopstack); 240 | die("Unbalanced }\n") if ( !defined($aryref) ); 241 | my ( $type, $line, $orignendlabel ) = @{$aryref}; 242 | die("Unbalanced }\n") if ( !defined($type) ); 243 | 244 | if ( $type eq "FUNC" ) { 245 | end_function(); 246 | next; 247 | } 248 | 249 | # Otherwise an if or loop end 250 | print( $OUT $line ); 251 | next; 252 | } 253 | 254 | # putchar 255 | if (m{putchar\((.+)\);}) { 256 | my $origarg = $1; 257 | my $arg = checkvar( $origarg, 0 ); 258 | if ( defined($arg) ) { 259 | printf( $OUT "\tLDA %s\t\t# putchar $arg\n", $arg ); 260 | printf( $OUT "\tOUT A\n" ); 261 | printf( $OUT "\tJOU .\n"); 262 | } else { 263 | $arg= undef; 264 | $arg = 10 if ( $origarg eq "'\\n'" ); 265 | $arg = ord($1) if ( $origarg =~ m{'(.)'} ); 266 | die("Unrecognised putchar argument $origarg\n") 267 | if (!defined($arg)); 268 | printf( $OUT "\tLCA \$%02x\t\t# putchar $arg\n", $arg ); 269 | printf( $OUT "\tOUT A\n" ); 270 | printf( $OUT "\tJOU .\n"); 271 | } 272 | next; 273 | } 274 | 275 | # prhex(n): Lots of instructions to do this, sigh 276 | if (m{prhex(n?)\((.+)\);}) { 277 | my ($n, $arg)= ($1, $2); 278 | $arg = checkvar( $arg, 1 ); 279 | 280 | # Get new labels 281 | my $l1= newlabel(); 282 | my $l2= newlabel(); 283 | printf( $OUT "\tLDA %s\t\t# prhex$n $arg high nibble\n", $arg); 284 | printf( $OUT "\tLCB \$04\n"); 285 | printf( $OUT "\tLDA A>>B\n"); 286 | printf( $OUT "\tLCB \$09\n"); 287 | printf( $OUT "\tJGT $l1\n"); 288 | printf( $OUT "\tLCB \$30\n"); 289 | printf( $OUT "\tJMP $l2\n"); 290 | printf( $OUT "$l1:\tLCB \$37\n"); 291 | printf( $OUT "$l2:\tLDA A+B\n"); 292 | printf( $OUT "\tOUT A\n"); 293 | printf( $OUT "\tJOU .\n"); 294 | 295 | # Get new labels 296 | $l1= newlabel(); 297 | $l2= newlabel(); 298 | printf( $OUT "\tLDA %s\t\t# prhex$n $arg low nibble\n", $arg); 299 | printf( $OUT "\tLCB \$0F\n"); 300 | printf( $OUT "\tLDA A&B\n"); 301 | printf( $OUT "\tLCB \$09\n"); 302 | printf( $OUT "\tJGT $l1\n"); 303 | printf( $OUT "\tLCB \$30\n"); 304 | printf( $OUT "\tJMP $l2\n"); 305 | printf( $OUT "$l1:\tLCB \$37\n"); 306 | printf( $OUT "$l2:\tLDA A+B\n"); 307 | printf( $OUT "\tOUT A\n"); 308 | printf( $OUT "\tJOU .\n"); 309 | if ($n eq 'n') { 310 | printf( $OUT "\tLCA \$0A\n"); 311 | printf( $OUT "\tOUT A\n"); 312 | printf( $OUT "\tJOU .\n"); 313 | } 314 | next; 315 | } 316 | 317 | # Postincrement 318 | if (m{(\S+)\+\+;}) { 319 | my $var1 = $1; 320 | $var1 = checkvar( $var1, 1 ); 321 | printf( $OUT "\tLDA %s\n", $var1 ); 322 | printf( $OUT "\tLDA A+1\n" ); 323 | printf( $OUT "\tSTO A %s\n", $var1 ); 324 | next; 325 | } 326 | 327 | # Arithmetic shift right 328 | if (m{(\S+)\s*=\s*(\S+)\s*>>\s*(\S+);}) { 329 | my ( $lvar, $var1, $var2 ) = ( $1, $2, $3 ); 330 | $lvar = checkvar( $lvar, 1 ); 331 | $var1 = checkvar( $var1, 1 ); 332 | printf( $OUT "\tLDA %s\t\t# %s= %s >> %s\n", $var1, $lvar, $var1, $var2); 333 | if ($var2=~ m{^-?\d+$}) { 334 | printf( $OUT "\tLCB \$%02x\n", $var2 & 0xff); 335 | } else { 336 | $var2 = checkvar( $var2, 1 ); 337 | printf( $OUT "\tLDB %s\n", $var2); 338 | } 339 | printf( $OUT "\tLDA A>>BA\n" ); 340 | printf( $OUT "\tSTO A %s\n", $lvar ); 341 | next; 342 | } 343 | 344 | # break 345 | if (m{break;}) { 346 | 347 | # Get the length of the @Loopstack -1, to get highest index 348 | my $i = @Loopstack - 1; 349 | my $found = 0; 350 | while ( $i >= 0 ) { 351 | my $aryref = $Loopstack[ $i-- ]; 352 | die("No matching loop end for break\n") if ( !defined($aryref) ); 353 | my ( $type, $line, $orignendlabel ) = @{$aryref}; 354 | if ( $type eq "LOOP" ) { 355 | printf( $OUT "\tJMP %s\t\t# break\n", $orignendlabel ); 356 | $found = 1; 357 | last; 358 | } 359 | } 360 | die("No matching loop end for break\n") if ( !$found ); 361 | next; 362 | } 363 | 364 | # Exit: inifinite loop 365 | if (m{exit;}) { 366 | print( $OUT "end:\tJMP \$FFFF\n" ); 367 | next; 368 | } 369 | 370 | # Function declaration: function name (param) { 371 | if (m{function\s+(\S+)\s*\((\S*)\)\s*\{}) { 372 | my $name = $1; 373 | my $param = $2; 374 | die("Can't declare function $name inside $funcname\n") 375 | if ( defined($funcname) ); 376 | $funcname = $name; 377 | $Function{$name}= 1; 378 | die("function $name previously declared\n") 379 | if ( exists( $Funcparam{$name} ) ); 380 | print( $OUT "\n$name:\n" ); 381 | if ( defined($param) && ( $param ne "" ) ) { 382 | addvar($param); 383 | $param = checkvar( $param, 1 ); 384 | $Funcparam{$name} = $param; 385 | } 386 | push( @Loopstack, ["FUNC"] ); 387 | next; 388 | } 389 | 390 | # Return with return value. Use the param as return location 391 | if (m{return\((\S+)\);}) { 392 | my $retvar = $1; 393 | $retvar = checkvar( $retvar, 1 ); 394 | printf( $OUT "\tLDA %s\t\t# Return $retvar\n", $retvar ); 395 | printf( $OUT "\tSTO A %s\n", $Funcparam{$funcname} ); 396 | printf( $OUT "\tRTS $funcname\n"); 397 | next; 398 | } 399 | 400 | # Function call with optional argument and assignment 401 | if (m{(\S+)=\s*(\S+)\s*\((\S*)\)\s*;}) { 402 | my $name = $2; 403 | my $argument = $3; 404 | my $lvar = $1; 405 | $lvar = checkvar( $lvar, 1 ); 406 | do_function_call( $name, $argument, $lvar ); 407 | next; 408 | } 409 | 410 | # Function call with optional argument and no assignment 411 | if (m{(\S+)\s*\((\S*)\)\s*;}) { 412 | my $name = $1; 413 | my $argument = $2; 414 | do_function_call( $name, $argument ); 415 | next; 416 | } 417 | 418 | # Constant assignment 419 | if (m{(\S+)\s*=\s*(\S+)\s*;}) { 420 | my ( $var, $val ) = ( $1, $2 ); 421 | $var = checkvar( $var, 1 ); 422 | 423 | # If the value is a constant 424 | if ($val=~ m{^-?\d+$}) { 425 | printf( $OUT "\tLCA \$%02x\t\t\t# $var = $val\n", $val & 0xff); 426 | } else { 427 | # See if the val is a variable 428 | my $rhsvar= checkvar( $val, 1); 429 | printf( $OUT "\tLDA %s\t\t\t# $var = $val\n", $rhsvar); 430 | } 431 | printf( $OUT "\tSTO A %s\n", $var); 432 | next; 433 | } 434 | 435 | # Return and no return value 436 | if (m{return;}) { 437 | printf( $OUT "\tRTS $funcname\t\t# return\n"); 438 | next; 439 | } 440 | 441 | die("Unrecognised line: $_\n"); 442 | } 443 | 444 | die("No main function defined\n") if (!defined($Function{"main"})); 445 | close($IN); 446 | close($OUT); 447 | exit(0); 448 | -------------------------------------------------------------------------------- /csim: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | use Data::Dumper; 5 | use Term::ReadKey; 6 | use IO::Pty; 7 | use Storable; 8 | 9 | # CSCVon8 Simulator, (C) 2019 Warren Toomey, GPL3 10 | 11 | my @RAM= (0) x 32768; 12 | my @ROM; 13 | my $ALUROM; 14 | my @DecodeROM; 15 | my $debug=0; 16 | my $PC=0; 17 | my $A=0; 18 | my $B=0; 19 | my $AH=0; 20 | my $AL=0; 21 | my $IR=0; 22 | my $phase=0; 23 | 24 | my $aluop; 25 | my $loadop; 26 | my $dbusop; 27 | my $jumpop; 28 | my $arena; 29 | my $pcincr; 30 | my $usreset; 31 | 32 | # The 1-char buffer from the keyboard. undefined means no character. 33 | my $inchar; 34 | 35 | # By default, UART I/O goes to STDIN/OUT 36 | my $IN= *STDIN; 37 | my $OUT= *STDOUT; 38 | 39 | # List of control line masks and shifts. 40 | use constant { 41 | ALUOP => 0x001f, 42 | LOADOP => 0x0007, LOADSHIFT => 5, 43 | DBUSOP => 0x0003, DBUSSHIFT => 8, 44 | JUMPOP => 0x0007, JUMPSHIFT => 10, 45 | ARENA => 0x0001, ARSHIFT => 13, # Active low 46 | PCINCR => 0x0001, PCSHIFT => 14, 47 | USRESET => 0x0001, USSHIFT => 15, # Active low 48 | IRSHIFT => 4, 49 | CSHIFT => 8, 50 | VSHIFT => 9, 51 | ZSHIFT => 10, 52 | NSHIFT => 11, 53 | DSHIFT => 12, 54 | MEMRESULT => 0, 55 | ALURESULT => 1, 56 | UARTRESULT => 2, 57 | }; 58 | 59 | # List of ALUop names 60 | my @ALUop = ( 61 | "0", 62 | "A", 63 | "B", 64 | "-A", 65 | "-B", 66 | "A+1", 67 | "B+1", 68 | "A-1", 69 | "B-1", 70 | "A+B", 71 | "A+B+1", 72 | "A-B", 73 | "A-Bspecial", 74 | "B-A", 75 | "A-B-1", 76 | "B-A-1", 77 | "A*BHI", 78 | "A*BLO", 79 | "A/B", 80 | "A%B", 81 | "A<>BL", 83 | "A>>BA", 84 | "AROLB", 85 | "ARORB", 86 | "A&B", 87 | "A|B", 88 | "A^B", 89 | "!A", 90 | "!B", 91 | "A+BCD", 92 | "A-BCD" 93 | ); 94 | 95 | # Enable debugging, pty I/O and randomised memory 96 | while (@ARGV > 0) { 97 | # Set debug mode 98 | if ($ARGV[0] eq "-d") { $debug++; shift(@ARGV); next; } 99 | 100 | # Open up a pty 101 | if ($ARGV[0] eq "-p") { 102 | $OUT = new IO::Pty; $IN= $OUT; 103 | print("pty is ", $OUT->ttyname(), "\n"); 104 | shift(@ARGV); next; 105 | } 106 | 107 | # Randomise the RAM 108 | if ($ARGV[0] eq "-r") { 109 | foreach my $i (0 .. 32767) { 110 | $RAM[$i]= int(rand(256)); 111 | } 112 | shift(@ARGV); next; 113 | } 114 | die("Usage: $0 [-d] [-p] [-r]\n-d: debug, -r: randomise RAM, -p: open pty\n"); 115 | } 116 | 117 | # Set the UART up to read one char at a time 118 | ReadMode('cbreak', $IN); 119 | 120 | # Load the ALU ROM 121 | my $ROMIN; 122 | if (-f "alu.hex") { 123 | $ALUROM = retrieve("alu.hex"); 124 | } else { 125 | # Load the ROM file and store a cached version 126 | open( $ROMIN, "<", "alu.rom" ) || die("Can't open alu.rom: $!\n"); 127 | while (<$ROMIN>) { 128 | chomp; push( @{ $ALUROM }, map( { hex($_) } split( /\s/, $_ ) ) ); 129 | } 130 | close($ROMIN); 131 | store($ALUROM, "alu.hex"); 132 | } 133 | 134 | # Load the Decode ROM 135 | open( $ROMIN, "<", "ucode.rom" ) || die("Can't open ucode.rom: $!\n"); 136 | while (<$ROMIN>) { 137 | chomp; push( @DecodeROM, map( { hex($_) } split( /\s+/, $_ ) ) ); 138 | } 139 | close($ROMIN); 140 | 141 | # Load the instruction ROM 142 | open( $ROMIN, "<", "instr.rom" ) || die("Can't open instr.rom: $!\n"); 143 | while (<$ROMIN>) { 144 | chomp; push( @ROM, map( { hex($_) } split( /\s+/, $_ ) ) ); 145 | } 146 | close($ROMIN); 147 | 148 | # Start the simulation 149 | while (1) { 150 | # Work out the decode ROM index 151 | my $decodeidx= ($IR << IRSHIFT) | $phase; 152 | 153 | # Get the microinstruction 154 | my $uinst= $DecodeROM[ $decodeidx ]; 155 | 156 | # Decode the microinstruction 157 | $aluop= $uinst & ALUOP; 158 | $loadop= ($uinst>>LOADSHIFT) & LOADOP; 159 | $dbusop= ($uinst>>DBUSSHIFT) & DBUSOP; 160 | $jumpop= ($uinst>>JUMPSHIFT) & JUMPOP; 161 | $arena= ($uinst>>ARSHIFT) & ARENA; 162 | $pcincr= ($uinst>>PCSHIFT) & PCINCR; 163 | $usreset= ($uinst>>USSHIFT) & USRESET; 164 | printf("PC %04x IR %02x p %01x ui %04x upa %d%d%d ", $PC, 165 | $IR, $phase, $uinst, $usreset, $pcincr, $arena) if ($debug); 166 | 167 | # Do the ALU operation. 168 | my $databus=0; 169 | my ($carry, $overflow, $zero, $negative, $divbyzero); 170 | if ($dbusop== ALURESULT) { 171 | my $aluresult= $ALUROM->[ ($aluop<<16) | ($A<<8) | $B ]; 172 | printf("AB %02x %02x %s %04x ", $A, $B, $ALUop[$aluop], $aluresult) 173 | if ($debug); 174 | 175 | # Extract the flags from the result, and remove from the result 176 | $carry= ($aluresult>>CSHIFT) & 1; 177 | $overflow= ($aluresult>>VSHIFT) & 1; 178 | $zero= ($aluresult>>ZSHIFT) & 1; 179 | $negative= ($aluresult>>NSHIFT) & 1; 180 | $divbyzero= ($aluresult>>DSHIFT) & 1; 181 | $databus = $aluresult & 0xff; 182 | } 183 | 184 | # Determine the address on the address bus: AR or PC 185 | my $address; 186 | if ($arena==0) { 187 | $address= ($AH<<8) | $AL; 188 | printf("AR %02x%02x ", $AH, $AL) if ($debug); 189 | } else { 190 | $address= $PC; 191 | printf("PC %04x ", $PC) if ($debug); 192 | } 193 | 194 | # Get the memory value 195 | if ($dbusop== MEMRESULT) { 196 | $databus= ($address & 0x8000) ? $RAM[$address-0x8000] : $ROM[$address]; 197 | } 198 | 199 | # Read from UART. Wait up to 0.5 seconds, 200 | # and if no character, "read" a NUL character. 201 | if ($dbusop== UARTRESULT) { 202 | # Return 0 if they were silly enough to read when nothing is there. 203 | # Empty the buffer regardless. 204 | $databus = defined($inchar) ? ord($inchar) : 0; 205 | 206 | # Only reset $inchar if there is a reader on the data bus. This 207 | # allows UARTRESULT to be asserted for several microinstructions 208 | # before the actual read is done. 209 | $inchar= undef if ($loadop); 210 | } 211 | printf("dop %x dbus %02x ", $dbusop, $databus) if ($debug); 212 | 213 | # Load from the data bus 214 | if ($loadop==1) { $IR= $databus; print("->IR ") if ($debug); } 215 | if ($loadop==2) { $A= $databus; print("->A ") if ($debug); } 216 | if ($loadop==3) { $B= $databus; print("->B ") if ($debug); } 217 | if ($loadop==4) { 218 | if ($address & 0x8000) { $RAM[$address-0x8000]= $databus; } 219 | print("->RAM ") if ($debug); 220 | } 221 | if ($loadop==5) { $AH= $databus; print("->AH ") if ($debug); } 222 | if ($loadop==6) { $AL= $databus; print("->AL ") if ($debug); } 223 | if ($loadop==7) { 224 | print($OUT chr($databus)); $|=1; # Flush the output 225 | print("->IO ") if ($debug); 226 | } 227 | 228 | # Increment the PC and the phase 229 | $PC++ if ($pcincr==1); 230 | $phase= ($usreset==0) ? 0 : ($phase+1) & 0xf; 231 | 232 | # Do any jumps 233 | printf("j%d ", $jumpop) if ($jumpop && $debug); 234 | if ($jumpop==1 && $carry) { 235 | $PC= $address; 236 | print("JC ") if ($debug); 237 | } 238 | if ($jumpop==2 && $overflow) { 239 | $PC= $address; 240 | print("JO ") if ($debug); 241 | } 242 | if ($jumpop==3 && $zero) { 243 | $PC= $address; 244 | print("JZ ") if ($debug); 245 | } 246 | if ($jumpop==4 && $negative) { 247 | $PC= $address; 248 | print("JN ") if ($debug); 249 | } 250 | if ($jumpop==5 && $divbyzero) { 251 | $PC= $address; 252 | print("JD ") if ($debug); 253 | } 254 | 255 | # If the instruction is testing for an available UART character to 256 | # read and we have one, don't jump. If not, try to read one and 257 | # jump if that fails. If we read one, put it in the $inchar buffer. 258 | if ($jumpop==7 && !defined($inchar)) { 259 | 260 | # This code if we are reading from a terminal 261 | if (-t $IN) { 262 | $inchar= ReadKey(0.5, $IN); 263 | } else { 264 | # This code for files and pipes 265 | $inchar= getc($IN); 266 | printf("File/pipe read %02x ", (defined($inchar) ? ord($inchar) : 0xff)) if ($debug); 267 | } 268 | 269 | # There was no character to read 270 | if (!defined($inchar)) { 271 | $PC= $address; print("JI ") if ($debug); 272 | } 273 | } 274 | 275 | # Exit if PC goes to $FFFF 276 | last if ($PC==0xffff); 277 | print("\n") if ($debug); 278 | } 279 | 280 | # Clean up and exit 281 | ReadMode('normal', $IN); 282 | exit(0); 283 | -------------------------------------------------------------------------------- /disasm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | use Data::Dumper; 5 | 6 | # CSCVon8 disassembler, (C) 2019 Warren Toomey, GPL3 7 | 8 | my %Inst; 9 | my @ROM; 10 | 11 | # Disassemble the instruction ROM filename on the cmd-line, 12 | # or instr.rom if not given. 13 | my $romfile= (@ARGV == 1) ? $ARGV[0] : "instr.rom"; 14 | 15 | open( my $IN, "<", "opcodes" ) || die("Cannot read opcodes: $!\n"); 16 | while (<$IN>) { 17 | chomp; 18 | my ($opcode, $oplen, $name)= split( m{\s+}, $_); 19 | $Inst{$opcode}= [ $name, $oplen ]; 20 | } 21 | close($IN); 22 | 23 | open($IN, "<", $romfile) || die("Cannot read $romfile: $!\n"); 24 | while (<$IN>) { 25 | chomp; push(@ROM, split(m{\s+}, $_)); 26 | } 27 | close($IN); 28 | 29 | #print(Dumper(\%Inst)); 30 | #print(Dumper(\@ROM)); 31 | 32 | my $i=0; 33 | while ($i < 0x7FFF) { 34 | my $suffix=""; 35 | my $inst= $ROM[$i]; 36 | printf("%04x: %02s ", $i, $inst); 37 | 38 | # Just print the byte if not a defined instruction 39 | if (!defined($Inst{$inst})) { 40 | print("\n"); $i++; next; 41 | } 42 | 43 | my ($name, $len)= @{ $Inst{$inst} }; 44 | 45 | # Lose the underscores 46 | $name=~ s{_}{ }g; 47 | 48 | # Find a suffix 49 | if ($name=~ m{(.*) (,[AB]$)}) { 50 | $suffix= $2; $name=$1; 51 | } 52 | 53 | print("$name "); 54 | printf("\$%02s", $ROM[$i+1]) if ($len==2); 55 | printf("\$%02s%02s", $ROM[$i+1], $ROM[$i+2]) if ($len==3); 56 | printf("\$%02s%02s/%02s", $ROM[$i+1], $ROM[$i+2], $ROM[$i+3]) if ($len==4); 57 | printf("\$%02s%02s \$%02s%02s", 58 | $ROM[$i+1], $ROM[$i+2], $ROM[$i+3], $ROM[$i+4]) if ($len==5); 59 | printf("\$%02s%02s \$%02s%02s \$%02s%02s", 60 | $ROM[$i+1], $ROM[$i+2], $ROM[$i+3], $ROM[$i+4], $ROM[$i+5], $ROM[$i+6]) 61 | if ($len==7); 62 | print("00$suffix") if ($suffix); 63 | print("\n"); 64 | $i += $len; 65 | } 66 | exit(0); 67 | 68 | -------------------------------------------------------------------------------- /gen_alu: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | use Data::Dumper; 5 | use Storable; 6 | 7 | # Script to generate the contents of the ALU ROM. 8 | # (C) 2019 Warren Toomey, GPL3 9 | # 10 | # The ROM takes these 21 bits of input. 11 | # - bit 20-16, the ALU operation 12 | # - bit 15-8, the A value 13 | # - bit 7-0, the B value 14 | # 15 | # There are 13 bits of output. 16 | # - bit 12, the divide-by-zero (D) bit, active high 17 | # - bit 11, the negative (N) bit, active high 18 | # - bit 10, the zero (Z) bit, active high 19 | # - bit 9, the overflow (V) bit, active high 20 | # - bit 8, the carry (C) bit, active high 21 | # - bit 7-0, the result 22 | # 23 | # All other output bits are unused and not wired up. 24 | 25 | use constant DIVFLAG => 0x1000; # The divide-by-zero flag 26 | use constant NEGFLAG => 0x0800; # The negative flag 27 | use constant ZEROFLAG => 0x0400; # The zero flag 28 | use constant OFLOWFLAG => 0x0200; # The overflow flag 29 | use constant CARRYFLAG => 0x0100; # The carry flag 30 | use constant CMASK => 0x01ff; # Mask to keep carry bit from Perl operation 31 | 32 | # Global variables to make writing the anonymous subs easier 33 | our ($A, $B, $result); # A and B inputs, and ALU result 34 | 35 | # The ROM contents to be generated 36 | my @ROM; 37 | 38 | # Lookup tables to convert BCD to 8-bit numbers and vice versa 39 | my @BCDtoNum; 40 | my @NumtoBCD; 41 | 42 | # Function to build the above two lookup tables 43 | sub init_bcd_tables { 44 | 45 | foreach my $i (0x00 .. 0xff) { 46 | 47 | # Firstly convert what might be two BCD digits to an 8-bit value. 48 | # Any BCD digit above 9 is treated as 0. 49 | my $topdigit= $i >> 4; 50 | my $botdigit= $i & 0xf; 51 | $topdigit=0 if ($topdigit > 9); 52 | $botdigit=0 if ($botdigit > 9); 53 | 54 | # Convert to an 8-bit value and store in the table 55 | $BCDtoNum[$i]= $topdigit * 10 + $botdigit; 56 | 57 | # Now do the opposite, take an 8-bit value and convert to two 58 | # BCD digits. Any 8-bit value above 99 is changed to 0. 59 | my $decimalnum= ($i>99) ? 0 : $i; 60 | $topdigit= int($decimalnum/10); 61 | $botdigit= $decimalnum%10; 62 | 63 | # Convert to two BCD nibbles and store in the table 64 | $NumtoBCD[$i]= ($topdigit<<4) + $botdigit; 65 | } 66 | } 67 | 68 | # Some operations are complicated enough that they are in their own subroutine. 69 | # Rotate $A to the left $B times. Slow but works. 70 | sub ROL { 71 | $result= $A; 72 | for (my $i=0; $i < $B; $i++) { 73 | my $msb= $result & 0x80; 74 | $result= ($result << 1) & 0xff; 75 | $result |= ($msb) ? 1 : 0; 76 | } 77 | } 78 | 79 | # Rotate $A to the right $B times. Slow but works. 80 | sub ROR { 81 | $result= $A; 82 | for (my $i=0; $i < $B; $i++) { 83 | my $lsb= $result & 0x1; 84 | $result= $result >> 1; 85 | $result |= ($lsb) ? 0x80 : 0; 86 | } 87 | } 88 | 89 | # Arithmetic shift $A to the right $B times. Slow but works. 90 | sub ASR { 91 | $result= $A; 92 | my $msb= $result & 0x80; 93 | for (my $i=0; $i < $B; $i++) { 94 | $result= $result >> 1; 95 | $result |= $msb; 96 | } 97 | } 98 | 99 | # Two digit BCD addition of $A and $B. 100 | # Any result >100 is reduced by 100 and carry set. 101 | # Result is also two BCD digits. 102 | sub BCD_ADD { 103 | # Convert both to 8-bit values 104 | my $a= $BCDtoNum[ $A ]; 105 | my $b= $BCDtoNum[ $B ]; 106 | 107 | my $c=0; 108 | $result= $a + $b; 109 | if ($result > 99) { 110 | $result -= 99; 111 | $c= CARRYFLAG; # This is active high at this point 112 | } 113 | $result= $NumtoBCD[ $result] + $c; 114 | } 115 | 116 | # Two digit BCD addition of $A and $B. 117 | # Any result <0 is incremented by 100 and carry set. 118 | # Result is also two BCD digits. 119 | sub BCD_SUB { 120 | # Convert both to 8-bit values 121 | my $a= $BCDtoNum[ $A ]; 122 | my $b= $BCDtoNum[ $B ]; 123 | 124 | my $c=0; 125 | $result= $a - $b; 126 | if ($result < 0) { 127 | $result += 99; 128 | $c= CARRYFLAG; # This is active high at this point 129 | } 130 | $result= $NumtoBCD[ $result] + $c; 131 | } 132 | 133 | # Array of subroutines, some anonymous, which calculate the result 134 | # given the A and B values 135 | my @Opsub= ( 136 | sub { $result= 0 }, # 0 137 | sub { $result= $A; }, # A 138 | sub { $result= $B; }, # B 139 | sub { $result= (-$A) & CMASK; }, # -A 140 | sub { $result= (-$B) & CMASK; }, # -B 141 | sub { $result= ($A+1) & CMASK; }, # A+1 142 | sub { $result= ($B+1) & CMASK; }, # B+1 143 | sub { $result= ($A-1) & CMASK; }, # A-1 144 | sub { $result= ($B-1) & CMASK; }, # B-1 145 | sub { $result= ($A+$B) & CMASK; }, # A+B 146 | sub { $result= ($A+$B+1) & CMASK; }, # A+B+1 147 | sub { $result= ($A-$B) & CMASK; }, # A-B 148 | sub { $result= ($A-$B) & CMASK; }, # A-B special, op 12 149 | sub { $result= ($B-$A) & CMASK; }, # B-A 150 | sub { $result= ($A-$B-1) & CMASK; }, # A-B-1 151 | sub { $result= ($B-$A-1) & CMASK; }, # B-A-1 152 | sub { $result= ($A*$B) & 0xff; }, # A*B, low bits 153 | sub { $result= ($A*$B) >> 8; }, # A*B, high bits 154 | sub { $result= ($B==0) ? 0 : int($A/$B); }, # A/B 155 | sub { $result= ($B==0) ? 0 : int($A%$B); }, # A%B 156 | sub { $result= ($A<<$B) & CMASK; }, # A<>$B; }, # A>>B logical 158 | \&ASR, # A>>B arithmetic 159 | \&ROL, # A ROL B 160 | \&ROR, # A ROR B, 161 | sub { $result= $A&$B; }, # A AND B 162 | sub { $result= $A|$B; }, # A OR B 163 | sub { $result= $A^$B; }, # A XOR B 164 | sub { $result= (~$A) & 0xff; }, # NOT A 165 | sub { $result= (~$B) & 0xff; }, # NOT B 166 | \&BCD_ADD, # BCD A + B 167 | \&BCD_SUB, # BCD A + B 168 | ); 169 | 170 | ### MAIN PROGRAM ### 171 | 172 | # Generate the BCD tables 173 | init_bcd_tables(); 174 | 175 | # Loop across all possible ALU inputs 176 | foreach my $aluop (0x00 .. 0x1f) { 177 | 178 | # Cache the ALU op subroutine and if it's a div or mod 179 | my $opsub= $Opsub[$aluop]; 180 | my $isdivmod = ($aluop==18 || $aluop==19) ? 1 : 0; 181 | 182 | foreach $A (0x00 .. 0xff) { 183 | 184 | # Cache A's sign 185 | my $asign= $A & 0x80; 186 | 187 | foreach $B (0x00 .. 0xff) { 188 | my $bsign= $B & 0x80; 189 | 190 | # Run the subroutine to calculate the result 191 | $opsub->(); 192 | my $rsign= $result & 0x80; 193 | 194 | # At this point we have an active high carry flag in bit 8 195 | # and an active high negative bit in bit 7 196 | 197 | # Add on any zero flag 198 | $result |= ZEROFLAG if (($result&0xff)==0); 199 | 200 | # Flip the zero bit for special ALUop 12 201 | $result ^= ZEROFLAG if ($aluop==12); 202 | 203 | # Add on any active low negative flag 204 | $result |= NEGFLAG if ($rsign); 205 | 206 | # If A's sign is the same as B's sign, and the 207 | # result sign is different, set the overflow flag 208 | $result |= OFLOWFLAG if (($asign==$bsign) && ($asign != $rsign)); 209 | 210 | # Put in the divide-by-zero flag if B is zero and we did a DIV or MOD 211 | $result |= DIVFLAG if ($isdivmod && $B==0); 212 | 213 | # Put the result into the ROM 214 | $ROM[ ($aluop<<16) | ($A<<8) | $B ] = $result; 215 | } 216 | } 217 | } 218 | 219 | # Write ROM out in hex for Verilog 220 | open( my $OUT, ">", "alu.rom" ) || die("Can't write to alu.rom: $!\n"); 221 | for my $i ( 0 .. ( 2**21 - 1 ) ) { 222 | printf( $OUT "%x ", $ROM[$i] ? $ROM[$i] : 0 ); 223 | print( $OUT "\n" ) if ( ( $i % 8 ) == 7 ); 224 | } 225 | close($OUT); 226 | 227 | # If there is a ROMs directory, also write out eight minipro binary ROM file, 228 | # each of which has little-endian 16-bit values. 229 | if (-d "ROMs") { 230 | my $offset= 0; 231 | my $lastposn= 2**18 - 1; 232 | foreach my $bank (0 .. 7) { 233 | open($OUT, '>:raw', "ROMs/alu$bank.rom") or die "Unable to open: $!"; 234 | for my $i ( $offset .. $lastposn ) { 235 | print($OUT pack("v", $ROM[$i] ? $ROM[$i] : 0 )); 236 | } 237 | close($OUT); 238 | $offset += 2**18; $lastposn += 2**18; 239 | } 240 | } 241 | 242 | exit(0); 243 | -------------------------------------------------------------------------------- /gen_ucode: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | use Data::Dumper; 5 | 6 | # CSCVon8 microcode generator, (C) 2019 Warren Toomey, GPL3 7 | # 8 | # Generate the ucode.rom from the microcode text file, 9 | # and create the opcodes file. Also generate a ROM file, 10 | # 27Cucode.rom which is ready to write to the read ROM 11 | # using minipro. 12 | 13 | # Hash of control lines and their values 14 | my %Cline; 15 | 16 | # Hash of control lines indicating which ones are low 17 | my %Cislow; 18 | 19 | # Hash of previously seen opcodes 20 | my %Opcode; 21 | 22 | # Bitmask to set all active low lines off 23 | my $lowoffmask=0; 24 | 25 | # The ROM to write out 26 | my @ROM; 27 | 28 | # The current instruction, name and microsequence position. 29 | # Also, the number of instructions bytes 30 | my $opcode=0; 31 | my $opname; 32 | my $seq=0; 33 | my $instrlen=0; 34 | 35 | # If set, this line is placed at position 0 in each microsequence 36 | my $startline; 37 | 38 | # Debug flag if needed. Current line number 39 | my $debug=0; 40 | my $linenum=0; 41 | 42 | # Given a string with space-separated control lines, parse each 43 | # word, and update the ROM with the microinstruction 44 | sub parse_lines { 45 | my ($input, $inscode, $insname)= @_; 46 | print("Parsing $input\n") if ($debug==2); 47 | 48 | # Start with all lines off 49 | my $result= $lowoffmask; 50 | 51 | foreach my $name (split(m{\s+}, $input)) { 52 | 53 | die("Unrecognised line $name on line $linenum\n") 54 | if (!defined($Cline{$name})); 55 | 56 | # Set the named line in the result 57 | printf(" %s: %04x => ", $name, $result) if ($debug==2); 58 | if ($Cislow{$name}) { 59 | $result ^= $Cline{$name}; 60 | } else { 61 | $result |= $Cline{$name}; 62 | } 63 | printf("%04x\n", $result) if ($debug==2); 64 | 65 | # Increment the instruction length if we have a PCincr 66 | $instrlen++ if ($name eq "PCincr"); 67 | print("len $instrlen as PCincr\n") if (($debug==2) && $name eq "PCincr"); 68 | } 69 | 70 | # Set the ROM for opcode/sequence with this value and 71 | # move to the next sequence position 72 | $ROM[ ($opcode << 4) | $seq ] = $result; $seq++; 73 | printf("%04x: %s\t\t%s %s\n", $result, $input, $inscode, $insname) 74 | if ($debug==1); 75 | } 76 | 77 | #### MAIN PROGRAM #### 78 | 79 | # Enable debugging 80 | while ( ( @ARGV >= 1 ) && ( $ARGV[0] ) eq "-d" ) { 81 | $debug++; 82 | shift(@ARGV); 83 | } 84 | 85 | # Overwrite the opcodes file 86 | open( my $OPOUT, ">", "opcodes" ) || die("Can't write to opcodes: $!\n"); 87 | 88 | open(my $IN, "<", "microcode") || die("Can't read microcode: $!\n"); 89 | while (<$IN>) { 90 | chomp; 91 | $linenum++; 92 | s{#.*}{}; # Lose comments 93 | s{^\s+}{}; # Lose leading whitespace 94 | s{\s+$}{}; # Lose trailing whitespace 95 | next if (m{^$}); # Ignore empty lines 96 | 97 | # Starting microinstruction in a microsequence 98 | if (m{:=\s*(.+)}) { 99 | $startline= $1; 100 | print("Got start line $startline\n") if ($debug==2); 101 | next; 102 | } 103 | 104 | # Control line definition 105 | if (m{^(\S+)\s*=\s*(\S+)}) { 106 | my ($name, $val)= ($1, $2); 107 | 108 | # Determine if it is active low 109 | # Update the low mask if it is 110 | my $islow=0; 111 | if ($name=~ m{^@(.*)}) { 112 | $name= $1; $islow=1; 113 | $lowoffmask |= hex($val); 114 | } 115 | 116 | die("Control line $name redefined on line $linenum\n") 117 | if (defined($Cline{$name})); 118 | $Cline{$name}= hex($val); 119 | $Cislow{$name}= $islow; next; 120 | } 121 | 122 | # First line in a microsequence 123 | if (m{^(\S+)\s+(\S+)\s*:\s*(.+)}) { 124 | 125 | # Get the new opcode number, name and list of control lines 126 | my $newopcode= $1; my $newopname= $2; my $linelist=$3; 127 | print("$newopcode $newopname:\n") if ($debug==2); 128 | die("Opcode $opcode redefined on line $linenum\n") 129 | if (defined($Opcode{$opcode})); 130 | 131 | # Print out the details of the last opcode 132 | printf($OPOUT "%02x %d %s\n", $opcode, $instrlen, $opname) if ($seq!=0); 133 | 134 | # Replace with the new information and reset the sequence 135 | $opcode= hex($newopcode); $opname= $newopname; $seq=0; $instrlen=0; 136 | 137 | # If there is a start line, parse it first 138 | parse_lines($startline, $newopcode, $newopname) if (defined($startline)); 139 | 140 | # Parse the control lines 141 | parse_lines($linelist, "", ""); next; 142 | } 143 | 144 | # If we get here, the line must just be a list of control lines. 145 | # Parse them 146 | parse_lines($_, "", ""); 147 | } 148 | close($IN); 149 | 150 | # Print out the details of the last opcode 151 | printf($OPOUT "%02x %d %s\n", $opcode, $instrlen, $opname) if ($seq!=0); 152 | close($OPOUT); 153 | 154 | # Find any instructions which were not defined and turn them into a NOP. 155 | # This assumes that instruction 00 is a NOP definition. 156 | my $irloadvalue= $ROM[0]; 157 | my $nopvalue= $ROM[1]; 158 | foreach my $i (0 .. 0xff) { 159 | if (!defined($ROM[ ($i << 4) ])) { 160 | $ROM[ ($i << 4) ] = $irloadvalue; 161 | $ROM[ ($i << 4) + 1 ] = $nopvalue; 162 | } 163 | } 164 | 165 | # Write the ROM out in hex 166 | open( my $OUT, ">", "ucode.rom" ) || die("Can't write to ucode.rom: $!\n"); 167 | for my $i ( 0 .. ( 2**12 - 1 ) ) { 168 | printf( $OUT "%x ", $ROM[$i] ? $ROM[$i] : 0 ); 169 | print( $OUT "\n" ) if ( ( $i % 16 ) == 15 ); 170 | } 171 | close($OUT); 172 | 173 | # Write the minipro binary ROM file, little-endian 16-bit values. 174 | # The ROM has 16 bits of addressing, so we have to write 2^16 values. 175 | open($OUT, '>:raw', '27Cucode.rom') or die "Unable to open: $!"; 176 | for my $i ( 0 .. ( 2**16 - 1 ) ) { 177 | print($OUT pack("v", $ROM[$i] ? $ROM[$i] : 0 )); 178 | } 179 | close($OUT); 180 | 181 | exit(0); 182 | -------------------------------------------------------------------------------- /icarus_tb.v: -------------------------------------------------------------------------------- 1 | // Testbed for the CSCvon8 CPU 2 | // (c) Warren Toomey, GPL3 3 | 4 | `timescale 1ns/1ps 5 | `default_nettype none 6 | `include "ttlcsvon8.v" 7 | 8 | module icarus_tb(); 9 | 10 | parameter AddressSize = 16; 11 | parameter WordSize = 8; 12 | parameter HalfClock = 230; // Half a clock cycle in nS 13 | 14 | reg clk= 0; 15 | reg reset= 0; 16 | reg [3:0] counter=0; 17 | wire [AddressSize-1:0] PCval; // Current PC value 18 | 19 | // Initialize all variables 20 | initial begin 21 | $dumpfile("test.vcd"); 22 | $dumpvars(0, icarus_tb); 23 | // #44000 $finish; // Terminate simulation 24 | end 25 | 26 | // Clock generator 27 | always begin 28 | #HalfClock clk = ~clk; // Toggle clk every HalfClock to make a full cycle 29 | end 30 | 31 | always @(posedge clk or negedge clk) begin 32 | if (counter > 4'h8) 33 | reset= 1; 34 | else 35 | counter <= counter + 1; 36 | end 37 | 38 | // Stop if we have jumped to location $FFFF 39 | always @(negedge clk) begin 40 | if (PCval == 16'hFFFF) begin 41 | $finish; 42 | end 43 | end 44 | 45 | // Connect DUT to test bench 46 | ttlcsvon8 DUT(clk, reset, PCval); 47 | 48 | endmodule 49 | -------------------------------------------------------------------------------- /opcodes: -------------------------------------------------------------------------------- 1 | 00 1 NOP 2 | 01 1 LDA_0 3 | 02 1 LDA_B 4 | 03 1 LDA_-A 5 | 04 1 LDA_-B 6 | 05 1 LDA_A+1 7 | 06 1 LDA_B+1 8 | 07 1 LDA_A-1 9 | 08 1 LDA_B-1 10 | 09 1 LDA_A+B 11 | 0a 1 LDA_A+B+1 12 | 0b 1 LDA_A-B 13 | 0d 1 LDA_B-A 14 | 0e 1 LDA_A-B-1 15 | 0f 1 LDA_B-A-1 16 | 10 1 LDA_A*BHI 17 | 11 1 LDA_A*B 18 | 12 1 LDA_A/B 19 | 13 1 LDA_A%B 20 | 14 1 LDA_A<>B 22 | 16 1 LDA_A>>BA 23 | 17 1 LDA_AROLB 24 | 18 1 LDA_ARORB 25 | 19 1 LDA_A&B 26 | 1a 1 LDA_A|B 27 | 1b 1 LDA_A^B 28 | 1c 1 LDA_!A 29 | 1d 1 LDA_!B 30 | 1e 1 LDA_A+BCD 31 | 1f 1 LDA_A-BCD 32 | 21 1 LDB_0 33 | 22 1 LDB_A 34 | 23 1 LDB_-A 35 | 24 1 LDB_-B 36 | 25 1 LDB_A+1 37 | 26 1 LDB_B+1 38 | 27 1 LDB_A-1 39 | 28 1 LDB_B-1 40 | 29 1 LDB_A+B 41 | 2a 1 LDB_A+B+1 42 | 2b 1 LDB_A-B 43 | 2d 1 LDB_B-A 44 | 2e 1 LDB_A-B-1 45 | 2f 1 LDB_B-A-1 46 | 30 1 LDB_A*BHI 47 | 31 1 LDB_A*B 48 | 32 1 LDB_A/B 49 | 33 1 LDB_A%B 50 | 34 1 LDB_A<>B 52 | 36 1 LDB_A>>BA 53 | 37 1 LDB_AROLB 54 | 38 1 LDB_ARORB 55 | 39 1 LDB_A&B 56 | 3a 1 LDB_A|B 57 | 3b 1 LDB_A^B 58 | 3c 1 LDB_!A 59 | 3d 1 LDB_!B 60 | 3e 1 LDB_A+BCD 61 | 3f 1 LDB_A-BCD 62 | 40 3 STO_0 63 | 41 3 STO_A 64 | 42 3 STO_B 65 | 43 3 STO_-A 66 | 44 3 STO_-B 67 | 45 3 STO_A+1 68 | 46 3 STO_B+1 69 | 47 3 STO_A-1 70 | 48 3 STO_B-1 71 | 49 3 STO_A+B 72 | 4a 3 STO_A+B+1 73 | 4b 3 STO_A-B 74 | 4d 3 STO_B-A 75 | 4e 3 STO_A-B-1 76 | 4f 3 STO_B-A-1 77 | 50 3 STO_A*BHI 78 | 51 3 STO_A*B 79 | 52 3 STO_A/B 80 | 53 3 STO_A%B 81 | 54 3 STO_A<>B 83 | 56 3 STO_A>>BA 84 | 57 3 STO_AROLB 85 | 58 3 STO_ARORB 86 | 59 3 STO_A&B 87 | 5a 3 STO_A|B 88 | 5b 3 STO_A^B 89 | 5c 3 STO_!A 90 | 5d 3 STO_!B 91 | 5e 3 STO_A+BCD 92 | 5f 3 STO_A-BCD 93 | 60 2 LCA 94 | 61 2 LCB 95 | 62 3 LDA 96 | 63 3 LDB 97 | 64 1 OUT_A 98 | 65 1 OUT_B 99 | 66 1 INA 100 | 67 1 INB 101 | 68 2 OUT 102 | 70 3 JMP 103 | 71 3 JEQ 104 | 72 3 JNE 105 | 73 3 JGT 106 | 74 3 JLT 107 | 75 3 JGE 108 | 76 3 JLE 109 | 77 3 JOU 110 | 78 3 JIU 111 | 79 3 JAZ 112 | 7a 3 JBZ 113 | 7b 3 JAN 114 | 7c 3 JBN 115 | 80 3 TST_A+B_JC 116 | 81 3 TST_A-B_JC 117 | 82 3 TST_B-A_JC 118 | 83 3 TST_A+1_JC 119 | 84 3 TST_B+1_JC 120 | 90 2 LDA_,B 121 | 91 2 LDB_,B 122 | 92 2 STO_A_,B 123 | 93 2 STO_B_,B 124 | 94 2 STO_0_,B 125 | e0 3 JLT8 126 | e1 3 JLT15 127 | e2 3 JLT12 128 | e3 3 JLE8 129 | e4 3 JLE15 130 | e5 3 JLE12 131 | e6 3 JGT8 132 | e7 3 JGT15 133 | e8 3 JGT12 134 | f0 7 JSR 135 | f1 3 RTS 136 | f2 3 LIA 137 | f3 3 LIB 138 | f4 4 SIA 139 | f5 4 SIB 140 | f6 5 PPR 141 | -------------------------------------------------------------------------------- /ram.v: -------------------------------------------------------------------------------- 1 | // RAM component 2 | // (c) 2019 Warren Toomey, GPL3 3 | 4 | module ram (Address, InData, CS_bar, WE_bar, OE_bar, OutData); 5 | 6 | parameter AddressSize = 16; 7 | parameter WordSize = 8; 8 | parameter Filename= "empty.ram"; 9 | parameter DELAY_RISE = 55; 10 | parameter DELAY_FALL = 55; 11 | 12 | input [AddressSize-1:0] Address; 13 | input [WordSize-1:0] InData; 14 | input CS_bar, WE_bar, OE_bar; 15 | output [WordSize-1:0] OutData; 16 | 17 | reg [WordSize-1:0] Mem [0:(1<