差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
nmpsm3软处理器 [2020/07/23 11:21] zili |
nmpsm3软处理器 [2020/07/23 14:06] (当前版本) zili |
||
---|---|---|---|
行 9: | 行 9: | ||
\\ | \\ | ||
+ | \\ | ||
#### NMPSM3屏幕截图 | #### NMPSM3屏幕截图 | ||
{{ :nmpsm3_palette_change.png |NMPSM3调色板更改示范}} | {{ :nmpsm3_palette_change.png |NMPSM3调色板更改示范}} | ||
行 20: | 行 21: | ||
\\ | \\ | ||
+ | \\ | ||
#### NMPSM3硬件 | #### NMPSM3硬件 | ||
+ | 与处理器一起,我还基于8位Nintendo构建了其他一些模块,包括UART和图片处理单元(PPU)。一些Verilog代码很粗糙,因为在创建此项目时我正在学习Verilog。\\ | ||
+ | |||
+ | ##### Final_Project.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module Final_Project( | ||
+ | input clk, | ||
+ | | ||
+ | input [15:0]sw, | ||
+ | | ||
+ | input btnC, | ||
+ | input btnU, | ||
+ | input btnD, | ||
+ | input btnL, | ||
+ | input btnR, | ||
+ | | ||
+ | input data, | ||
+ | | ||
+ | input RsRx, | ||
+ | output RsTx, | ||
+ | | ||
+ | output RxTest, | ||
+ | output TxTest, | ||
+ | | ||
+ | output [15:0]led, | ||
+ | | ||
+ | output [6:0]seg, | ||
+ | output [3:0]an, | ||
+ | output dp, | ||
+ | | ||
+ | output [3:0]vgaRed, | ||
+ | output [3:0]vgaGreen, | ||
+ | output [3:0]vgaBlue, | ||
+ | output Hsync, | ||
+ | output Vsync, | ||
+ | | ||
+ | output sclk, | ||
+ | output ce | ||
+ | ); | ||
+ | | ||
+ | //UART test ports. | ||
+ | assign RxTest = RsRx; | ||
+ | assign TxTest = RsTx; | ||
+ | | ||
+ | wire clk100MHz; | ||
+ | wire clk50MHz; | ||
+ | wire clk25MHz; | ||
+ | wire t0out; | ||
+ | wire t1out; | ||
+ | wire ack0; | ||
+ | wire ack1; | ||
+ | wire ack2; | ||
+ | wire ack3; | ||
+ | wire sigout0; | ||
+ | wire sigout1; | ||
+ | wire sigout2; | ||
+ | wire sigout3; | ||
+ | wire ce1k; | ||
+ | wire blink; | ||
+ | wire read; | ||
+ | wire write; | ||
+ | wire vblank; | ||
+ | wire reset; | ||
+ | wire [15:0]id; | ||
+ | wire [15:0]outdata; | ||
+ | wire [7:0]hour; | ||
+ | wire [7:0]min; | ||
+ | wire [7:0]sec; | ||
+ | wire [35:0]inst; | ||
+ | wire [15:0]in_port; | ||
+ | wire [15:0]address; | ||
+ | wire [7:0]romdata; | ||
+ | wire [11:0]mdout; | ||
+ | wire [7:0]vgadata; | ||
+ | wire [9:0]addr; | ||
+ | wire [10:0]romaddress; | ||
+ | wire [11:0]mdin; | ||
+ | | ||
+ | //UART wires. | ||
+ | wire [7:0]uartdata; | ||
+ | wire [11:0]txcount; | ||
+ | wire [11:0]rxcount; | ||
+ | | ||
+ | //Unused VGA bits in this design. | ||
+ | assign vgaRed[0] = 1'b0; | ||
+ | assign vgaGreen[0] = 1'b0; | ||
+ | assign vgaBlue[0] = 1'b0; | ||
+ | assign vgaBlue[1] = 1'b0; | ||
+ | | ||
+ | //Reset signal. | ||
+ | assign reset = btnU; | ||
+ | |||
+ | //Flip-flop for interrupt 0. | ||
+ | FF ff0(.set(t0out), .reset(ack0), .sigout(sigout0)); | ||
+ | |||
+ | //Flip-flop for interrupt 1. | ||
+ | FF ff1(.set(t1out), .reset(ack1), .sigout(sigout1)); | ||
+ | |||
+ | //Flip-flop for interrupt 2. | ||
+ | FF ff2(.set(vblank), .reset(ack2), .sigout(sigout2)); | ||
+ | |||
+ | //Flip-flop for interrupt 3(not used). | ||
+ | FF ff3(.set(1'b0), .reset(ack3), .sigout(sigout3)); | ||
+ | | ||
+ | //Divide by 100,000. | ||
+ | div100k divideBy100K(.clock(clk100MHz), .ce1k(ce1k)); | ||
+ | | ||
+ | //Clock divider. | ||
+ | clk25 c(.clk_in1(clk), .clk_out1(clk100MHz), .clk_out2(clk50MHz), .clk_out3(clk25MHz)); | ||
+ | | ||
+ | //NMPSM3 soft processor. | ||
+ | NMPSM3 nmpsm3(.clk(clk100MHz), .reset(reset), .IRQ0(sigout0), .IRQ1(sigout1), .IRQ2(sigout2), .IRQ3(sigout3), | ||
+ | .INSTRUCTION(inst), .IN_PORT(in_port), .READ_STROBE(read), .WRITE_STROBE(write), .IRQ_ACK0(ack0), | ||
+ | .IRQ_ACK1(ack1), .IRQ_ACK2(ack2), .IRQ_ACK3(ack3), .ADDRESS(address), .OUT_PORT(outdata), | ||
+ | .PORT_ID(id)); | ||
+ | | ||
+ | //Program ROM for NMPSM3. | ||
+ | Program_ROM prgROM(.clka(clk100MHz), .addra(address[9:0]), .douta(inst)); | ||
+ | | ||
+ | //Lookup ROM | ||
+ | Lookup_ROM lookuprom(.clka(clk100MHz), .addra(romaddress), .douta(romdata)); | ||
+ | | ||
+ | //UART | ||
+ | uart uart1(.clk(clk100MHz), .reset(reset), .id(id), .din(outdata), .write(write), .rx(RsRx), .tx(RsTx), | ||
+ | .dout(uartdata), .rxcount(rxcount), .txcount(txcount)); | ||
+ | | ||
+ | //LED output controller. | ||
+ | ledio LEDIO(.clk(clk100MHz), .reset(reset), .write(write), .id(id), .din(outdata), .ledsout(led[7:0])); | ||
+ | | ||
+ | //LED output controller 2. | ||
+ | LEDIO2 ledio2(.clk(clk100MHz), .reset(reset), .write(write), .id(id), .din(outdata), .ledsout(led[15:8])); | ||
+ | | ||
+ | //Seven segment controller. | ||
+ | seg7io seg7control(.clk(clk100MHz), .ce1k(ce1k), .write(write), .reset(reset), .id(id), .din(outdata), | ||
+ | .segselect(an), .segs({dp,seg})); | ||
+ | | ||
+ | //Timer 0. | ||
+ | timer0 time0(.clk(clk100MHz), .cein(ce1k), .write(write), .reset(reset), .id(id), .din(outdata), .dout(t0out)); | ||
+ | | ||
+ | //Timer 1. | ||
+ | timer1 time1(.clk(clk100MHz), .cein(ce1k), .write(write), .reset(reset), .id(id), .din(outdata), .dout(t1out)); | ||
+ | | ||
+ | //ROM controller for lookup ROM. | ||
+ | ROMcontroller ROMcontrol(.clk(clk100MHz), .id(id), .ain(outdata), .aout(romaddress)); | ||
+ | | ||
+ | //Processor input data MUX. | ||
+ | dataMUX datamux(.read(read), .blink(blink), .id(id), .i2cdata(16'd0), .i2cstatus(16'd0), .xpos(16'd0), .ypos(16'd0), | ||
+ | .uartdata({8'h00,uartdata}), .txcount(txcount), .rxcount(rxcount), .romdata(romdata), | ||
+ | .switches(sw), .sec(sec), .min(min), .hour(hour), .micdata({btnD, 3'h0, mdout}), | ||
+ | .dout(in_port)); | ||
+ | |||
+ | //Clock control. | ||
+ | ClockControl clockcontrol(.clock(clk100MHz), .ce_1KHz(ce1k), .button({btnD, btnL, btnC, btnR}), .blink(blink), | ||
+ | .hour(hour), .min(min), .sec(sec)); | ||
+ | |||
+ | //Picture processing unit. | ||
+ | VGA ppu(.clk25MHz(clk25MHz), .clk(clk100MHz), .write(write), .id(id), .data(outdata[7:0]), | ||
+ | .vblank(vblank), .vsync(Vsync), .hsync(Hsync), .vga({vgaBlue[3:2], vgaGreen[3:1], vgaRed[3:1]})); | ||
+ | | ||
+ | //Microphone control. | ||
+ | MControl mc(.clk(clk100MHz), .reset(reset), .serialdata(data), .nenable(ce), .sclk(sclk), .micdata(mdout)); | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### NMPSM3.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module NMPSM3(clk, reset, INSTRUCTION, IN_PORT, IRQ0, IRQ1, IRQ2, IRQ3, | ||
+ | ADDRESS, OUT_PORT, PORT_ID, READ_STROBE, WRITE_STROBE, | ||
+ | IRQ_ACK0, IRQ_ACK1, IRQ_ACK2, IRQ_ACK3); | ||
+ | |||
+ | input clk, reset, IRQ0, IRQ1, IRQ2, IRQ3; | ||
+ | input [35:0]INSTRUCTION; | ||
+ | input [15:0]IN_PORT; | ||
+ | output READ_STROBE, WRITE_STROBE, IRQ_ACK0, IRQ_ACK1, IRQ_ACK2, IRQ_ACK3; | ||
+ | output [15:0]PORT_ID; | ||
+ | output [15:0]OUT_PORT; | ||
+ | output [15:0]ADDRESS; | ||
+ | | ||
+ | localparam SIZE = 16; | ||
+ | | ||
+ | localparam JPNZ = 8'h16; | ||
+ | localparam JPZ = 8'h19; | ||
+ | localparam JPNC = 8'h1C; | ||
+ | localparam JPC = 8'h20; | ||
+ | | ||
+ | localparam CLNZ = 8'h29; | ||
+ | localparam CLZ = 8'h2C; | ||
+ | localparam CLNC = 8'h30; | ||
+ | localparam CLC = 8'h33; | ||
+ | | ||
+ | localparam RTNZ = 8'h39; | ||
+ | localparam RTZ = 8'h3C; | ||
+ | localparam RTNC = 8'h40; | ||
+ | localparam RTC = 8'h43; | ||
+ | | ||
+ | localparam IRQADDR0 = 8'hCC; | ||
+ | localparam IRQADDR1 = 8'hD0; | ||
+ | localparam IRQADDR2 = 8'hD3; | ||
+ | localparam IRQADDR3 = 8'hD6; | ||
+ | | ||
+ | localparam STEP = 8'hD9; | ||
+ | | ||
+ | wire [43:0]control; | ||
+ | wire [15:0]portA; | ||
+ | wire [15:0]portB; | ||
+ | wire zero; | ||
+ | wire [7:0]decodeAddr; | ||
+ | wire I0, I1, I2, I3; | ||
+ | wire [15:0]addrp1; | ||
+ | wire [10:0] addrA; | ||
+ | wire [15:0] dataA; | ||
+ | wire weA; | ||
+ | wire [10:0] addrB; | ||
+ | wire [15:0] dataB; | ||
+ | wire weB; | ||
+ | wire [9:0]stackm1; | ||
+ | wire [19:0]none; | ||
+ | wire [7:0]portAup; | ||
+ | wire [7:0]portAdn; | ||
+ | wire [7:0]portBup; | ||
+ | wire [7:0]portBdn; | ||
+ | wire [4:0]sel; | ||
+ | wire [15:0]a; | ||
+ | wire [15:0]b; | ||
+ | wire [15:0]inst; | ||
+ | | ||
+ | reg [1:0]IRQload = 2'b00; | ||
+ | reg [15:0]wresult = 16'h0000; | ||
+ | reg wcarry = 1'b0; | ||
+ | reg [15:0]result = 16'h0000; | ||
+ | reg carry = 1'b0; | ||
+ | reg [1:0]load = 2'b00; | ||
+ | reg IRQMreg = 1'b1; | ||
+ | reg IRQ0reg = 1'b0; | ||
+ | reg IRQ1reg = 1'b0; | ||
+ | reg IRQ2reg = 1'b0; | ||
+ | reg IRQ3reg = 1'b0; | ||
+ | reg [9:0]stack = 10'h000; | ||
+ | reg [15:0]addr = 16'h0000; | ||
+ | | ||
+ | //Used to synchronize interrupts and reset with internal clock. | ||
+ | reg IR0 = 1'b0; | ||
+ | reg IR1 = 1'b0; | ||
+ | reg IR2 = 1'b0; | ||
+ | reg IR3 = 1'b0; | ||
+ | reg [1:0]rst = 2'b00; | ||
+ | |||
+ | RAMB16_S36_S36 #( | ||
+ | .INIT_A(36'h000000000), // Value of output RAM registers on Port A at startup | ||
+ | .INIT_B(36'h000000000), // Value of output RAM registers on Port B at startup | ||
+ | .SRVAL_A(36'h000000000), // Port A output value upon SSR assertion | ||
+ | .SRVAL_B(36'h000000000), // Port B output value upon SSR assertion | ||
+ | .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .WRITE_MODE_B("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .SIM_COLLISION_CHECK("ALL"), // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL" | ||
+ | |||
+ | // Micro-code for the decoder ROM | ||
+ | .INIT_00(256'H00200001_00000000_00000000_04040007_00000000_00000000_04000007_00000000), | ||
+ | .INIT_01(256'H00000000_08200007_00000001_00000000_00000000_08000007_00000000_04040007), | ||
+ | .INIT_02(256'H00000000_0000000B_00000000_00000000_0000000F_00000000_00000000_0000000B), | ||
+ | .INIT_03(256'H00000000_00000000_00000000_0000000B_00000000_00000000_0000000B_00000000), | ||
+ | .INIT_04(256'H00000000_1950000F_00000000_00000000_1950000B_00000000_00000000_0000000B), | ||
+ | .INIT_05(256'H00000000_00000000_00000000_1950000B_00000000_00000000_1950000B_00000000), | ||
+ | .INIT_06(256'H00000017_12300001_00000000_00000000_1950000B_00000000_00000000_1950000B), | ||
+ | .INIT_07(256'H00000000_00000000_00000017_12300001_00000000_00000017_12300001_00000000), | ||
+ | .INIT_08(256'H00001137_12300001_00000000_00000017_12300001_00000000_00000017_12300001), | ||
+ | .INIT_09(256'H00000000_00000000_00000000_44080407_00000000_00001157_12300001_00000000), | ||
+ | .INIT_0A(256'H00000000_20000A07_00000000_00000000_20000C07_00000000_00000000_44080207), | ||
+ | .INIT_0B(256'H00000000_00000000_00000000_04065007_00000000_00000000_04064007_00000000), | ||
+ | .INIT_0C(256'H00000000_04066007_00000000_00000000_04063007_00000000_00000000_04062007), | ||
+ | .INIT_0D(256'H00000000_00000000_00000000_0406C007_00000000_00000000_04067007_00000000), | ||
+ | .INIT_0E(256'H00000000_04069007_00000000_00000000_0406D007_00000000_00000000_04068007), | ||
+ | .INIT_0F(256'H00000000_00000000_00000000_0406A007_00000000_00000000_0406E007_00000000), | ||
+ | .INIT_10(256'H00000000_00010007_00000000_00000000_0406B007_00000000_00000000_0406F007), | ||
+ | .INIT_11(256'H00000000_00000000_00000000_00012007_00000000_00000000_00011007_00000000), | ||
+ | .INIT_12(256'H00000000_04075007_00000000_00000000_04074007_00000000_00000000_00013007), | ||
+ | .INIT_13(256'H00000000_00000000_00000000_04077007_00000000_00000000_04076007_00000000), | ||
+ | .INIT_14(256'H00000000_00000027_00000000_00000000_00018007_00000000_00000000_00019007), | ||
+ | .INIT_15(256'H00000000_00000000_00000000_00000067_00000000_00000000_00000047_00000000), | ||
+ | .INIT_16(256'H00000000_000000C7_00000000_00000000_000000A7_00000000_00000000_00000087), | ||
+ | .INIT_17(256'H00000000_00000000_00000000_00000107_00000000_00000000_000000E7_00000000), | ||
+ | .INIT_18(256'H04040007_12300001_00000000_00000000_00000000_00000000_00000000_19100007), | ||
+ | .INIT_19(256'H00000000_00000000_80000013_99900161_00000000_00000000_00000000_00000000), | ||
+ | .INIT_1A(256'H00000013_19900161_00000000_00000013_19900161_00000000_00000013_19900161), | ||
+ | .INIT_1B(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000007_00000000), | ||
+ | .INIT_1C(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_1D(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_1E(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_1F(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_20(256'H00000080_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_21(256'H00000000_00000000_000000E0_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_22(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_23(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_24(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_25(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_26(256'H00000000_00000370_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_27(256'H00000000_00000000_00000000_000003D0_00000000_00000000_000003A0_00000000), | ||
+ | .INIT_28(256'H00000000_00000470_00000000_00000000_00000440_00000000_00000000_00000410), | ||
+ | .INIT_29(256'H00000000_00000000_00000000_00000000_00000000_00000000_000004A0_00000000), | ||
+ | .INIT_2A(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_2B(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_2C(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_2D(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_2E(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_2F(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_30(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_31(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_32(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_33(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_34(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_35(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_36(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_37(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_38(256'H00000000_00000C70_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_39(256'H00000000_00000000_00000000_00000CD8_00000000_00000000_00000000_00000000), | ||
+ | .INIT_3A(256'H00000004_00000D6C_00000000_00000002_00000D4A_00000000_00000001_00000D19), | ||
+ | .INIT_3B(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_3C(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_3D(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_3E(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000), | ||
+ | .INIT_3F(256'H00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000)) | ||
+ | DecoderROM ( | ||
+ | .DOA(control[31:0]), // Port A 32-bit Data Output | ||
+ | .DOB({none, control[43:32]}), // Port B 32-bit Data Output | ||
+ | .ADDRA({1'b0, decodeAddr}), // Port A 9-bit Address Input | ||
+ | .ADDRB({1'b1, decodeAddr}), // Port B 9-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(1'b0), // Port A Write Enable Input | ||
+ | .WEB(1'b0) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_A(18'h00000), // Value of output RAM registers on Port A at startup | ||
+ | .INIT_B(18'h00000), // Value of output RAM registers on Port B at startup | ||
+ | .SRVAL_A(18'h00000), // Port A output value upon SSR assertion | ||
+ | .SRVAL_B(18'h00000), // Port B output value upon SSR assertion | ||
+ | .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .WRITE_MODE_B("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .SIM_COLLISION_CHECK("ALL")) // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL" | ||
+ | RAMupper ( | ||
+ | .DOA(portAup), // Port A 16-bit Data Output | ||
+ | .DOB(portBup), // Port B 16-bit Data Output | ||
+ | .ADDRA(addrA), // Port A 10-bit Address Input | ||
+ | .ADDRB(addrB), // Port B 10-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(dataA[15:8]), // Port A 16-bit Data Input | ||
+ | .DIB(dataB[15:8]), // Port-B 16-bit Data Input | ||
+ | .DIPA(1'b0), // Port A 1-bit parity Input | ||
+ | .DIPB(1'b0), // Port B 1-bit parity Input | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(weA), // Port A Write Enable Input | ||
+ | .WEB(weB) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_A(18'h00000), // Value of output RAM registers on Port A at startup | ||
+ | .INIT_B(18'h00000), // Value of output RAM registers on Port B at startup | ||
+ | .SRVAL_A(18'h00000), // Port A output value upon SSR assertion | ||
+ | .SRVAL_B(18'h00000), // Port B output value upon SSR assertion | ||
+ | .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .WRITE_MODE_B("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .SIM_COLLISION_CHECK("ALL")) // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL" | ||
+ | RAMlower ( | ||
+ | .DOA(portAdn), // Port A 16-bit Data Output | ||
+ | .DOB(portBdn), // Port B 16-bit Data Output | ||
+ | .ADDRA(addrA), // Port A 10-bit Address Input | ||
+ | .ADDRB(addrB), // Port B 10-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(dataA[7:0]), // Port A 16-bit Data Input | ||
+ | .DIB(dataB[7:0]), // Port-B 16-bit Data Input | ||
+ | .DIPA(1'b0), // Port A 1-bit parity Input | ||
+ | .DIPB(1'b0), // Port B 1-bit parity Input | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(weA), // Port A Write Enable Input | ||
+ | .WEB(weB) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | always @(posedge clk) begin | ||
+ | if(rst) begin | ||
+ | carry <= 1'b0; | ||
+ | IRQMreg <= 1'b1; | ||
+ | IRQ0reg <= 1'b0; | ||
+ | IRQ1reg <= 1'b0; | ||
+ | IRQ2reg <= 1'b0; | ||
+ | IRQ3reg <= 1'b0; | ||
+ | stack <= 10'h000; | ||
+ | result <= 16'h0000; | ||
+ | addr <= 16'h0000; | ||
+ | load <= 2'b00; | ||
+ | rst <= rst + 1'b1; | ||
+ | end | ||
+ | else begin | ||
+ | result <= wresult; | ||
+ | carry <= wcarry; | ||
+ | if(control[1]) | ||
+ | addr <= ADDRESS; | ||
+ | if(control[25:24] == 2'b01) | ||
+ | stack <= stack + 1'b1; | ||
+ | if(control[25:24] == 2'b10) | ||
+ | stack <= stack - 1'b1; | ||
+ | if(control[8:5] == 4'b0001) | ||
+ | IRQ0reg <=1'b1; | ||
+ | if(control[8:5] == 4'b0010) | ||
+ | IRQ1reg <=1'b1; | ||
+ | if(control[8:5] == 4'b0011) | ||
+ | IRQ2reg <=1'b1; | ||
+ | if(control[8:5] == 4'b0100) | ||
+ | IRQ3reg <=1'b1; | ||
+ | if(control[8:5] == 4'b0101) | ||
+ | IRQ0reg <=1'b0; | ||
+ | if(control[8:5] == 4'b0110) | ||
+ | IRQ1reg <=1'b0; | ||
+ | if(control[8:5] == 4'b0111) | ||
+ | IRQ2reg <=1'b0; | ||
+ | if(control[8:5] == 4'b1000) | ||
+ | IRQ3reg <=1'b0; | ||
+ | if(control[8:5] == 4'b1001) | ||
+ | IRQMreg <=1'b1; | ||
+ | if(control[8:5] == 4'b1010) begin | ||
+ | IRQMreg <= 1'b1; | ||
+ | IRQ0reg <= 1'b0; | ||
+ | IRQ1reg <= 1'b0; | ||
+ | IRQ2reg <= 1'b0; | ||
+ | IRQ3reg <= 1'b0; | ||
+ | end | ||
+ | if(control[8:5] == 4'b1011) | ||
+ | IRQMreg <= 1'b0; | ||
+ | if(control[35]) | ||
+ | load <= {carry, ~zero}; | ||
+ | //Synchronize interrupts and reset with the internal clock. | ||
+ | if(IRQ0) | ||
+ | IR0 <= 1'b1; | ||
+ | else | ||
+ | IR0 <= 1'b0; | ||
+ | if(IRQ1) | ||
+ | IR1 <= 1'b1; | ||
+ | else | ||
+ | IR1 <= 1'b0; | ||
+ | if(IRQ2) | ||
+ | IR2 <= 1'b1; | ||
+ | else | ||
+ | IR2 <= 1'b0; | ||
+ | if(IRQ3) | ||
+ | IR3 <= 1'b1; | ||
+ | else | ||
+ | IR3 <= 1'b0; | ||
+ | if (reset) | ||
+ | rst <= 2'b01; | ||
+ | end | ||
+ | end | ||
+ | | ||
+ | assign IRQ_ACK0 = control[31]; | ||
+ | assign IRQ_ACK1 = control[32]; | ||
+ | assign IRQ_ACK2 = control[33]; | ||
+ | assign IRQ_ACK3 = control[34]; | ||
+ | | ||
+ | always @(control) | ||
+ | case(control[33:31]) | ||
+ | 3'b001 : IRQload <= 2'h1; | ||
+ | 3'b010 : IRQload <= 2'h2; | ||
+ | 3'b100 : IRQload <= 2'h3; | ||
+ | default : IRQload <= 2'h4; | ||
+ | endcase | ||
+ | | ||
+ | and andIRQ0 (I0, IRQMreg, IRQ0reg, IR0); | ||
+ | and andIRQ1 (I1, IRQMreg, IRQ1reg, IR1); | ||
+ | and andIRQ2 (I2, IRQMreg, IRQ2reg, IR2); | ||
+ | and andIRQ3 (I3, IRQMreg, IRQ3reg, IR3); | ||
+ | | ||
+ | assign decodeAddr = control[0] ? control[43:36] : | ||
+ | ({control[0], I0} == 2'b01) ? IRQADDR0 : | ||
+ | ({control[0], I0, I1} == 3'b001) ? IRQADDR1 : | ||
+ | ({control[0], I0, I1, I2} == 4'b0001) ? IRQADDR2 : | ||
+ | ({control[0], I0, I1, I2, I3} == 5'b00001) ? IRQADDR3 : | ||
+ | ({zero, INSTRUCTION[35:28]} == {1'b1, JPNZ}) ? STEP : | ||
+ | ({zero, INSTRUCTION[35:28]} == {1'b0, JPZ }) ? STEP : | ||
+ | ({carry, INSTRUCTION[35:28]} == {1'b1, JPNC}) ? STEP : | ||
+ | ({carry, INSTRUCTION[35:28]} == {1'b0, JPC }) ? STEP : | ||
+ | ({zero, INSTRUCTION[35:28]} == {1'b1, CLNZ}) ? STEP : | ||
+ | ({zero, INSTRUCTION[35:28]} == {1'b0, CLZ }) ? STEP : | ||
+ | ({carry, INSTRUCTION[35:28]} == {1'b1, CLNC}) ? STEP : | ||
+ | ({carry, INSTRUCTION[35:28]} == {1'b0, CLC }) ? STEP : | ||
+ | ({zero, INSTRUCTION[35:28]} == {1'b1, RTNZ}) ? STEP : | ||
+ | ({zero, INSTRUCTION[35:28]} == {1'b0, RTZ }) ? STEP : | ||
+ | ({carry, INSTRUCTION[35:28]} == {1'b1, RTNC}) ? STEP : | ||
+ | ({carry, INSTRUCTION[35:28]} == {1'b0, RTC }) ? STEP : | ||
+ | INSTRUCTION[35:28]; | ||
+ | |||
+ | assign PORT_ID = (control[10:9] == 2'b01) ? portB : | ||
+ | (control[10:9] == 2'b10) ? INSTRUCTION[15:0] : | ||
+ | 16'h0000; | ||
+ | | ||
+ | assign OUT_PORT = (control[11] == 1'b1) ? portA : 16'h0000; | ||
+ | | ||
+ | assign WRITE_STROBE = control[29]; | ||
+ | | ||
+ | assign READ_STROBE = control[30]; | ||
+ | | ||
+ | assign stackm1 = stack - 1'b1; | ||
+ | | ||
+ | assign weA = control[26]; | ||
+ | assign weB = control[27]; | ||
+ | | ||
+ | assign addrA = {1'b0, INSTRUCTION[25:16]}; | ||
+ | | ||
+ | assign portA = {portAup, portAdn}; | ||
+ | | ||
+ | assign portB = {portBup, portBdn}; | ||
+ | |||
+ | assign dataA = (control[19:17] == 3'b001) ? portA : | ||
+ | (control[19:17] == 3'b010) ? portB : | ||
+ | (control[19:17] == 3'b011) ? wresult : | ||
+ | (control[19:17] == 3'b100) ? IN_PORT : | ||
+ | INSTRUCTION[15:0]; | ||
+ | | ||
+ | assign addrB = (control[21:20] == 2'b01) ? {control[28], stack[9:0]} : | ||
+ | (control[21:20] == 2'b10) ? {control[28], portB[9:0]} : | ||
+ | (control[21:20] == 2'b11) ? {control[28], stackm1[9:0]} : | ||
+ | {control[28], INSTRUCTION[9:0]}; | ||
+ | | ||
+ | assign dataB = (control[23:22] == 2'b01) ? addrp1 : | ||
+ | (control[23:22] == 2'b10) ? ADDRESS : | ||
+ | portA; | ||
+ | |||
+ | assign addrp1 = addr + 1'b1; | ||
+ | | ||
+ | assign ADDRESS = rst ? 16'h0000 : | ||
+ | (control[4:2] == 3'b001) ? addrp1 : | ||
+ | (control[4:2] == 3'b010) ? INSTRUCTION[15:0] : | ||
+ | (control[4:2] == 3'b011) ? portA : | ||
+ | (control[4:2] == 3'b100) ? {14'h0000,IRQload}: | ||
+ | (control[4:2] == 3'b101) ? portB : | ||
+ | addr; | ||
+ | | ||
+ | //ALU code begins here. | ||
+ | assign zero = (result == 16'h0000) ? 1'b1 : 1'b0; | ||
+ | | ||
+ | assign inst = INSTRUCTION[15:0]; | ||
+ | assign a = portA; | ||
+ | assign b = portB; | ||
+ | assign sel = control[16:12]; | ||
+ | | ||
+ | //OR a | b, a | inst | ||
+ | wire orc; | ||
+ | wire [15:0]orr; | ||
+ | | ||
+ | assign orc = 1'b0; | ||
+ | assign orr = sel[0] ? (a | b) : (a | inst); | ||
+ | | ||
+ | //AND a & b, a & inst | ||
+ | wire andc; | ||
+ | wire [15:0]andr; | ||
+ | | ||
+ | assign andc = 1'b0; | ||
+ | assign andr = sel[0] ? (a & b) : (a & inst); | ||
+ | | ||
+ | //XOR a ^ b, a ^ inst | ||
+ | wire xorc; | ||
+ | wire [15:0]xorr; | ||
+ | | ||
+ | assign xorc = 1'b0; | ||
+ | assign xorr = sel[0] ? (a ^ b) : (a ^ inst); | ||
+ | |||
+ | //ADD ADD a + b, ADDC a + b | ||
+ | wire addbcarryin, addbcarryout; | ||
+ | wire [15:0]addbresult; | ||
+ | | ||
+ | assign addbcarryin = sel[0] ? carry : 1'b0; | ||
+ | assign {addbcarryout, addbresult} = a + b + addbcarryin; | ||
+ | |||
+ | //SUB SUB a - b, SUBC a - b | ||
+ | wire subbcarryin, subbcarryout; | ||
+ | wire [15:0]subbresult; | ||
+ | | ||
+ | assign subbcarryin = sel[0] ? carry : 1'b0; | ||
+ | assign {subbcarryout, subbresult} = a - b - subbcarryin; | ||
+ | |||
+ | //ADD ADD a + inst, ADDC a + inst | ||
+ | wire addicarryin, addicarryout; | ||
+ | wire [15:0]addiresult; | ||
+ | | ||
+ | assign addicarryin = sel[0] ? carry : 1'b0; | ||
+ | assign {addicarryout, addiresult} = a + inst + addicarryin; | ||
+ | |||
+ | //SUB SUB a - inst, SUBC a - inst | ||
+ | wire subicarryin, subicarryout; | ||
+ | wire [15:0]subiresult; | ||
+ | |||
+ | assign subicarryin = sel[0] ? carry : 1'b0; | ||
+ | assign {subicarryout, subiresult} = a - inst - subicarryin; | ||
+ | |||
+ | //TEST TEST a and b, TEST a and inst | ||
+ | wire testc; | ||
+ | wire [15:0]testr; | ||
+ | | ||
+ | assign testc = ^testr; | ||
+ | assign testr = sel[0] ? (a & b) : (a & inst); | ||
+ | |||
+ | //COMP COMP a to b, COMP a to inst | ||
+ | wire tempc1, tempc2, compc; | ||
+ | wire [15:0]compr; | ||
+ | | ||
+ | assign tempc1 = (a < inst) ? 1'b1 : 1'b0; | ||
+ | assign tempc2 = (a < b) ? 1'b1 : 1'b0; | ||
+ | |||
+ | assign compc = sel[0] ? tempc2 : tempc1; | ||
+ | assign compr = sel[0] ? (a ^ b) : (a ^ inst); | ||
+ | |||
+ | //LEFT ROL, ASL | ||
+ | wire leftc; | ||
+ | wire [15:0]leftr; | ||
+ | |||
+ | assign leftc = a[15]; | ||
+ | assign leftr = sel[0] ? {a[14:0], carry} : {a[14:0], 1'b0}; | ||
+ | |||
+ | //RIGHT ROR, LSR | ||
+ | wire rightc; | ||
+ | wire [15:0]rightr; | ||
+ | |||
+ | assign rightc = a[0]; | ||
+ | assign rightr = sel[0] ? {carry, a[15:1]} : {1'b0, a[15:1]}; | ||
+ | | ||
+ | //CARRY SETC, CLRC | ||
+ | wire carryc; | ||
+ | wire [15:0]carryr; | ||
+ | |||
+ | assign carryc = sel[0]; | ||
+ | assign carryr = result; | ||
+ | |||
+ | //LOAD LOAD carry and result with load, no change. | ||
+ | wire loadc; | ||
+ | wire [15:0]loadr; | ||
+ | | ||
+ | assign loadc = sel[0] ? load[1] : carry; | ||
+ | assign loadr = sel[0] ? {15'h0000, load[0]} : result; | ||
+ | | ||
+ | //MUX results | ||
+ | always @(*) | ||
+ | case(sel[4:1]) | ||
+ | 4'b0000 : wresult <= loadr; | ||
+ | 4'b0001 : wresult <= orr; | ||
+ | 4'b0010 : wresult <= andr; | ||
+ | 4'b0011 : wresult <= xorr; | ||
+ | 4'b0100 : wresult <= addbresult; | ||
+ | 4'b0101 : wresult <= subbresult; | ||
+ | 4'b0110 : wresult <= addiresult; | ||
+ | 4'b0111 : wresult <= subiresult; | ||
+ | 4'b1000 : wresult <= testr; | ||
+ | 4'b1001 : wresult <= compr; | ||
+ | 4'b1010 : wresult <= leftr; | ||
+ | 4'b1011 : wresult <= rightr; | ||
+ | 4'b1100 : wresult <= carryr; | ||
+ | default : wresult <= loadr; | ||
+ | endcase | ||
+ | | ||
+ | always @(*) | ||
+ | case(sel[4:1]) | ||
+ | 4'b0000 : wcarry <= loadc; | ||
+ | 4'b0001 : wcarry <= orc; | ||
+ | 4'b0010 : wcarry <= andc; | ||
+ | 4'b0011 : wcarry <= xorc; | ||
+ | 4'b0100 : wcarry <= addbcarryout; | ||
+ | 4'b0101 : wcarry <= subbcarryout; | ||
+ | 4'b0110 : wcarry <= addicarryout; | ||
+ | 4'b0111 : wcarry <= subicarryout; | ||
+ | 4'b1000 : wcarry <= testc; | ||
+ | 4'b1001 : wcarry <= compc; | ||
+ | 4'b1010 : wcarry <= leftc; | ||
+ | 4'b1011 : wcarry <= rightc; | ||
+ | 4'b1100 : wcarry <= carryc; | ||
+ | default : wcarry <= loadc; | ||
+ | endcase | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### VGA.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | //Address ports: | ||
+ | //0x8000 - 0x87FF Background pattern table A. | ||
+ | //0x8800 - 0x8FFF Background pattern table B. | ||
+ | //0x9000 - 0x97FF Sprite pattern table A. | ||
+ | //0x9800 - 0x9FFF Sprite pattern table B. | ||
+ | //0xA000 - 0xA3FF Name table. | ||
+ | //0xA400 - 0xA4FF Unused. | ||
+ | //0xA500 - 0xA5FF Background attribute table. | ||
+ | //0xA600 - 0xA60F Background pallettes 0 through 15. | ||
+ | //0xA610 - 0xA61F Sprite pallettes 0 through 15. | ||
+ | //0xA700 Base color (background color). | ||
+ | //0xB000 - 0xB3FF Sprite RAM (256 sprites). | ||
+ | |||
+ | module VGA( | ||
+ | input clk25MHz, | ||
+ | input clk, | ||
+ | input write, | ||
+ | input [15:0]id, | ||
+ | input [7:0]data, | ||
+ | output reg vblank = 1'b0, | ||
+ | output reg vsync = 1'b1, | ||
+ | output reg hsync = 1'b1, | ||
+ | output reg [7:0]vga = 8'h00 | ||
+ | ); | ||
+ | | ||
+ | parameter WAIT = 5'h00; | ||
+ | parameter NTAT = 5'h01; | ||
+ | parameter PTAB = 5'h02; | ||
+ | parameter BUFF = 5'h03; | ||
+ | parameter NEXT = 5'h04; | ||
+ | parameter SPRAM = 5'h05; | ||
+ | parameter SAB = 5'h06; | ||
+ | parameter WRIT0 = 5'h07; | ||
+ | parameter WRIT1 = 5'h08; | ||
+ | parameter WRIT2 = 5'h09; | ||
+ | parameter WRIT3 = 5'h0A; | ||
+ | parameter WRIT4 = 5'h0B; | ||
+ | parameter WRIT5 = 5'h0C; | ||
+ | parameter WRIT6 = 5'h0D; | ||
+ | parameter WRIT7 = 5'h0E; | ||
+ | parameter BUFF0 = 5'h0F; | ||
+ | parameter BUFF1 = 5'h10; | ||
+ | parameter BUFF2 = 5'h11; | ||
+ | parameter BUFF3 = 5'h12; | ||
+ | parameter BUFF4 = 5'h13; | ||
+ | parameter BUFF5 = 5'h14; | ||
+ | parameter BUFF6 = 5'h15; | ||
+ | parameter BUFF7 = 5'h16; | ||
+ | | ||
+ | reg [9:0]hcount = 10'h001; | ||
+ | reg [9:0]vcount = 10'h001; | ||
+ | reg [9:0]nextpixel = 10'h000; | ||
+ | reg [9:0]nextpixel2 = 10'h000; | ||
+ | reg [8:0]currline = 9'h000; | ||
+ | reg [9:0]next256pixel = 9'h000; | ||
+ | | ||
+ | wire [8:0]nxt256pix; | ||
+ | wire [7:0]cur256line; | ||
+ | wire [7:0]nxt256line; | ||
+ | wire [7:0]colorout; | ||
+ | | ||
+ | reg [8:0]currsprite = 9'h000; | ||
+ | reg [7:0]basecolor = 8'h00; | ||
+ | | ||
+ | reg [7:0]bgpal0 = 8'b00000000; | ||
+ | reg [7:0]bgpal1 = 8'b00111000; | ||
+ | reg [7:0]bgpal2 = 8'b00100000; | ||
+ | reg [7:0]bgpal3 = 8'b00011000; | ||
+ | reg [7:0]bgpal4 = 8'b00000000; | ||
+ | reg [7:0]bgpal5 = 8'b00111111; | ||
+ | reg [7:0]bgpal6 = 8'b00100100; | ||
+ | reg [7:0]bgpal7 = 8'b00011011; | ||
+ | reg [7:0]bgpal8 = 8'b00000000; | ||
+ | reg [7:0]bgpal9 = 8'b00011111; | ||
+ | reg [7:0]bgpal10 = 8'b00010100; | ||
+ | reg [7:0]bgpal11 = 8'b00001010; | ||
+ | reg [7:0]bgpal12 = 8'b00000000; | ||
+ | reg [7:0]bgpal13 = 8'b00000111; | ||
+ | reg [7:0]bgpal14 = 8'b00000100; | ||
+ | reg [7:0]bgpal15 = 8'b00000011; | ||
+ | | ||
+ | reg [7:0]sppal0 = 8'b00000000; | ||
+ | reg [7:0]sppal1 = 8'b00100110; | ||
+ | reg [7:0]sppal2 = 8'b00111111; | ||
+ | reg [7:0]sppal3 = 8'b00000010; | ||
+ | reg [7:0]sppal4 = 8'b00000000; | ||
+ | reg [7:0]sppal5 = 8'b10111111; | ||
+ | reg [7:0]sppal6 = 8'b10100100; | ||
+ | reg [7:0]sppal7 = 8'b10011011; | ||
+ | reg [7:0]sppal8 = 8'b00000000; | ||
+ | reg [7:0]sppal9 = 8'b10011111; | ||
+ | reg [7:0]sppal10 = 8'b10010100; | ||
+ | reg [7:0]sppal11 = 8'b10001010; | ||
+ | reg [7:0]sppal12 = 8'b00000000; | ||
+ | reg [7:0]sppal13 = 8'b10000111; | ||
+ | reg [7:0]sppal14 = 8'b10000100; | ||
+ | reg [7:0]sppal15 = 8'b10000011; | ||
+ | | ||
+ | always @(posedge clk) begin | ||
+ | if(id == 16'hA600 && write) bgpal0 <= data; | ||
+ | if(id == 16'hA601 && write) bgpal1 <= data; | ||
+ | if(id == 16'hA602 && write) bgpal2 <= data; | ||
+ | if(id == 16'hA603 && write) bgpal3 <= data; | ||
+ | if(id == 16'hA604 && write) bgpal4 <= data; | ||
+ | if(id == 16'hA605 && write) bgpal5 <= data; | ||
+ | if(id == 16'hA606 && write) bgpal6 <= data; | ||
+ | if(id == 16'hA607 && write) bgpal7 <= data; | ||
+ | if(id == 16'hA608 && write) bgpal8 <= data; | ||
+ | if(id == 16'hA609 && write) bgpal9 <= data; | ||
+ | if(id == 16'hA60A && write) bgpal10 <= data; | ||
+ | if(id == 16'hA60B && write) bgpal11 <= data; | ||
+ | if(id == 16'hA60C && write) bgpal12 <= data; | ||
+ | if(id == 16'hA60D && write) bgpal13 <= data; | ||
+ | if(id == 16'hA60E && write) bgpal14 <= data; | ||
+ | if(id == 16'hA60F && write) bgpal15 <= data; | ||
+ | | ||
+ | if(id == 16'hA610 && write) sppal0 <= data; | ||
+ | if(id == 16'hA611 && write) sppal1 <= data; | ||
+ | if(id == 16'hA612 && write) sppal2 <= data; | ||
+ | if(id == 16'hA613 && write) sppal3 <= data; | ||
+ | if(id == 16'hA614 && write) sppal4 <= data; | ||
+ | if(id == 16'hA615 && write) sppal5 <= data; | ||
+ | if(id == 16'hA616 && write) sppal6 <= data; | ||
+ | if(id == 16'hA617 && write) sppal7 <= data; | ||
+ | if(id == 16'hA618 && write) sppal8 <= data; | ||
+ | if(id == 16'hA619 && write) sppal9 <= data; | ||
+ | if(id == 16'hA61A && write) sppal10 <= data; | ||
+ | if(id == 16'hA61B && write) sppal11 <= data; | ||
+ | if(id == 16'hA61C && write) sppal12 <= data; | ||
+ | if(id == 16'hA61D && write) sppal13 <= data; | ||
+ | if(id == 16'hA61E && write) sppal14 <= data; | ||
+ | if(id == 16'hA61F && write) sppal15 <= data; | ||
+ | | ||
+ | if(id == 16'hA700 && write) basecolor <= data; | ||
+ | end | ||
+ | | ||
+ | //Line buffer wires and regs. | ||
+ | reg lbwe = 1'b0; | ||
+ | wire [8:0]lbaddra; | ||
+ | wire [7:0]lbdin; | ||
+ | wire lbrstb; | ||
+ | wire [8:0]lbaddrb; | ||
+ | wire [7:0]lbdout; | ||
+ | wire [7:0]lbcheck; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | //Test pattern. | ||
+ | .INIT_00(256'h00_01_02_03_04_05_06_07_08_09_0A_0B_0C_0D_0E_0F_10_11_12_13_14_15_16_17_18_19_1A_1B_1C_1D_1E_1F), | ||
+ | .INIT_01(256'h20_21_22_23_24_25_26_27_28_29_2A_2B_2C_2D_2E_2F_30_31_32_33_34_35_36_37_38_39_3A_3B_3C_3D_3E_3F), | ||
+ | .INIT_02(256'h40_41_42_43_44_45_46_47_48_49_4A_4B_4C_4D_4E_4F_50_51_52_53_54_55_56_57_58_59_5A_5B_5C_5D_5E_5F), | ||
+ | .INIT_03(256'h60_61_62_63_64_65_66_67_68_69_6A_6B_6C_6D_6E_6F_70_71_72_73_74_75_76_77_78_79_7A_7B_7C_7D_7E_7F), | ||
+ | .INIT_04(256'h80_81_82_83_84_85_86_87_88_89_8A_8B_8C_8D_8E_8F_90_91_92_93_94_95_96_97_98_99_9A_9B_9C_9D_9E_9F), | ||
+ | .INIT_05(256'hA0_A1_A2_A3_A4_A5_A6_A7_A8_A9_AA_AB_AC_AD_AE_AF_B0_B1_B2_B3_B4_B5_B6_B7_B8_B9_BA_BB_BC_BD_BE_BF), | ||
+ | .INIT_06(256'hC0_C1_C2_C3_C4_C5_C6_C7_C8_C9_CA_CB_CC_CD_CE_CF_D0_D1_D2_D3_D4_D5_D6_D7_D8_D9_DA_DB_DC_DD_DE_DF), | ||
+ | .INIT_07(256'hE0_E1_E2_E3_E4_E5_E6_E7_E8_E9_EA_EB_EC_ED_EE_EF_F0_F1_F2_F3_F4_F5_F6_F7_F8_F9_FA_FB_FC_FD_FE_FF), | ||
+ | .INIT_08(256'h0F_0E_0D_0C_0B_0A_09_08_07_06_05_04_03_02_01_00_1F_1E_1D_1C_1B_1A_19_18_17_16_15_14_13_12_11_10), | ||
+ | .INIT_09(256'h2F_2E_2D_2C_2B_2A_29_28_27_26_25_24_23_22_21_20_3F_3E_3D_3C_3B_3A_39_38_37_36_35_34_33_32_31_30), | ||
+ | .INIT_0A(256'h4F_4E_4D_4C_4B_4A_49_48_47_46_45_44_43_42_41_40_5F_5E_5D_5C_5B_5A_59_58_57_56_55_54_53_52_51_50), | ||
+ | .INIT_0B(256'h6F_6E_6D_6C_6B_6A_69_68_67_66_65_64_63_62_61_60_7F_7E_7D_7C_7B_7A_79_78_77_76_75_74_73_72_71_70), | ||
+ | .INIT_0C(256'h8F_8E_8D_8C_8B_8A_89_88_87_86_85_84_83_82_81_80_9F_9E_9D_9C_9B_9A_99_98_97_96_95_94_93_92_91_90), | ||
+ | .INIT_0D(256'hAF_AE_AD_AC_AB_AA_A9_A8_A7_A6_A5_A4_A3_A2_A1_A0_BF_BE_BD_BC_BB_BA_B9_B8_B7_B6_B5_B4_B3_B2_B1_B0), | ||
+ | .INIT_0E(256'hCF_CE_CD_CC_CB_CA_C9_C8_C7_C6_C5_C4_C3_C2_C1_C0_DF_DE_DD_DC_DB_DA_D9_D8_D7_D6_D5_D4_D3_D2_D1_D0), | ||
+ | .INIT_0F(256'hEF_EE_ED_EC_EB_EA_E9_E8_E7_E6_E5_E4_E3_E2_E1_E0_FF_FE_FD_FC_FB_FA_F9_F8_F7_F6_F5_F4_F3_F2_F1_F0)) | ||
+ | LineBufferRAM ( | ||
+ | .DOA(lbcheck), | ||
+ | .DOB(lbdout), // Port B 8-bit Data Output | ||
+ | .ADDRA({2'b00, lbaddra}), // Port A 11-bit Address Input | ||
+ | .ADDRB({2'b00, lbaddrb}), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk25MHz), // Port B Clock | ||
+ | .DIA(lbdin), // Port A 8-bit Data Input | ||
+ | .DIPA(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(lbrstb), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(lbwe), // Port A Write Enable Input | ||
+ | .WEB(1'b0) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | //Name table wires and regs. | ||
+ | wire [7:0]ntdout; | ||
+ | wire [9:0]ntaddra; | ||
+ | wire [9:0]ntaddrb; | ||
+ | wire [7:0]ntdin; | ||
+ | wire ntwe; | ||
+ | | ||
+ | assign ntdin = data; | ||
+ | assign ntaddrb = id - 16'hA000; | ||
+ | assign ntwe = (id >= 16'hA000 && id <= 16'hA3FF) ? write : 1'b0; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_00(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_01(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_02(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_03(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_04(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_05(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_06(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_07(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_08(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_09(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_0A(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_0B(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_0C(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_0D(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_0E(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_0F(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_10(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_11(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_12(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_13(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_14(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_15(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_16(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_17(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_18(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_19(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_1A(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_1B(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_1C(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_1D(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_1E(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF), | ||
+ | .INIT_1F(256'hFF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF)) | ||
+ | NameTableRAM ( | ||
+ | .DOA(ntdout), // Port B 8-bit Data Output | ||
+ | .ADDRA({1'b0, ntaddra}), // Port A 11-bit Address Input | ||
+ | .ADDRB({1'b0, ntaddrb}), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIB(ntdin), // Port A 8-bit Data Input | ||
+ | .DIPB(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(1'b0), // Port A Write Enable Input | ||
+ | .WEB(ntwe) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | //Background pattern table A wires. | ||
+ | wire [7:0]bgptadout; | ||
+ | wire [10:0]bgptaaddra; | ||
+ | wire [10:0]bgptaaddrb; | ||
+ | wire [7:0]bgptadin; | ||
+ | wire bgptawe; | ||
+ | |||
+ | assign bgptadin = data; | ||
+ | assign bgptaaddrb = id - 16'h8000; | ||
+ | assign bgptawe = (id >= 16'h8000 && id <= 16'h87FF) ? write : 1'b0; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_00(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_01(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_02(256'h00_FC_C6_C6_FC_C6_C6_FC_00_C6_C6_FE_C6_C6_6C_38_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_03(256'h00_C0_C0_C0_FC_C0_C0_FE_00_FE_C0_C0_FC_C0_C0_FE_00_F8_CC_C6_C6_C6_CC_F8_00_3C_66_C0_C0_C0_66_3C), | ||
+ | .INIT_04(256'h00_7C_C6_C6_06_06_06_1E_00_7E_18_18_18_18_18_7E_00_C6_C6_C6_FE_C6_C6_C6_00_3E_66_C6_CE_C0_60_3E), | ||
+ | .INIT_05(256'h00_C6_CE_DE_FE_F6_E6_C6_00_C6_C6_D6_FE_FE_EE_C6_00_7E_60_60_60_60_60_60_00_CE_DC_F8_F0_D8_CC_C6), | ||
+ | .INIT_06(256'h00_CE_DC_F8_CE_C6_C6_FC_00_7A_CC_DE_C6_C6_C6_7C_00_C0_C0_FC_C6_C6_C6_FC_00_7C_C6_C6_D6_C6_C6_7C), | ||
+ | .INIT_07(256'h00_10_38_7C_EE_C6_C6_C6_00_7C_C6_C6_C6_C6_C6_C6_00_18_18_18_18_18_18_7E_00_7C_C6_06_7C_C0_CC_78), | ||
+ | .INIT_08(256'h00_FE_E0_70_38_1C_0E_FE_00_18_18_18_3C_66_66_66_00_C6_EE_7C_38_7C_EE_C6_00_C6_EE_FE_FE_D6_C6_C6), | ||
+ | .INIT_09(256'h00_1C_24_24_1C_04_04_00_00_38_40_40_40_38_00_00_00_38_24_24_38_20_20_00_00_34_48_48_38_08_30_00), | ||
+ | .INIT_0A(256'h00_24_24_24_38_20_20_00_00_08_14_0C_3A_48_30_00_00_10_10_10_3C_10_18_00_00_3C_40_78_44_38_00_00), | ||
+ | .INIT_0B(256'h00_16_08_14_14_14_08_00_00_4C_70_50_48_40_40_00_00_30_48_08_08_00_08_00_00_10_10_10_00_10_00_00), | ||
+ | .INIT_0C(256'h00_20_20_38_24_24_38_00_00_30_48_48_48_30_00_00_00_48_48_48_48_30_00_00_00_54_54_54_54_28_00_00), | ||
+ | .INIT_0D(256'h00_18_20_20_20_70_20_00_00_78_04_38_40_38_00_00_00_10_10_10_1C_60_00_00_00_04_0A_38_48_48_30_00), | ||
+ | .INIT_0E(256'h00_44_28_10_28_44_00_00_00_28_54_54_54_44_00_00_00_10_38_28_44_44_00_00_00_34_48_48_48_48_00_00), | ||
+ | .INIT_0F(256'h00_00_00_00_7C_00_00_00_00_08_00_08_02_22_1C_00_00_7C_20_10_08_7C_00_00_00_18_24_04_1C_24_24_00), | ||
+ | .INIT_10(256'h04_04_FC_00_00_00_00_01_20_20_3F_00_00_00_00_80_80_00_00_00_00_00_00_00_01_00_00_00_00_00_00_00), | ||
+ | .INIT_11(256'h82_82_82_82_82_82_82_82_FF_00_00_00_00_00_FF_00_FE_02_02_02_02_02_FE_00_7F_40_40_40_40_40_7F_00), | ||
+ | .INIT_12(256'h00_00_FF_80_00_00_00_80_00_00_FF_01_00_00_00_01_82_82_82_82_82_02_04_08_41_41_41_41_41_40_20_10), | ||
+ | .INIT_13(256'h10_60_80_00_00_00_00_00_08_06_01_00_00_00_00_00_02_02_04_08_10_60_80_00_40_40_20_10_08_06_01_00), | ||
+ | .INIT_14(256'h01_00_00_00_00_FC_04_04_80_00_00_00_00_3F_20_20_00_00_00_00_00_00_00_80_00_00_00_00_00_00_00_01), | ||
+ | .INIT_15(256'h00_FF_00_00_00_00_00_FF_41_41_41_41_41_41_41_41_00_FE_82_82_82_82_82_82_00_7F_40_40_40_40_40_7F), | ||
+ | .INIT_16(256'h80_00_00_00_80_FF_00_00_01_00_00_00_01_FF_00_00_08_04_02_82_82_82_82_82_10_20_40_41_41_41_41_41), | ||
+ | .INIT_17(256'h00_00_00_00_00_80_60_10_00_00_00_00_00_01_06_08_00_80_60_10_08_04_02_02_00_01_06_08_10_20_40_40), | ||
+ | .INIT_18(256'h00_00_00_00_00_7F_40_40_40_40_7F_00_00_00_00_00_00_00_FF_00_00_00_00_00_00_00_00_00_00_FF_00_00), | ||
+ | .INIT_19(256'h20_20_20_20_10_08_04_02_80_80_00_00_00_00_00_00_00_00_01_01_02_0C_F0_00_00_80_40_20_10_0C_03_00), | ||
+ | .INIT_1A(256'h00_00_00_00_00_3F_20_20_04_04_FC_80_80_80_80_80_00_00_C0_40_40_40_40_C0_00_00_1F_10_08_04_02_01), | ||
+ | .INIT_1B(256'h1C_22_41_41_41_22_1C_00_00_80_80_80_80_80_80_80_80_80_80_80_80_FC_04_04_40_40_40_40_40_C0_00_00), | ||
+ | .INIT_1C(256'h41_40_40_40_40_40_7F_00_00_FE_02_02_02_02_02_FE_00_7F_40_40_40_40_40_40_01_00_00_00_00_00_00_00), | ||
+ | .INIT_1D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_61_41_43_00_61_41_43_00_40_40_41_41_41_41_41_41), | ||
+ | .INIT_1E(256'h00_00_00_00_00_00_00_00_FF_FF_AA_55_AA_55_AA_55_AA_55_AA_55_AA_55_AA_55_AA_55_AA_55_AA_55_FF_FF), | ||
+ | .INIT_1F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_61_41_43_00_61_41_43_00), | ||
+ | .INIT_20(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_21(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_22(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_23(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_24(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_25(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_26(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_27(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_28(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_29(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_30(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_31(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_32(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_33(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_34(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_35(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_36(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_37(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_38(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_39(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00)) | ||
+ | BGPatternTableARAM ( | ||
+ | .DOA(bgptadout), // Port B 8-bit Data Output | ||
+ | .ADDRA(bgptaaddra), // Port A 11-bit Address Input | ||
+ | .ADDRB(bgptaaddrb), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIB(bgptadin), // Port A 8-bit Data Input | ||
+ | .DIPB(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(1'b0), // Port A Write Enable Input | ||
+ | .WEB(bgptawe) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | //Background pattern table B wires. | ||
+ | wire [7:0]bgptbdout; | ||
+ | wire [10:0]bgptbaddra; | ||
+ | wire [10:0]bgptbaddrb; | ||
+ | wire [7:0]bgptbdin; | ||
+ | wire bgptbwe; | ||
+ | | ||
+ | assign bgptbdin = data; | ||
+ | assign bgptbaddrb = id - 16'h8800; | ||
+ | assign bgptbwe = (id >= 16'h8800 && id <= 16'h8FFF) ? write : 1'b0; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_00(256'h00_7C_C6_06_3C_18_0C_7E_00_FE_E0_78_3C_0E_C6_7C_00_7E_18_18_18_18_38_18_00_7C_C6_C6_C6_C6_C6_7C), | ||
+ | .INIT_01(256'h00_30_30_30_18_0C_C6_FE_00_7C_C6_C6_FC_C0_60_3C_00_7C_C6_06_06_FC_C0_FC_00_0C_0C_FE_CC_6C_3C_1C), | ||
+ | .INIT_02(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_78_0C_06_7E_C6_C6_7C_00_7C_C6_C6_7C_C6_C6_7C), | ||
+ | .INIT_03(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_04(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_05(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_06(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_07(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_08(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_09(256'h00_1C_24_24_1C_04_04_00_00_38_40_40_40_38_00_00_00_38_24_24_38_20_20_00_00_34_48_48_38_08_30_00), | ||
+ | .INIT_0A(256'h00_24_24_24_38_20_20_00_00_08_14_0C_3A_48_30_00_00_10_10_10_3C_10_18_00_00_3C_40_78_44_38_00_00), | ||
+ | .INIT_0B(256'h00_16_08_14_14_14_08_00_00_4C_70_50_48_40_40_00_00_30_48_08_08_00_08_00_00_10_10_10_00_10_00_00), | ||
+ | .INIT_0C(256'h00_20_20_38_24_24_38_00_00_30_48_48_48_30_00_00_00_48_48_48_48_30_00_00_00_54_54_54_54_28_00_00), | ||
+ | .INIT_0D(256'h00_18_20_20_20_70_20_00_00_78_04_38_40_38_00_00_00_10_10_10_1C_60_00_00_00_04_0A_38_48_48_30_00), | ||
+ | .INIT_0E(256'h00_44_28_10_28_44_00_00_00_28_54_54_54_44_00_00_00_10_38_28_44_44_00_00_00_34_48_48_48_48_00_00), | ||
+ | .INIT_0F(256'h00_00_00_00_7C_00_00_00_00_08_00_08_02_22_1C_00_00_7C_20_10_08_7C_00_00_00_18_24_04_1C_24_24_00), | ||
+ | .INIT_10(256'hF8_F8_00_00_00_00_00_01_3F_3F_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_11(256'hFC_FC_FC_FC_FC_FC_FC_FC_FF_FF_FF_FF_FF_FF_00_00_FC_FC_FC_FC_FC_FC_00_00_7F_7F_7F_7F_7F_7F_00_00), | ||
+ | .INIT_12(256'hFF_FF_00_00_00_00_00_00_FF_FF_00_00_00_00_00_01_FC_FC_FC_FC_FC_FC_F8_F0_7E_7E_7E_7E_7E_7F_3F_1F), | ||
+ | .INIT_13(256'hE0_80_00_00_00_00_00_00_0F_07_00_00_00_00_00_00_FC_FC_F8_F0_E0_80_00_00_7F_7F_3F_1F_0F_07_00_00), | ||
+ | .INIT_14(256'h00_00_00_00_00_F8_F8_F8_00_00_00_00_00_3F_3F_3F_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_01), | ||
+ | .INIT_15(256'h00_FF_FF_FF_FF_FF_FF_00_7E_7E_7E_7E_7E_7E_7E_7E_00_FC_FC_FC_FC_FC_FC_FC_00_7F_7F_7F_7F_7F_7F_00), | ||
+ | .INIT_16(256'h00_00_00_00_00_FF_FF_FF_00_00_00_00_01_FF_FF_FF_F0_F8_FC_FC_FC_FC_FC_FC_1F_3F_7F_7E_7E_7E_7E_7E), | ||
+ | .INIT_17(256'h00_00_00_00_00_00_80_E0_00_00_00_00_00_01_07_0F_00_80_80_E0_F0_F8_FC_FC_00_01_07_0F_1F_3F_7F_7F), | ||
+ | .INIT_18(256'h00_00_00_00_00_7F_7F_7F_7F_7F_00_00_00_00_00_00_FF_FF_00_00_00_00_00_00_00_00_00_00_00_FF_FF_FF), | ||
+ | .INIT_19(256'h3F_3F_3F_3F_1F_0F_07_03_00_00_00_00_00_00_00_00_FF_FF_FE_FE_FC_F0_00_00_FF_FF_7F_3F_1F_0F_00_00), | ||
+ | .INIT_1A(256'h00_00_00_00_00_3F_3F_3F_F8_F8_00_00_00_00_00_00_FF_FF_7F_7F_7F_7F_7F_7F_FF_FF_E0_E0_F0_F8_FC_FE), | ||
+ | .INIT_1B(256'h1C_3C_7E_7E_7E_3C_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_F8_F8_F8_7F_7F_7F_7F_7F_FF_FF_FF), | ||
+ | .INIT_1C(256'h7F_7F_7F_7F_7F_7F_00_00_00_FC_FC_FC_FC_FC_FC_00_00_7F_7F_7F_7F_7F_7F_7F_01_00_00_00_00_00_00_00), | ||
+ | .INIT_1D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_7F_7F_7E_7E_7E_7E_7E_7E), | ||
+ | .INIT_1E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_1F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_7E_7E_7C_00_7E_7E_7C_00), | ||
+ | .INIT_20(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_21(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_22(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_23(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_24(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_25(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_26(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_27(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_28(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_29(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_30(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_31(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_32(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_33(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_34(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_35(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_36(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_37(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_38(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_39(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00)) | ||
+ | BGPatternTableBRAM ( | ||
+ | .DOA(bgptbdout), // Port B 8-bit Data Output | ||
+ | .ADDRA(bgptbaddra), // Port A 11-bit Address Input | ||
+ | .ADDRB(bgptbaddrb), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIB(bgptbdin), // Port A 8-bit Data Input | ||
+ | .DIPB(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(1'b0), // Port A Write Enable Input | ||
+ | .WEB(bgptbwe) // Port B Write Enable Input | ||
+ | ); | ||
+ | |||
+ | //Background attribute table wires. | ||
+ | wire [7:0]bgatdout; | ||
+ | wire [7:0]bgataddra; | ||
+ | wire [7:0]bgataddrb; | ||
+ | wire [7:0]bgatdin; | ||
+ | wire bgatwe; | ||
+ | | ||
+ | assign bgatdin = data; | ||
+ | assign bgataddrb = id - 16'hA500; | ||
+ | assign bgatwe = (id >= 16'hA500 && id <= 16'hA5FF) ? write : 1'b0; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_00(256'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA), | ||
+ | .INIT_01(256'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA), | ||
+ | .INIT_02(256'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA), | ||
+ | .INIT_03(256'hFF_FF_FF_FF_FF_FF_FF_FF_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA), | ||
+ | .INIT_04(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_05(256'h56_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_56_55_55_55_55_55_55_55), | ||
+ | .INIT_06(256'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55), | ||
+ | .INIT_07(256'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA)) | ||
+ | BGAttributeTableRAM ( | ||
+ | .DOA(bgatdout), // Port B 8-bit Data Output | ||
+ | .ADDRA({3'h0, bgataddra}), // Port A 11-bit Address Input | ||
+ | .ADDRB({3'h0, bgataddrb}), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIB(bgatdin), // Port A 8-bit Data Input | ||
+ | .DIPB(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(1'b0), // Port A Write Enable Input | ||
+ | .WEB(bgatwe) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | //Sprite RAM wires. | ||
+ | wire spwe; | ||
+ | wire [9:0]spaddra; | ||
+ | wire [7:0]spdin; | ||
+ | wire [7:0]spaddrb; | ||
+ | wire [31:0]spdout; | ||
+ | | ||
+ | assign spwe = (id >= 16'hB000 && id <= 16'hB3FF) ? write : 1'b0; | ||
+ | assign spaddra = id - 16'hB000; | ||
+ | assign spdin = data; | ||
+ | assign spaddrb = (currsprite) ? currsprite - 1'b1 : 8'h00; | ||
+ | | ||
+ | BRAM_TDP_MACRO #( | ||
+ | .BRAM_SIZE("36Kb"), // Target BRAM: "18Kb" or "36Kb" | ||
+ | .READ_WIDTH_A (8), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") | ||
+ | .READ_WIDTH_B (32), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") | ||
+ | .WRITE_WIDTH_A(8), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") | ||
+ | .WRITE_WIDTH_B(32), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") | ||
+ | .INIT_00(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_01(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_02(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_03(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_04(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_05(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_06(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_07(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | | ||
+ | .INIT_08(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_09(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_0A(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_0B(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_0C(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_0D(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_0E(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_0F(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | | ||
+ | .INIT_10(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_11(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_12(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_13(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_14(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_15(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_16(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_17(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | | ||
+ | .INIT_18(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_19(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_1A(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_1B(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_1C(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_1D(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_1E(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF), | ||
+ | .INIT_1F(256'h00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF__00_00_00_FF) | ||
+ | ) SpriteRAM ( | ||
+ | .DOB(spdout), // Port B 32-bit Data Output | ||
+ | .ADDRA({2'b00, spaddra}), // Port A 12-bit Address Input | ||
+ | .ADDRB({2'b00, spaddrb}), // Port B 10-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(spdin), // Port A 8-bit Data Input | ||
+ | .DIB(32'h00000000), // Port B 32-bit Data Input | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .RSTA(1'b0), // 1-bit input port-A reset | ||
+ | .RSTB(1'b0), // 1-bit input port-B reset | ||
+ | .WEA(spwe), // Port A Write Enable Input | ||
+ | .WEB(1'b0) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | wire awe; | ||
+ | wire [10:0]aaddra; | ||
+ | wire [7:0]adin; | ||
+ | wire [10:0]aaddrb; | ||
+ | wire [7:0]adout; | ||
+ | | ||
+ | assign awe = (id >= 16'h9000 && id <= 16'h97FF) ? write : 1'b0; | ||
+ | assign aaddra = id - 16'h9000; | ||
+ | assign adin = data; | ||
+ | |||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_00(256'hD0_70_F8_F8_F8_F0_E0_80_3E_0F_06_25_16_1F_0F_03_E0_30_F0_F0_E0_C0_00_00_1D_0D_4B_2D_3F_1F_07_00), | ||
+ | .INIT_01(256'h30_70_7C_FE_ED_ED_F6_F6_E0_E0_F0_F0_F0_E0_C0_00_7D_1F_0D_4B_2D_3F_1F_07_00_3C_7E_7E_7E_7E_3C_00), | ||
+ | .INIT_02(256'h04_64_00_12_00_09_27_00_6E_38_08_48_A0_D0_E0_80_76_1C_10_12_05_0B_07_01_00_00_00_60_E0_C0_80_00), | ||
+ | .INIT_03(256'hEC_CC_9C_98_B8_F0_E0_C0_5C_B0_60_A4_68_F8_F0_C0_0F_0F_1F_1F_1F_0F_07_01_04_28_00_48_20_50_60_84), | ||
+ | .INIT_04(256'hE0_E0_F8_FE_FF_FF_FB_BE_01_03_33_1D_0E_06_0B_1D_C0_E0_F8_F8_38_F0_E0_40_13_0B_0B_1D_0D_15_3A_7B), | ||
+ | .INIT_05(256'h00_00_00_00_20_00_00_20_E0_E0_F0_F8_FC_F6_EE_F8_33_7B_FD_FE_EF_67_11_3F_BD_18_18_18_00_3C_18_18), | ||
+ | .INIT_06(256'h01_00_C0_11_70_2C_D8_0A_EF_93_63_F2_FE_FC_BF_5F_09_91_C6_4F_7F_3F_FD_FA_68_FC_AE_F7_DA_77_3F_0C), | ||
+ | .INIT_07(256'hFF_FF_FE_FE_FE_F6_F6_EE_9A_3E_FC_E0_F8_FC_FE_BE_07_07_0F_0E_1E_1D_1D_1E_04_00_20_10_6E_E8_93_50), | ||
+ | .INIT_08(256'h3C_70_60_E0_E0_F0_F0_F0_1D_03_1F_1E_38_77_7F_3F_F8_E0_E0_E0_F0_F0_F0_E0_01_00_01_01_00_00_01_01), | ||
+ | .INIT_09(256'h00_18_B8_B0_B0_C0_C0_00_1C_3F_3F_77_E3_F1_F1_F0_1C_0E_0E_07_07_03_01_01_00_00_00_00_18_BD_FF_99), | ||
+ | .INIT_0A(256'h70_98_C0_08_58_62_38_20_18_38_30_30_7C_66_F6_FF_18_1C_0C_0C_02_00_01_01_7F_FF_FF_3F_FF_FF_FF_40), | ||
+ | .INIT_0B(256'hFF_FF_FF_FF_FF_FF_FF_FF_F0_38_38_70_F0_E0_C0_80_07_07_07_07_07_0F_0F_0F_0E_05_4B_10_12_06_04_00), | ||
+ | .INIT_0C(256'h03_01_00_01_02_07_1F_3F_00_00_00_00_00_00_78_3C_7A_37_0F_1F_3E_3F_7B_FE_00_00_08_3C_38_3C_08_00), | ||
+ | .INIT_0D(256'h00_00_18_3C_3C_34_18_00_00_80_C0_C0_80_00_00_18_3E_1E_09_07_07_07_0E_1C_80_C0_C0_C0_C0_00_C0_80), | ||
+ | .INIT_0E(256'h00_3D_1D_0B_07_07_07_07_00_00_66_66_66_00_00_00_70_F8_F0_08_78_38_38_38_FF_FF_FF_FF_FF_FF_FF_00), | ||
+ | .INIT_0F(256'h81_80_A7_A3_A3_91_60_1F_74_A0_A4_80_20_40_00_00_01_07_23_AA_DD_6A_A1_48_3C_1C_83_8F_9F_3E_F8_F0), | ||
+ | .INIT_10(256'hCC_DE_BE_7C_F0_E0_88_FC_07_07_07_07_1F_37_37_1F_E0_80_C0_F0_60_A8_5C_DE_07_0F_1F_1F_1C_0F_07_02), | ||
+ | .INIT_11(256'h03_05_0D_0E_3E_36_7A_7D_00_00_00_00_02_00_00_02_80_80_38_1C_1C_38_D0_B8_07_07_18_7C_FC_F8_C7_7D), | ||
+ | .INIT_12(256'h00_00_00_00_40_00_00_40_C0_E0_D0_B0_FC_7C_BE_FE_07_07_0F_1F_3E_3F_1F_0F_E0_F0_F8_FC_DE_EE_FC_F0), | ||
+ | .INIT_13(256'hFF_93_9F_95_93_93_83_81_14_2D_16_3A_1D_4A_5C_A8_0F_17_1A_1C_1C_38_38_38_3C_66_C3_99_99_C3_66_3C), | ||
+ | .INIT_14(256'h78_F0_E0_E0_C0_C0_00_00_5F_74_77_3F_3F_1F_07_00_FC_F8_F8_F0_C0_00_00_00_33_1B_1F_0F_03_00_00_00), | ||
+ | .INIT_15(256'h14_3E_7C_5E_7C_7E_3F_14_A0_C0_E0_E0_40_00_00_00_7B_BD_DE_EF_FF_FF_FE_F8_FB_FC_7F_7F_1F_07_03_00), | ||
+ | .INIT_16(256'h00_00_00_00_00_00_00_00_3F_1F_0F_1F_3F_7B_71_20_00_17_14_54_57_B4_17_00_00_49_49_49_49_49_E9_00), | ||
+ | .INIT_17(256'hE0_40_60_F0_F0_60_40_E0_01_00_11_77_77_11_00_01_00_00_00_00_00_00_00_00_3C_66_C3_81_81_C3_66_3C), | ||
+ | .INIT_18(256'hFE_DE_7E_FE_FC_7C_FC_78_3D_3F_1F_78_7C_7E_3F_1F_C0_70_F8_F8_FC_FC_FC_FC_03_0F_1F_1F_3F_3F_3F_37), | ||
+ | .INIT_19(256'h00_00_00_00_00_00_40_20_00_00_00_00_20_60_60_60_00_C0_D8_F8_BC_BE_AF_B7_00_00_11_3B_7F_7F_F7_F7), | ||
+ | .INIT_1A(256'hC0_80_80_00_00_00_00_00_00_08_18_30_F0_60_C0_80_18_00_00_48_00_00_00_00_1C_3E_7F_7F_7F_7F_3E_1C), | ||
+ | .INIT_1B(256'hFF_01_7D_7D_7D_7D_7D_01_FF_01_41_41_41_41_7D_01_00_00_00_00_00_00_00_00_F0_F0_F0_E0_E0_E0_C0_C0), | ||
+ | .INIT_1C(256'hD0_B8_78_F0_F8_DC_BE_7E_07_03_00_01_01_07_1F_3F_3C_7E_F3_C1_C1_F3_7E_3C_3C_7E_F3_C1_C1_F3_7E_3C), | ||
+ | .INIT_1D(256'h07_07_0F_0F_0F_1F_1F_1F_FE_FE_C0_FC_FC_C0_FE_FE_20_30_98_36_4A_35_48_02_0A_09_05_01_00_00_00_00), | ||
+ | .INIT_1E(256'h05_05_05_06_07_07_07_06_A0_F0_F0_F0_F0_E0_E0_E0_3B_7B_7B_79_3D_3F_1F_07_80_C0_C0_A0_60_60_60_C0), | ||
+ | .INIT_1F(256'hC6_CE_DE_FE_FE_F6_E6_C6_FC_FC_FC_F8_F8_F0_C0_00_3F_3F_3F_1F_1F_0F_03_00_FC_C0_FE_E0_7F_80_F0_00), | ||
+ | .INIT_20(256'h98_68_F0_E0_C0_00_01_02_1F_1F_0E_05_03_00_80_40_C0_C0_E0_F0_F8_3C_06_03_07_2F_07_13_00_00_00_00), | ||
+ | .INIT_21(256'h10_30_E0_C0_00_00_00_00_0C_0F_07_03_10_08_00_00_17_37_37_17_17_F5_F6_F4_E8_E8_E8_E8_E8_AF_61_2F), | ||
+ | .INIT_22(256'h00_FC_7E_1E_0C_01_05_05_3C_7E_E7_DB_DB_E7_7E_3C_38_7C_FE_FE_FE_FE_7C_38_BB_7E_26_A2_7A_1A_07_07), | ||
+ | .INIT_23(256'h7E_FF_FF_FF_FF_FF_FF_7E_00_00_C0_30_98_E8_FC_FC_00_00_03_0E_1F_1F_3F_3F_00_70_F0_70_A0_40_F8_80), | ||
+ | .INIT_24(256'h02_01_00_C0_E0_F0_68_98_40_80_00_03_05_0E_1F_1F_00_00_00_00_C0_E0_F0_E0_C0_70_3C_1F_0F_07_03_01), | ||
+ | .INIT_25(256'hF8_FE_00_00_C0_E0_30_10_1F_7F_00_00_03_07_0F_0C_00_24_24_24_00_F4_F6_17_00_24_24_24_00_2F_6F_E8), | ||
+ | .INIT_26(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_74_48_61_F5_B6_60_F8_84_1A_7C_BB_9F_4F_02_79_15), | ||
+ | .INIT_27(256'hE0_58_AC_58_F0_20_00_00_07_1D_2A_55_6B_D4_A8_D9_00_00_00_00_00_00_00_00_A8_D8_AC_58_70_20_00_00), | ||
+ | .INIT_28(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_C0_C0_00_00_00), | ||
+ | .INIT_29(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_30(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_31(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_32(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_33(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_34(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_35(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_36(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_37(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_38(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_39(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00)) | ||
+ | aRAM ( | ||
+ | .DOB(adout), // Port B 8-bit Data Output | ||
+ | .ADDRA(aaddra), // Port A 11-bit Address Input | ||
+ | .ADDRB(aaddrb), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(adin), // Port A 8-bit Data Input | ||
+ | .DIPA(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(awe), // Port A Write Enable Input | ||
+ | .WEB(1'b0) // Port B Write Enable Input | ||
+ | ); | ||
+ | |||
+ | wire bwe; | ||
+ | wire [10:0]baddra; | ||
+ | wire [7:0]bdin; | ||
+ | wire [10:0]baddrb; | ||
+ | wire [7:0]bdout; | ||
+ | | ||
+ | assign bwe = (id >= 16'h9800 && id <= 16'h9FFF) ? write : 1'b0; | ||
+ | assign baddra = id - 16'h9800; | ||
+ | assign bdin = data; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_00(256'hF8_70_00_00_10_20_00_00_00_20_31_32_19_00_00_00_C0_00_00_20_40_00_00_00_41_62_64_32_00_00_00_00), | ||
+ | .INIT_01(256'h00_70_58_D8_EA_E2_F1_F0_E0_00_00_00_20_40_00_00_01_40_62_64_32_00_00_00_3C_42_A1_95_8D_9D_42_3C), | ||
+ | .INIT_02(256'h00_60_09_8E_0A_04_01_00_0E_80_D0_F0_70_20_00_00_70_01_0B_0F_0E_04_01_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_03(256'h10_30_60_60_40_00_00_00_C0_84_8C_4C_98_00_00_00_0F_07_00_00_08_04_00_00_04_00_50_F0_30_20_00_04), | ||
+ | .INIT_04(256'hE0_E0_E0_C2_C3_C7_FC_FE_00_03_37_73_F1_F1_94_61_20_30_30_60_F8_F0_E0_E0_3A_54_54_32_03_0B_07_03), | ||
+ | .INIT_05(256'h00_00_00_00_7C_FC_F8_78_E0_E0_F0_F8_FC_F0_EC_F8_03_43_6D_7E_2F_07_0B_07_91_00_00_18_00_24_00_18), | ||
+ | .INIT_06(256'h01_08_40_00_60_64_D8_08_E7_F3_90_0A_86_4E_5F_3F_3D_FB_09_50_64_72_FA_FC_08_10_24_15_1A_06_00_00), | ||
+ | .INIT_07(256'h00_00_00_00_00_08_08_10_80_F0_20_00_63_CF_FF_EF_07_07_0F_0F_1F_1D_1F_1F_00_80_08_00_06_48_03_10), | ||
+ | .INIT_08(256'h2C_70_60_E0_E0_F0_F0_F0_02_0C_00_0C_38_77_6F_1F_40_E0_E0_E0_F0_F0_F0_E0_00_00_00_00_00_00_01_01), | ||
+ | .INIT_09(256'h00_00_00_40_40_20_00_00_0C_36_36_77_E0_F0_F0_F0_00_0E_0E_07_07_03_01_01_00_00_00_00_10_91_F7_B5), | ||
+ | .INIT_0A(256'h00_00_08_10_00_00_08_20_08_30_30_30_70_60_E0_E1_10_0C_0C_0C_0E_12_29_5F_00_00_00_26_26_00_00_3F), | ||
+ | .INIT_0B(256'h00_00_00_00_00_00_00_00_70_30_20_70_F0_E0_C0_80_06_07_07_07_07_0F_0F_0F_00_00_10_06_00_00_00_00), | ||
+ | .INIT_0C(256'h00_00_00_00_01_00_0E_0E_00_00_00_00_00_00_00_00_04_08_10_06_0E_3C_7C_F0_00_00_10_28_04_28_10_00), | ||
+ | .INIT_0D(256'h00_00_00_24_14_18_00_00_00_00_00_00_00_00_00_00_00_01_06_00_03_07_0E_0C_00_00_00_00_00_C0_00_00), | ||
+ | .INIT_0E(256'h00_02_02_04_01_03_07_06_00_00_00_66_66_00_00_00_00_00_08_70_10_38_38_38_00_00_00_66_66_00_00_FF), | ||
+ | .INIT_0F(256'h01_00_25_21_20_11_00_00_E0_00_24_80_00_40_00_00_03_93_17_EE_50_4A_00_40_00_02_0C_00_04_3C_78_30), | ||
+ | .INIT_10(256'hC4_DA_BA_7C_F0_E0_D0_E0_07_07_07_07_1F_3F_3F_1F_98_04_3C_88_60_D0_E0_C0_07_0F_0F_07_1C_0F_07_07), | ||
+ | .INIT_11(256'h03_02_02_01_F1_E9_C5_83_00_00_00_00_07_0F_0F_07_00_C0_F8_3C_FC_F8_80_80_07_07_1F_7E_FF_FF_27_7F), | ||
+ | .INIT_12(256'h00_00_00_00_E0_F0_F0_E0_C0_E0_E0_C0_DC_FF_FF_F3_07_07_0F_1F_1F_1F_1F_0F_00_00_18_3C_DC_F0_FC_F0), | ||
+ | .INIT_13(256'h00_11_1F_17_11_11_00_00_30_25_52_38_91_68_C8_E0_00_08_04_08_1C_38_38_38_00_00_18_3C_3C_18_00_00), | ||
+ | .INIT_14(256'hF8_F0_E0_00_00_00_00_00_27_0F_0B_00_10_08_00_00_BC_38_F8_F0_C0_00_00_00_0F_07_03_01_03_00_00_00), | ||
+ | .INIT_15(256'h00_1A_04_16_14_0A_19_00_40_20_00_00_00_00_00_00_7E_FF_FF_FF_FF_FF_FE_F8_1F_9E_5F_1F_0F_07_03_00), | ||
+ | .INIT_16(256'h00_00_00_00_00_00_00_00_00_0E_06_0E_1A_30_20_00_00_17_14_54_57_B4_17_00_00_49_49_49_49_49_E9_00), | ||
+ | .INIT_17(256'hE0_40_C0_00_F0_C0_40_E0_01_00_10_44_45_10_00_01_00_00_00_00_00_00_00_00_24_42_99_3C_3C_99_42_24), | ||
+ | .INIT_18(256'hFE_FE_FE_FE_FC_7C_FC_F8_1F_0B_07_1B_3D_7E_7F_6F_00_90_78_F8_FC_FC_7C_FC_00_0B_1F_07_23_36_1E_0F), | ||
+ | .INIT_19(256'h3C_7E_C3_DF_DF_DF_7E_3C_00_00_00_00_00_00_00_80_00_00_80_C8_9C_AE_BE_FE_00_00_0D_07_03_07_07_1F), | ||
+ | .INIT_1A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_80_00_00_78_78_78_78_78_30_00_00_00_00_00_00_00_20_10_00), | ||
+ | .INIT_1B(256'h00_FE_FE_FE_FE_FE_FE_FE_00_FE_82_82_82_82_82_FE_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_1C(256'h20_40_80_00_D8_FC_FE_FE_00_00_00_00_01_07_1F_3F_00_20_00_0C_0C_00_20_00_00_20_00_00_00_00_20_00), | ||
+ | .INIT_1D(256'h07_07_0F_0F_0F_1F_1F_1F_00_FE_C0_C0_FC_C0_C0_FE_40_30_50_22_38_1E_04_00_19_04_16_05_0A_00_00_00), | ||
+ | .INIT_1E(256'h01_01_01_00_00_00_00_00_C0_C0_C0_A0_00_80_E0_E0_1F_0F_2F_27_03_00_01_01_80_C0_C0_C0_80_80_80_80), | ||
+ | .INIT_1F(256'h00_C6_CE_DE_FE_F6_E6_C6_FC_FC_FC_F8_F8_70_C0_00_2F_2F_33_11_19_0E_03_00_FC_E0_FE_F0_7F_00_00_00), | ||
+ | .INIT_20(256'h00_00_08_04_02_11_09_06_08_0C_14_21_44_88_90_60_9C_9C_C8_E0_30_C8_04_02_7B_77_3B_3C_1F_07_00_00), | ||
+ | .INIT_21(256'hC2_02_02_02_02_04_04_F8_40_40_42_40_50_28_20_1F_E7_07_C7_07_E7_07_06_04_E7_E4_E7_E4_E7_E0_6E_20), | ||
+ | .INIT_22(256'hFC_02_00_00_00_01_01_01_00_00_00_18_18_00_00_00_38_7C_FE_FE_FE_BE_5C_38_00_00_00_00_08_00_00_00), | ||
+ | .INIT_23(256'h24_66_E7_18_18_E7_66_24_00_00_C0_30_98_E8_FC_FC_00_00_03_0E_1F_1F_3F_3F_F0_80_00_00_80_40_F8_C0), | ||
+ | .INIT_24(256'h06_09_11_22_04_08_00_00_60_90_88_44_20_00_00_00_00_C0_F0_38_18_CC_E4_C4_40_23_10_2C_37_7B_7D_7F), | ||
+ | .INIT_25(256'hF8_FE_82_02_02_02_02_C2_1F_7F_41_40_40_42_40_40_FE_00_24_24_00_04_06_07_7F_00_24_24_00_20_60_E0), | ||
+ | .INIT_26(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_80_00_00_00_00_00_20_00_08_02_00_00), | ||
+ | .INIT_27(256'h40_08_04_08_50_20_80_C0_05_08_00_00_41_80_01_8A_C0_80_00_00_00_00_00_00_03_89_04_08_50_20_00_00), | ||
+ | .INIT_28(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_C0_C0_00_00_00), | ||
+ | .INIT_29(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_2F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_30(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_31(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_32(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_33(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_34(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_35(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_36(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_37(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_38(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_39(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00), | ||
+ | .INIT_3F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00)) | ||
+ | bRAM ( | ||
+ | .DOB(bdout), // Port B 8-bit Data Output | ||
+ | .ADDRA(baddra), // Port A 11-bit Address Input | ||
+ | .ADDRB(baddrb), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(bdin), // Port A 8-bit Data Input | ||
+ | .DIPA(1'b0), // 1-bit Parity | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(bwe), // Port A Write Enable Input | ||
+ | .WEB(1'b0) // Port B Write Enable Input | ||
+ | ); | ||
+ | |||
+ | //////////////////////////////////////////Display Buffer/////////////////////////////////////////// | ||
+ | assign nxt256pix = next256pixel[9:1]; | ||
+ | assign cur256line = currline ? ((currline + 1'b1) / 2) : 8'h00; | ||
+ | assign nxt256line = (vcount > 31 && vcount < 512) ? cur256line + 1'b1 : 8'h00; | ||
+ | | ||
+ | //No color out if not in drawing area. | ||
+ | assign lbrstb = (cur256line && nxt256pix) ? 1'b0 : 1'b1; | ||
+ | | ||
+ | //Select between odd line buffer and even line buffer | ||
+ | assign lbaddrb[8] = (cur256line % 2 == 1) ? 1'b0 : 1'b1; | ||
+ | assign lbaddrb[7:0] = nxt256pix - 1'b1; | ||
+ | |||
+ | |||
+ | //////////////////////////////////////////Buffer Fill FSM////////////////////////////////////////// | ||
+ | wire leavewait; | ||
+ | wire [1:0]bgatbits; | ||
+ | wire bgptabit; | ||
+ | wire bgptbbit; | ||
+ | reg [4:0]State = 3'b000; | ||
+ | reg [4:0]NextState = 3'b000; | ||
+ | reg [8:0]pix256draw = 9'h000; | ||
+ | |||
+ | //Sprite registers and wires. | ||
+ | wire spriteinrange; | ||
+ | wire [7:0]spritex; | ||
+ | wire [7:0]spritey; | ||
+ | wire [7:0]spriteptrn; | ||
+ | wire [1:0]upal; | ||
+ | wire hmirror; | ||
+ | wire vmirror; | ||
+ | wire back; | ||
+ | wire [2:0]invert; | ||
+ | wire [2:0]normal; | ||
+ | wire [10:0]address; | ||
+ | reg spbita = 1'b0; | ||
+ | reg spbitb = 1'b0; | ||
+ | reg [7:0]bfaddr = 8'h00; | ||
+ | reg bs = 1'b0; | ||
+ | reg [7:0]pix = 8'h00; | ||
+ | | ||
+ | always @(State, leavewait, pix256draw, currsprite, spriteinrange, back) begin | ||
+ | case(State) | ||
+ | WAIT : NextState = leavewait ? NTAT : WAIT; | ||
+ | NTAT : NextState = PTAB; | ||
+ | PTAB : NextState = BUFF; | ||
+ | BUFF : NextState = (pix256draw && (pix256draw < 256)) ? NTAT : NEXT; | ||
+ | NEXT : NextState = SPRAM; | ||
+ | SPRAM: NextState = spriteinrange ? SAB : | ||
+ | (currsprite == 256 && !spriteinrange) ? WAIT : | ||
+ | NEXT; | ||
+ | SAB : NextState = back ? WRIT0 : BUFF0; | ||
+ | WRIT0: NextState = WRIT1; | ||
+ | WRIT1: NextState = WRIT2; | ||
+ | WRIT2: NextState = WRIT3; | ||
+ | WRIT3: NextState = WRIT4; | ||
+ | WRIT4: NextState = WRIT5; | ||
+ | WRIT5: NextState = WRIT6; | ||
+ | WRIT6: NextState = WRIT7; | ||
+ | WRIT7: NextState = BUFF0; | ||
+ | BUFF0: NextState = BUFF1; | ||
+ | BUFF1: NextState = BUFF2; | ||
+ | BUFF2: NextState = BUFF3; | ||
+ | BUFF3: NextState = BUFF4; | ||
+ | BUFF4: NextState = BUFF5; | ||
+ | BUFF5: NextState = BUFF6; | ||
+ | BUFF6: NextState = BUFF7; | ||
+ | BUFF7: NextState = (currsprite == 256) ? WAIT : NEXT; | ||
+ | default : NextState = WAIT; | ||
+ | endcase | ||
+ | end | ||
+ | | ||
+ | always @(posedge clk) begin | ||
+ | if(!nxt256line) | ||
+ | State <= WAIT; | ||
+ | else | ||
+ | State <= NextState; | ||
+ | | ||
+ | if(NextState == WAIT) begin | ||
+ | lbwe = 1'b0; | ||
+ | pix256draw <= 9'h000; | ||
+ | currsprite = 9'h000; | ||
+ | bfaddr = 8'h00; | ||
+ | bs <= 1'b0; | ||
+ | end | ||
+ | | ||
+ | if(NextState == NTAT) begin | ||
+ | lbwe = 1'b0; | ||
+ | pix256draw <= pix256draw + 1; | ||
+ | end | ||
+ | | ||
+ | if(NextState == PTAB) begin | ||
+ | lbwe = 1'b0; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF) begin | ||
+ | lbwe = 1'b1; | ||
+ | end | ||
+ | | ||
+ | if(NextState == NEXT) begin | ||
+ | lbwe = 1'b0; | ||
+ | pix <= 8'h00; | ||
+ | pix256draw <= 9'h000; | ||
+ | currsprite = currsprite + 1; | ||
+ | bfaddr = 8'h00; | ||
+ | bs <= 1'b1; | ||
+ | end | ||
+ | | ||
+ | if(NextState == SAB) begin | ||
+ | bfaddr = hmirror ? spritex + 7 : spritex; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT0) begin | ||
+ | bfaddr = hmirror ? spritex + 6 : spritex + 1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT1) begin | ||
+ | bfaddr = hmirror ? spritex + 5 : spritex + 2; | ||
+ | if(lbcheck) | ||
+ | pix[0] <= 1'b1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT2) begin | ||
+ | bfaddr = hmirror ? spritex + 4 : spritex + 3; | ||
+ | if(lbcheck) | ||
+ | pix[1] <= 1'b1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT3) begin | ||
+ | bfaddr = hmirror ? spritex + 3 : spritex + 4; | ||
+ | if(lbcheck) | ||
+ | pix[2] <= 1'b1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT4) begin | ||
+ | bfaddr = hmirror ? spritex + 2 : spritex + 5; | ||
+ | if(lbcheck) | ||
+ | pix[3] <= 1'b1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT5) begin | ||
+ | bfaddr = hmirror ? spritex + 1 : spritex + 6; | ||
+ | if(lbcheck) | ||
+ | pix[4] <= 1'b1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT6) begin | ||
+ | bfaddr = hmirror ? spritex : spritex + 7; | ||
+ | if(lbcheck) | ||
+ | pix[5] <= 1'b1; | ||
+ | end | ||
+ | |||
+ | if(NextState == WRIT7) begin | ||
+ | if(lbcheck) | ||
+ | pix[6] <= 1'b1; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF0) begin | ||
+ | if((!adout[7] && !bdout[7]) || (back && pix[0])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | if(lbcheck) | ||
+ | pix[7] <= 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 7 : spritex; | ||
+ | spbita = adout[7]; | ||
+ | spbitb = bdout[7]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF1) begin | ||
+ | if((!adout[6] && !bdout[6]) || (back && pix[1])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 6 : spritex + 1; | ||
+ | spbita = adout[6]; | ||
+ | spbitb = bdout[6]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF2) begin | ||
+ | if((!adout[5] && !bdout[5]) || (back && pix[2])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 5 : spritex + 2; | ||
+ | spbita = adout[5]; | ||
+ | spbitb = bdout[5]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF3) begin | ||
+ | if((!adout[4] && !bdout[4]) || (back && pix[3])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 4 : spritex + 3; | ||
+ | spbita = adout[4]; | ||
+ | spbitb = bdout[4]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF4) begin | ||
+ | if((!adout[3] && !bdout[3]) || (back && pix[4])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 3 : spritex + 4; | ||
+ | spbita = adout[3]; | ||
+ | spbitb = bdout[3]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF5) begin | ||
+ | if((!adout[2] && !bdout[2]) || (back && pix[5])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 2 : spritex + 5; | ||
+ | spbita = adout[2]; | ||
+ | spbitb = bdout[2]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF6) begin | ||
+ | if((!adout[1] && !bdout[1]) || (back && pix[6])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex + 1 : spritex + 6; | ||
+ | spbita = adout[1]; | ||
+ | spbitb = bdout[1]; | ||
+ | end | ||
+ | | ||
+ | if(NextState == BUFF7) begin | ||
+ | if((!adout[0] && !bdout[0]) || (back && pix[7])) | ||
+ | lbwe = 1'b0; | ||
+ | else | ||
+ | lbwe = 1'b1; | ||
+ | bfaddr = hmirror ? spritex : spritex + 7; | ||
+ | spbita = adout[0]; | ||
+ | spbitb = bdout[0]; | ||
+ | end | ||
+ | end | ||
+ | | ||
+ | //Determine when it is time to go from WAIT to NTAT. | ||
+ | assign leavewait = (nxt256line && (vcount % 2 == 1'b0) && hcount < 10'h002) ? 1'b1 : 1'b0; | ||
+ | //Name table address. | ||
+ | assign ntaddra = nxt256line ? (32 * ((nxt256line - 1) / 8) + ((pix256draw - 1) / 8)) : 10'h000; | ||
+ | //Attribute table address. | ||
+ | assign bgataddra = nxt256line ? (8 * ((nxt256line - 1) / 8) + ((pix256draw - 1) / 32)) : 10'h000; | ||
+ | //Pattern table addresses. | ||
+ | assign bgptaaddra = pix256draw ? (8 * ntdout + (nxt256line - 1) % 8) :10'h000; | ||
+ | assign bgptbaddra = pix256draw ? (8 * ntdout + (nxt256line - 1) % 8) :10'h000; | ||
+ | //Attribute table bits for palette MUX. | ||
+ | assign bgatbits = (ntaddra % 4 == 2'b00) ? bgatdout[7:6] : | ||
+ | (ntaddra % 4 == 2'b01) ? bgatdout[5:4] : | ||
+ | (ntaddra % 4 == 2'b10) ? bgatdout[3:2] : | ||
+ | bgatdout[1:0]; | ||
+ | //Pattern table B bit for palette MUX. | ||
+ | assign bgptbbit = bgptbdout[~(pix256draw - 1) % 8]; | ||
+ | //Pattern table A bit for palette MUX. | ||
+ | assign bgptabit = bgptadout[~(pix256draw - 1) % 8]; | ||
+ | //Break down the sprite data into its separate parts. | ||
+ | assign spritex = spdout[31:24]; | ||
+ | assign spritey = spdout[7:0]; | ||
+ | assign spriteptrn = spdout[15:8]; | ||
+ | assign spriteinrange = (currsprite && (nxt256line - 1'b1 >= spritey) && | ||
+ | nxt256line - 1'b1 - spritey < 8) ? 1'b1 : 1'b0; | ||
+ | assign upal = spdout[17:16]; | ||
+ | assign hmirror = spdout[22]; | ||
+ | assign vmirror = spdout[23]; | ||
+ | assign back = spdout[21]; | ||
+ | //Get sprite graphic info with or without vertical mirroring. | ||
+ | assign invert = ~(nxt256line - 1'b1 - spritey); | ||
+ | assign normal = (nxt256line - 1'b1 - spritey); | ||
+ | assign address = spriteptrn * 8; | ||
+ | assign aaddrb = address + (vmirror ? invert : normal); | ||
+ | assign baddrb = aaddrb; | ||
+ | //Palette MUX | ||
+ | assign lbdin = ({bs, bgatbits, bgptbbit, bgptabit} == 5'h00) ? bgpal0 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h01) ? bgpal1 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h02) ? bgpal2 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h03) ? bgpal3 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h04) ? bgpal4 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h05) ? bgpal5 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h06) ? bgpal6 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h07) ? bgpal7 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h08) ? bgpal8 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h09) ? bgpal9 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h0A) ? bgpal10 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h0B) ? bgpal11 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h0C) ? bgpal12 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h0D) ? bgpal13 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h0E) ? bgpal14 : | ||
+ | ({bs, bgatbits, bgptbbit, bgptabit} == 5'h0F) ? bgpal15 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h10) ? sppal0 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h11) ? sppal1 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h12) ? sppal2 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h13) ? sppal3 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h14) ? sppal4 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h15) ? sppal5 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h16) ? sppal6 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h17) ? sppal7 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h18) ? sppal8 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h19) ? sppal9 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h1A) ? sppal10 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h1B) ? sppal11 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h1C) ? sppal12 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h1D) ? sppal13 : | ||
+ | ({bs, upal , spbitb , spbita } == 5'h1E) ? sppal14 : | ||
+ | sppal15; | ||
+ | | ||
+ | //Write to odd or even line buffer. | ||
+ | assign lbaddra[8] = ~lbaddrb[8]; | ||
+ | //Line buffer address. | ||
+ | assign lbaddra[7:0] = bs ? bfaddr : pix256draw - 1'b1; | ||
+ | //Determine final pixel color. | ||
+ | assign colorout = (hcount < 112 || hcount > 623 || !currline) ? 8'h00 : | ||
+ | !lbdout ? basecolor : | ||
+ | lbdout; | ||
+ | |||
+ | ////////////////////////////////////////////Base Timing//////////////////////////////////////////// | ||
+ | always @(posedge clk25MHz) begin | ||
+ | //Horizontal timing. | ||
+ | hcount <= hcount + 1'b1; | ||
+ | if(hcount == 704) | ||
+ | hsync <= 1'b0; | ||
+ | if(hcount == 800) begin | ||
+ | hcount <= 10'h001; | ||
+ | hsync <= 1'b1; | ||
+ | vcount <= vcount + 1'b1; | ||
+ | end | ||
+ | | ||
+ | //Vertical timing. | ||
+ | if(vcount == 523) | ||
+ | vsync <= 1'b0; | ||
+ | if(vcount == 525) begin | ||
+ | vcount <= 10'h001; | ||
+ | vsync <= 1'b1; | ||
+ | end | ||
+ | | ||
+ | //Visible pixel counters. | ||
+ | if(hcount >= 47 && hcount <= 686) | ||
+ | nextpixel <= nextpixel + 1; | ||
+ | else | ||
+ | nextpixel <= 0; | ||
+ | if(hcount >= 46 && hcount <= 685) | ||
+ | nextpixel2 <= nextpixel2 + 1; | ||
+ | else | ||
+ | nextpixel2 <= 0; | ||
+ | | ||
+ | //Visible line counters. | ||
+ | if(vcount >= 33 && hcount == 800) | ||
+ | currline <= currline + 1; | ||
+ | if(vcount >= 513 && hcount == 800) | ||
+ | currline <= 0; | ||
+ | |||
+ | //256 resolution pixel counter. | ||
+ | if(hcount >= 109 && hcount <= 621) | ||
+ | next256pixel <= next256pixel + 1; | ||
+ | else | ||
+ | next256pixel <= 1'b0; | ||
+ | | ||
+ | //Vertical blank. | ||
+ | if(vcount == 514) | ||
+ | vblank <= 1'b1; | ||
+ | else | ||
+ | vblank <= 1'b0; | ||
+ | | ||
+ | //Draw linebuffer data to screen. | ||
+ | vga <= colorout; | ||
+ | end | ||
+ | | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### uart.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module uart( | ||
+ | input clk, | ||
+ | input reset, | ||
+ | input [15:0] id, | ||
+ | input [15:0] din, | ||
+ | input write, | ||
+ | input rx, | ||
+ | output reg tx = 1'b1, | ||
+ | output [7:0]dout, | ||
+ | output reg [11:0]rxcount = 12'h000, | ||
+ | output reg [11:0]txcount = 12'h000 | ||
+ | ); | ||
+ | | ||
+ | parameter initbaud = 16'd5244; //Default 9600 baud. | ||
+ | | ||
+ | parameter setBaud = 16'h0200; | ||
+ | parameter txStoreByte = 16'h0201; | ||
+ | parameter txFlush = 16'h0202; | ||
+ | parameter txPurge = 16'h0203; | ||
+ | parameter rxNextByte = 16'h0204; | ||
+ | parameter rxPurge = 16'h0205; | ||
+ | | ||
+ | parameter TXREADY = 4'h0; | ||
+ | parameter TXSYNC = 4'h1; | ||
+ | parameter TXSTART = 4'h2; | ||
+ | parameter TXB0 = 4'h3; | ||
+ | parameter TXB1 = 4'h4; | ||
+ | parameter TXB2 = 4'h5; | ||
+ | parameter TXB3 = 4'h6; | ||
+ | parameter TXB4 = 4'h7; | ||
+ | parameter TXB5 = 4'h8; | ||
+ | parameter TXB6 = 4'h9; | ||
+ | parameter TXB7 = 4'hA; | ||
+ | parameter TXSTOP = 4'hB; | ||
+ | | ||
+ | parameter RXREADY = 4'h0; | ||
+ | parameter RXSTART = 4'h1; | ||
+ | parameter RXB0 = 4'h2; | ||
+ | parameter RXB1 = 4'h3; | ||
+ | parameter RXB2 = 4'h4; | ||
+ | parameter RXB3 = 4'h5; | ||
+ | parameter RXB4 = 4'h6; | ||
+ | parameter RXB5 = 4'h7; | ||
+ | parameter RXB6 = 4'h8; | ||
+ | parameter RXB7 = 4'h9; | ||
+ | parameter RXSTOP = 4'hA; | ||
+ | parameter RXSTORE = 4'hB; | ||
+ | | ||
+ | reg [3:0]txstate = TXREADY; | ||
+ | reg [3:0]txnextstate = TXREADY; | ||
+ | | ||
+ | reg [3:0]rxstate = RXREADY; | ||
+ | reg [3:0]rxnextstate = RXREADY; | ||
+ | |||
+ | //baudreg calculation is as follows: | ||
+ | //Clock frequency / desired baud rate / 2. | ||
+ | reg [15:0]txbaudreg = initbaud; | ||
+ | reg [17:0]txcountreg = 18'h00000; //Counts system clock cycles to generate baud clock. | ||
+ | reg baudclock = 1'b0; //Used to time data out. | ||
+ | | ||
+ | reg [15:0]rxbaudcntr = 16'h0000; | ||
+ | | ||
+ | reg [10:0]txstartreg = 11'h000; | ||
+ | reg [10:0]txendreg = 11'h000; //Tx buffer regs. | ||
+ | | ||
+ | reg [10:0]rxstartreg = 11'h000; | ||
+ | reg [10:0]rxendreg = 11'h000; //Rx buffer regs. | ||
+ | | ||
+ | reg baudthis = 1'b0; | ||
+ | reg baudlast = 1'b0; | ||
+ | reg baudpostrans = 1'b0; | ||
+ | | ||
+ | reg rxthis = 1'b0; | ||
+ | reg rxlast = 1'b0; | ||
+ | reg rxnegtrans = 1'b0; | ||
+ | | ||
+ | reg nbwait = 1'b0; //Wait while user retrieves received byte. | ||
+ | | ||
+ | reg [7:0]txreg = 8'h00; | ||
+ | reg [7:0]rxreg = 8'h00; | ||
+ | |||
+ | wire txwe; | ||
+ | wire rxwe; | ||
+ | | ||
+ | wire [7:0]txdout; | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_A(9'h000), // Value of output RAM registers on Port A at startup | ||
+ | .INIT_B(9'h000), // Value of output RAM registers on Port B at startup | ||
+ | .SRVAL_A(9'h000), // Port A output value upon SSR assertion | ||
+ | .SRVAL_B(9'h000), // Port B output value upon SSR assertion | ||
+ | .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .WRITE_MODE_B("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .SIM_COLLISION_CHECK("ALL")) // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL" | ||
+ | TXRAM ( | ||
+ | .DOA(txdout), // Port A 8-bit Data Output | ||
+ | .DOB(), // Port B 16-bit Data Output | ||
+ | .ADDRA(txstartreg), // Port A 11-bit Address Input | ||
+ | .ADDRB(txendreg), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(), // Port A 8-bit Data Input | ||
+ | .DIB(din[7:0]), // Port-B 8-bit Data Input | ||
+ | .DIPA(1'b0), // Port A 1-bit parity Input | ||
+ | .DIPB(1'b0), // Port B 1-bit parity Input | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(1'b0), // Port A Write Enable Input | ||
+ | .WEB(txwe) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | RAMB16_S9_S9 #( | ||
+ | .INIT_A(9'h000), // Value of output RAM registers on Port A at startup | ||
+ | .INIT_B(9'h000), // Value of output RAM registers on Port B at startup | ||
+ | .SRVAL_A(9'h000), // Port A output value upon SSR assertion | ||
+ | .SRVAL_B(9'h000), // Port B output value upon SSR assertion | ||
+ | .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .WRITE_MODE_B("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE | ||
+ | .SIM_COLLISION_CHECK("ALL")) // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL" | ||
+ | RXRAM ( | ||
+ | .DOA(), // Port A 8-bit Data Output | ||
+ | .DOB(dout), // Port B 16-bit Data Output | ||
+ | .ADDRA(rxendreg), // Port A 11-bit Address Input | ||
+ | .ADDRB(rxstartreg), // Port B 11-bit Address Input | ||
+ | .CLKA(clk), // Port A Clock | ||
+ | .CLKB(clk), // Port B Clock | ||
+ | .DIA(rxreg), // Port A 8-bit Data Input | ||
+ | .DIB(), // Port-B 8-bit Data Input | ||
+ | .DIPA(1'b0), // Port A 1-bit parity Input | ||
+ | .DIPB(1'b0), // Port B 1-bit parity Input | ||
+ | .ENA(1'b1), // Port A RAM Enable Input | ||
+ | .ENB(1'b1), // Port B RAM Enable Input | ||
+ | .SSRA(1'b0), // Port A Synchronous Set/Reset Input | ||
+ | .SSRB(1'b0), // Port B Synchronous Set/Reset Input | ||
+ | .WEA(rxwe), // Port A Write Enable Input | ||
+ | .WEB(1'b0) // Port B Write Enable Input | ||
+ | ); | ||
+ | | ||
+ | assign txwe = (write && id == txStoreByte) ? 1'b1 : 1'b0; | ||
+ | assign rxwe = (rxstate == RXSTOP) ? 1'b1 : 1'b0; | ||
+ | | ||
+ | always @(posedge clk) begin | ||
+ | txcountreg <= txcountreg + 1'b1; | ||
+ | txstate <= txnextstate; | ||
+ | rxstate <= rxnextstate; | ||
+ | | ||
+ | //Keep track of baud clock edges. | ||
+ | baudthis <= baudclock; | ||
+ | baudlast <= baudthis; | ||
+ | | ||
+ | //Keep track of rx edges | ||
+ | rxthis <= rx; | ||
+ | rxlast <= rxthis; | ||
+ | | ||
+ | //Keep track of rx negative edge. | ||
+ | if(rxlast && !rxthis) | ||
+ | rxnegtrans <= 1'b1; | ||
+ | else | ||
+ | rxnegtrans <= 1'b0; | ||
+ | | ||
+ | //Keep track of baud clock positive edge. | ||
+ | if(!baudlast && baudthis) | ||
+ | baudpostrans <= 1'b1; | ||
+ | else | ||
+ | baudpostrans <= 1'b0; | ||
+ | | ||
+ | //Reset all registers to defaults. | ||
+ | if(reset) begin | ||
+ | txcountreg <= 18'h00000; | ||
+ | rxstartreg <= 11'h000; | ||
+ | txstartreg <= 11'h000; | ||
+ | txbaudreg <= initbaud; | ||
+ | baudclock <= 1'b0; | ||
+ | txendreg <= 11'h000; | ||
+ | rxendreg <= 11'h000; | ||
+ | txstate <= TXREADY; | ||
+ | rxstate <= RXREADY; | ||
+ | txcount <= 10'h000; | ||
+ | rxcount <= 10'h000; | ||
+ | txreg <= 8'h00; | ||
+ | rxreg <= 8'h00; | ||
+ | tx <= 1'b1; | ||
+ | end | ||
+ | | ||
+ | if(txstate == TXREADY || txstate == TXSYNC) | ||
+ | tx <= 1'b1; | ||
+ | | ||
+ | if(txcountreg == txbaudreg) begin | ||
+ | baudclock <= ~baudclock; | ||
+ | txcountreg <= 18'h00000; | ||
+ | end | ||
+ | |||
+ | if(id == setBaud && write) | ||
+ | txbaudreg <= din; | ||
+ | | ||
+ | if(id == txStoreByte && write) begin | ||
+ | txendreg <= txendreg + 1; | ||
+ | if(txcount < 2048) //Still room in buffer. | ||
+ | txcount <= txcount + 1; | ||
+ | else //No room in buffer. Overwrite oldest byte. | ||
+ | txstartreg <= txstartreg + 1; | ||
+ | end | ||
+ | | ||
+ | if(nbwait) begin | ||
+ | rxstartreg <= rxstartreg + 1; | ||
+ | rxcount <= rxcount - 1; | ||
+ | nbwait <= nbwait + 1; | ||
+ | end | ||
+ | | ||
+ | if(id == rxNextByte && write && rxcount) begin | ||
+ | nbwait <= 1'b1; | ||
+ | end | ||
+ | | ||
+ | if(id == txPurge && write) begin | ||
+ | txendreg <= 0; | ||
+ | txstartreg <= 0; | ||
+ | txcount <= 0; | ||
+ | end | ||
+ | | ||
+ | if(id == rxPurge && write) begin | ||
+ | rxendreg <= 0; | ||
+ | rxstartreg <= 0; | ||
+ | rxcount <= 0; | ||
+ | end | ||
+ | |||
+ | if(txstate == TXSTART) begin | ||
+ | txreg <= txdout; | ||
+ | tx <= 1'b0; | ||
+ | end | ||
+ | | ||
+ | if(txstate == TXB0) | ||
+ | tx <= txreg[0]; | ||
+ | | ||
+ | if(txstate == TXB1) | ||
+ | tx <= txreg[1]; | ||
+ | | ||
+ | if(txstate == TXB2) | ||
+ | tx <= txreg[2]; | ||
+ | | ||
+ | if(txstate == TXB3) | ||
+ | tx <= txreg[3]; | ||
+ | | ||
+ | if(txstate == TXB4) | ||
+ | tx <= txreg[4]; | ||
+ | | ||
+ | if(txstate == TXB5) | ||
+ | tx <= txreg[5]; | ||
+ | | ||
+ | if(txstate == TXB6) | ||
+ | tx <= txreg[6]; | ||
+ | | ||
+ | if(txstate == TXB7) | ||
+ | tx <= txreg[7]; | ||
+ | | ||
+ | if(txstate == TXSTOP) begin | ||
+ | tx <= 1'b1; | ||
+ | end | ||
+ | | ||
+ | if(txnextstate == TXSTOP && baudpostrans) begin | ||
+ | txcount <= txcount - 1; | ||
+ | txstartreg <= txstartreg + 1; | ||
+ | end | ||
+ | |||
+ | if(rxbaudcntr) | ||
+ | rxbaudcntr <= rxbaudcntr - 1; | ||
+ | | ||
+ | if(rxstate == RXREADY && rxnextstate == RXSTART) | ||
+ | rxbaudcntr <= txbaudreg * 2 + txbaudreg; | ||
+ | | ||
+ | if(rxstate == RXSTART && rxnextstate == RXB0) begin | ||
+ | rxreg[0] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB0 && rxnextstate == RXB1) begin | ||
+ | rxreg[1] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB1 && rxnextstate == RXB2) begin | ||
+ | rxreg[2] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB2 && rxnextstate == RXB3) begin | ||
+ | rxreg[3] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB3 && rxnextstate == RXB4) begin | ||
+ | rxreg[4] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB4 && rxnextstate == RXB5) begin | ||
+ | rxreg[5] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB5 && rxnextstate == RXB6) begin | ||
+ | rxreg[6] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXB6 && rxnextstate == RXB7) begin | ||
+ | rxreg[7] <= rx; | ||
+ | rxbaudcntr <= txbaudreg * 2; | ||
+ | end | ||
+ | | ||
+ | if(rxstate == RXSTOP && rxnextstate == RXSTORE) begin | ||
+ | rxendreg <= rxendreg + 1; | ||
+ | if(rxcount < 1024) | ||
+ | rxcount <= rxcount + 1; | ||
+ | end | ||
+ | end | ||
+ | | ||
+ | always @(*) begin //Transmit finite state machine. | ||
+ | case(txstate) | ||
+ | TXREADY : txnextstate = reset ? TXREADY : | ||
+ | (id == txFlush && write && txcount) ? TXSYNC : | ||
+ | TXREADY; | ||
+ | TXSYNC : txnextstate = baudpostrans ? TXSTART : TXSYNC; | ||
+ | TXSTART : txnextstate = baudpostrans ? TXB0 : TXSTART; | ||
+ | TXB0 : txnextstate = baudpostrans ? TXB1 : TXB0; | ||
+ | TXB1 : txnextstate = baudpostrans ? TXB2 : TXB1; | ||
+ | TXB2 : txnextstate = baudpostrans ? TXB3 : TXB2; | ||
+ | TXB3 : txnextstate = baudpostrans ? TXB4 : TXB3; | ||
+ | TXB4 : txnextstate = baudpostrans ? TXB5 : TXB4; | ||
+ | TXB5 : txnextstate = baudpostrans ? TXB6 : TXB5; | ||
+ | TXB6 : txnextstate = baudpostrans ? TXB7 : TXB6; | ||
+ | TXB7 : txnextstate = baudpostrans ? TXSTOP : TXB7; | ||
+ | TXSTOP : txnextstate = (baudpostrans && txcount) ? TXSTART : | ||
+ | baudpostrans ? TXREADY : | ||
+ | TXSTOP; | ||
+ | default : txnextstate = TXREADY; | ||
+ | endcase | ||
+ | end | ||
+ | | ||
+ | always @(*) begin //Receive finite state machine. | ||
+ | case(rxstate) | ||
+ | RXREADY : rxnextstate = rxnegtrans ? RXSTART : RXREADY; | ||
+ | RXSTART : rxnextstate = rxbaudcntr ? RXSTART : RXB0; | ||
+ | RXB0 : rxnextstate = rxbaudcntr ? RXB0 : RXB1; | ||
+ | RXB1 : rxnextstate = rxbaudcntr ? RXB1 : RXB2; | ||
+ | RXB2 : rxnextstate = rxbaudcntr ? RXB2 : RXB3; | ||
+ | RXB3 : rxnextstate = rxbaudcntr ? RXB3 : RXB4; | ||
+ | RXB4 : rxnextstate = rxbaudcntr ? RXB4 : RXB5; | ||
+ | RXB5 : rxnextstate = rxbaudcntr ? RXB5 : RXB6; | ||
+ | RXB6 : rxnextstate = rxbaudcntr ? RXB6 : RXB7; | ||
+ | RXB7 : rxnextstate = rxbaudcntr ? RXB7 : RXSTOP; | ||
+ | RXSTOP : rxnextstate = RXSTORE; | ||
+ | RXSTORE : rxnextstate = RXREADY; | ||
+ | default : rxnextstate = RXREADY; | ||
+ | endcase | ||
+ | end | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### ROMcontroller.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module ROMcontroller( | ||
+ | input [15:0]id, | ||
+ | input [15:0]ain, | ||
+ | input clk, | ||
+ | output reg [10:0]aout = 11'h000 | ||
+ | ); | ||
+ | | ||
+ | always @(posedge clk) begin | ||
+ | if(id == 16'h0000) | ||
+ | aout <= {3'b000, ain[7:0]}; | ||
+ | if(id == 16'h0001) | ||
+ | aout <= {3'b001, ain[7:0]}; | ||
+ | if(id == 16'h0002) | ||
+ | aout <= {3'b010, ain[7:0]}; | ||
+ | if(id == 16'h0003) | ||
+ | aout <= {3'b011, ain[7:0]}; | ||
+ | if(id == 16'h0004) | ||
+ | aout <= {3'b100, ain[7:0]}; | ||
+ | if(id == 16'h0005) | ||
+ | aout <= {3'b101, ain[7:0]}; | ||
+ | if(id == 16'h0006) | ||
+ | aout <= {3'b110, ain[7:0]}; | ||
+ | if(id == 16'h0007) | ||
+ | aout <= {3'b111, ain[7:0]}; | ||
+ | end | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### MControl.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module MControl( | ||
+ | input clk, | ||
+ | input reset, | ||
+ | input serialdata, | ||
+ | output nenable, | ||
+ | output reg sclk = 1'b1, | ||
+ | output reg [11:0]micdata = 12'h000 | ||
+ | ); | ||
+ | | ||
+ | parameter WAIT = 2'b00; | ||
+ | parameter GETDATA = 2'b01; | ||
+ | parameter PUTDATA = 2'b10; | ||
+ | parameter QUIET = 2'b11; | ||
+ | |||
+ | reg [1:0]clockdivider = 2'b00; | ||
+ | reg [1:0]state = WAIT; | ||
+ | reg [1:0]nextstate = WAIT; | ||
+ | reg [4:0]bitcounter = 5'h00; | ||
+ | reg [11:0]datahold = 12'h000; | ||
+ | |||
+ | nand nen(nenable, ~state[1], state[0]); | ||
+ | | ||
+ | always @(posedge clk) begin | ||
+ | if(!reset) | ||
+ | clockdivider <= clockdivider + 1'b1; | ||
+ | else begin | ||
+ | clockdivider <= 2'b00; | ||
+ | sclk <= 1'b0; | ||
+ | end | ||
+ | | ||
+ | if(clockdivider == 2'b01) | ||
+ | sclk <= 1'b1; | ||
+ | if(clockdivider == 2'b11) | ||
+ | sclk <= 1'b0; | ||
+ | end | ||
+ | | ||
+ | always @(posedge sclk) begin | ||
+ | if(reset) | ||
+ | state <= WAIT; | ||
+ | else | ||
+ | state <= nextstate; | ||
+ | | ||
+ | if(nextstate == GETDATA) begin | ||
+ | bitcounter <= bitcounter + 1'b1; | ||
+ | datahold <= {datahold[10:0], serialdata}; | ||
+ | end | ||
+ | if(nextstate == PUTDATA) begin | ||
+ | datahold <= {datahold[10:0], serialdata}; | ||
+ | bitcounter <= 5'h00; | ||
+ | end | ||
+ | if(nextstate == WAIT) | ||
+ | micdata <= datahold; | ||
+ | end | ||
+ | | ||
+ | always @(state, reset, bitcounter) begin | ||
+ | case(state) | ||
+ | WAIT : nextstate = (reset) ? WAIT : GETDATA; | ||
+ | GETDATA : nextstate = (bitcounter == 5'h10) ? PUTDATA : GETDATA; | ||
+ | PUTDATA : nextstate = WAIT; | ||
+ | QUIET : nextstate = WAIT; | ||
+ | endcase | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### ClockControl.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | //This module controls the timing of the clock and the time change | ||
+ | //functions. It takes the 50 MHz system clock in as an input and the | ||
+ | //1 KHz clock enable. It also takes the status of the buttons in so | ||
+ | //it can set the clock time. The current time of the clock in BCD is | ||
+ | //provided on the output. | ||
+ | |||
+ | module ClockControl( | ||
+ | input clock, | ||
+ | input ce_1KHz, | ||
+ | input [3:0]button, | ||
+ | output [7:0]hour, | ||
+ | output [7:0]min, | ||
+ | output [7:0]sec, | ||
+ | output blink | ||
+ | ); | ||
+ | | ||
+ | reg ce_1Hz = 1'b0; | ||
+ | reg [9:0]mscounter = 10'h000; | ||
+ | reg [3:0]seclo = 4'h0; | ||
+ | reg [3:0]sechi = 4'h0; | ||
+ | reg [3:0]minlo = 4'h0; | ||
+ | reg [3:0]minhi = 4'h0; | ||
+ | reg [3:0]hourlo = 4'h1; | ||
+ | reg [3:0]hourhi = 4'h0; | ||
+ | | ||
+ | assign hour = {hourhi, hourlo}; | ||
+ | assign min = {minhi, minlo}; | ||
+ | assign sec = {sechi, seclo}; | ||
+ | assign blink = mscounter[9]; | ||
+ | |||
+ | always @(posedge clock) begin | ||
+ | //Reset 1 second clock enable pulse every clock cycle. | ||
+ | ce_1Hz = 1'b0; | ||
+ | | ||
+ | if(ce_1KHz) | ||
+ | mscounter = mscounter + 1; | ||
+ | | ||
+ | if(mscounter == 1000) begin | ||
+ | mscounter = 0; | ||
+ | ce_1Hz = 1'b1; //1 second clock enable pulse. | ||
+ | seclo = seclo + 1; | ||
+ | end | ||
+ | | ||
+ | if(seclo == 10) begin | ||
+ | seclo = 0; | ||
+ | sechi = sechi + 1; | ||
+ | end | ||
+ | | ||
+ | if(sechi == 6) begin | ||
+ | sechi = 0; | ||
+ | minlo = minlo + 1; | ||
+ | end | ||
+ | | ||
+ | if(minlo == 10) begin | ||
+ | minlo = 0; | ||
+ | minhi = minhi + 1; | ||
+ | end | ||
+ | | ||
+ | if(minhi == 6) begin | ||
+ | minhi = 0; | ||
+ | hourlo = hourlo + 1; | ||
+ | end | ||
+ | | ||
+ | if(hourlo == 10) begin | ||
+ | hourlo = 0; | ||
+ | hourhi = hourhi + 1; | ||
+ | end | ||
+ | | ||
+ | if(hourhi == 1 && hourlo == 3) begin | ||
+ | hourlo = 4'b0001; | ||
+ | hourhi = 0; | ||
+ | end | ||
+ | | ||
+ | //Button inputs used to set the clock time. | ||
+ | //Increment the lower minute digit. | ||
+ | if(button == 4'b0001 && ce_1Hz) | ||
+ | minlo = minlo + 1; | ||
+ | | ||
+ | //Increment the upper minute digit. | ||
+ | if(button == 4'b0010 && ce_1Hz) | ||
+ | minhi = minhi + 1; | ||
+ | | ||
+ | //Increment the lower hour digit. | ||
+ | if(button == 4'b0100 && ce_1Hz) | ||
+ | hourlo = hourlo + 1; | ||
+ | end | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### dataMUX.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module dataMUX( | ||
+ | input [15:0]xpos, | ||
+ | input [15:0]ypos, | ||
+ | input [15:0]i2cdata, | ||
+ | input [15:0]i2cstatus, | ||
+ | input read, | ||
+ | input blink, | ||
+ | input [15:0]id, | ||
+ | input [15:0]uartdata, | ||
+ | input [11:0]txcount, | ||
+ | input [11:0]rxcount, | ||
+ | input [7:0]romdata, | ||
+ | input [15:0]switches, | ||
+ | input [7:0]sec, | ||
+ | input [7:0]min, | ||
+ | input [7:0]hour, | ||
+ | input [15:0]micdata, | ||
+ | output [15:0]dout | ||
+ | ); | ||
+ | |||
+ | assign dout = (id == 16'h0001 && read) ? i2cdata : | ||
+ | (id == 16'h0002 && read) ? i2cstatus : | ||
+ | (id == 16'h0003 && read) ? uartdata : | ||
+ | (id == 16'h0004 && read) ? {4'h0, txcount} : | ||
+ | (id == 16'h0005 && read) ? {4'h0, rxcount} : | ||
+ | (id == 16'h0006 && read) ? xpos : | ||
+ | (id == 16'h0007 && read) ? ypos : | ||
+ | (id == 16'h0012 && read) ? {8'h00, romdata} : | ||
+ | (id == 16'h0013 && read) ? switches : | ||
+ | (id == 16'h0030 && read) ? {8'h00, sec} : | ||
+ | (id == 16'h0031 && read) ? {8'h00, min} : | ||
+ | (id == 16'h0032 && read) ? {8'h00, hour} : | ||
+ | (id == 16'h0033 && read) ? {15'h0000, blink} : | ||
+ | (id == 16'h0034 && read) ? micdata : | ||
+ | 16'h0000; | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### div100k.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module div100k( | ||
+ | input clock, | ||
+ | output reg ce1k = 1'b0 | ||
+ | ); | ||
+ | |||
+ | reg [17:0]counter = 18'h00000; | ||
+ | | ||
+ | always @(posedge clock) begin | ||
+ | counter <= counter + 1; | ||
+ | ce1k <= 0; | ||
+ | if(counter == 18'd100681) begin | ||
+ | counter <= 18'd0; | ||
+ | ce1k <= 1; | ||
+ | end | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### FF.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | //IRQ flipflop | ||
+ | module FF(input set, input reset, output reg sigout = 1'b0); | ||
+ | | ||
+ | always @(posedge set, posedge reset) begin | ||
+ | if(reset) | ||
+ | sigout <= 1'b0; | ||
+ | else | ||
+ | sigout <= 1'b1; | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### ledio.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module ledio( | ||
+ | input clk, | ||
+ | input reset, | ||
+ | input write, | ||
+ | input [15:0]id, | ||
+ | input [15:0]din, | ||
+ | output reg [7:0]ledsout = 8'h00 | ||
+ | ); | ||
+ | |||
+ | always @(posedge clk) | ||
+ | begin | ||
+ | if(id == 16'h0020 && write) | ||
+ | ledsout <= din[7:0]; | ||
+ | if(reset) | ||
+ | ledsout <= 8'h00; | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### LEDIO2.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module LEDIO2( | ||
+ | input clk, | ||
+ | input reset, | ||
+ | input write, | ||
+ | input [15:0]id, | ||
+ | input [15:0]din, | ||
+ | output reg [7:0]ledsout = 8'h00 | ||
+ | ); | ||
+ | |||
+ | always @(posedge clk) begin | ||
+ | if(id == 16'h0021 && write) ledsout <= din[7:0]; | ||
+ | if(reset) ledsout <= 8'h00; | ||
+ | end | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### seg7io.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module seg7io( | ||
+ | input clk, | ||
+ | input ce1k, | ||
+ | input write, | ||
+ | input reset, | ||
+ | input [15:0]id, | ||
+ | input [15:0]din, | ||
+ | output reg [3:0]segselect = 4'h0, | ||
+ | output reg [7:0]segs = 8'h00 | ||
+ | ); | ||
+ | |||
+ | reg [7:0]seg0 = 8'h00; | ||
+ | reg [7:0]seg1 = 8'h00; | ||
+ | reg [7:0]seg2 = 8'h00; | ||
+ | reg [7:0]seg3 = 8'h00; | ||
+ | |||
+ | always @(posedge ce1k) | ||
+ | begin | ||
+ | //Constantly cycle through the enable pins. | ||
+ | if(segselect == 4'b1110) begin | ||
+ | segselect <= 4'b0111; | ||
+ | segs <= ~seg0; | ||
+ | end | ||
+ | else if(segselect == 4'b0111) begin | ||
+ | segselect <= 4'b1011; | ||
+ | segs <= ~seg1; | ||
+ | end | ||
+ | else if(segselect == 4'b1011) begin | ||
+ | segselect <= 4'b1101; | ||
+ | segs <= ~seg2; | ||
+ | end | ||
+ | else begin | ||
+ | segselect <= 4'b1110; | ||
+ | segs <= ~seg3; | ||
+ | end | ||
+ | end | ||
+ | | ||
+ | always @(posedge clk) | ||
+ | begin | ||
+ | if(id == 16'h0024 && write) | ||
+ | seg0 <= din[7:0]; | ||
+ | if(id == 16'h0025 && write) | ||
+ | seg1 <= din[7:0]; | ||
+ | if(id == 16'h0026 && write) | ||
+ | seg2 <= din[7:0]; | ||
+ | if(id == 16'h0027 && write) | ||
+ | seg3 <= din[7:0]; | ||
+ | | ||
+ | if(reset) | ||
+ | begin | ||
+ | seg0 <= 8'h00; | ||
+ | seg1 <= 8'h00; | ||
+ | seg2 <= 8'h00; | ||
+ | seg3 <= 8'h00; | ||
+ | end | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### timer.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module timer0( | ||
+ | input clk, | ||
+ | input cein, | ||
+ | input write, | ||
+ | input [15:0] id, | ||
+ | input [15:0] din, | ||
+ | input reset, | ||
+ | output reg dout = 1'b0 | ||
+ | ); | ||
+ | |||
+ | reg [15:0] timerreg = 16'h0000; | ||
+ | |||
+ | always @(posedge clk) begin | ||
+ | dout <= 1'b0; | ||
+ | //Load timer bits. | ||
+ | if(id == 16'h0010 && write) | ||
+ | timerreg <= din; | ||
+ | //Decrement timer if not 0. | ||
+ | if(cein && timerreg > 1'b1) | ||
+ | timerreg <= timerreg - 1'b1; | ||
+ | //One timer is about to expire, send output strobe. | ||
+ | if(cein && timerreg == 1'b1) begin | ||
+ | timerreg <= timerreg - 1'b1; | ||
+ | dout <= 1'b1; | ||
+ | end | ||
+ | //Synchronous reset. | ||
+ | if(reset) | ||
+ | timerreg <= 16'h0000; | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### timer1.v | ||
+ | <code verilog> | ||
+ | |||
+ | `timescale 1ns / 1ps | ||
+ | |||
+ | module timer1( | ||
+ | input clk, | ||
+ | input cein, | ||
+ | input write, | ||
+ | input [15:0] id, | ||
+ | input [15:0] din, | ||
+ | input reset, | ||
+ | output reg dout = 1'b0 | ||
+ | ); | ||
+ | |||
+ | reg [15:0] timerreg = 16'h0000; | ||
+ | |||
+ | always @(posedge clk) begin | ||
+ | dout <= 1'b0; | ||
+ | //Load timer bits. | ||
+ | if(id == 16'h0011 && write) | ||
+ | timerreg <= din; | ||
+ | //Decrement timer if not 0. | ||
+ | if(cein && timerreg > 1'b1) | ||
+ | timerreg <= timerreg - 1'b1; | ||
+ | //One timer is about to expire, send output strobe. | ||
+ | if(cein && timerreg == 1'b1) begin | ||
+ | timerreg <= timerreg - 1'b1; | ||
+ | dout <= 1'b1; | ||
+ | end | ||
+ | //Synchronous reset. | ||
+ | if(reset) | ||
+ | timerreg <= 16'h0000; | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### lookupROM.coe | ||
+ | <code verilog> | ||
+ | |||
+ | memory_initialization_radix = 16; | ||
+ | memory_initialization_vector = | ||
+ | |||
+ | ; LEDTbl($ 000) | ||
+ | 01,02,04,08,10,20,40,80,40,20,10,08,04,02,01,02, | ||
+ | 04,08,10,20,40,80,40 , | ||
+ | 20,10,08,04,02,01,02,04,08,10,20,40,80,40,20,10,08,04,02,01,02,04,08,10,20 , | ||
+ | 40、80、40、20、10、08、04、02、01,FF,00,FF,00,FF,00,FF, | ||
+ | 00,AA,55,AA,55,AA,55,AA,55 ,AA,55,AA,55,AA, | ||
+ | 55、00、18、3C,7E,FF,00、18、3C,7E,FF,00、18、3C,7E,FF, | ||
+ | 00、18、3C,7E ,FF,00、18、3C,7E,FF,00、18、3C,7E,FF | ||
+ | ,00、00、00、00、00、00、00、00、00、00、00、00、00、00 ,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00 ,00、00、00、00、00、00、00、00、00、00、00、00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00, 00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00, 00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00, 00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | |||
+ | ; TimeLoTbl($ 100) | ||
+ | 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, | ||
+ | 50,50,50,50,50,50,50 ,50,50,50,50,50,50,50,50,50, | ||
+ | 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50 , | ||
+ | 50、50、50、50、50、50、50、50、50,FF,FF,FF,FF,FF,FF, | ||
+ | FF,FF,FF,A0,A0,A0,A0,A0,A0,A0,A0 ,A0,A0,A0,A0,A0,A0,A0, | ||
+ | A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0, | ||
+ | A0,A0 ,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,A0,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00 ,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00 ,00、00、00、00、00、00、00、00、00、00、00、00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00, 00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00, 00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00, 00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | |||
+ | ; Seg7IndexTbl($ 200) | ||
+ | 1C,1E,1B,0E,10,05,05,1B,1E,22,1B,1A,18,16,如图1A所示,10, | ||
+ | 23,23,23,00,01,02,03 , | ||
+ | 04,05,06,07,08,09,23,23,23,1C,1E,1B,00,00,00,00,00,00,00,00,00,00,00,00,00 , | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00 ,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00 ,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00 ,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00 ,00、00、00、00、00、00、00、00、00、00、00、00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00, 00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00, 00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00, 00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | |||
+ | ; Seg7Tbl($ 300) | ||
+ | 3F,06,5B,4F,66,6D,7D,07,7F,67,77,5F,图7C,39,58,如图5E所示, | ||
+ | 79,7B,71,6F,76,74,04 ,1E,38、37、54、5C,73、31、50、3E, | ||
+ | 1C,6E,00、80、00、00、00、00、00、00、00、00、00、00、00、00 , | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00 ,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00 ,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00 ,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00 ,00、00、00、00、00、00、00、00、00、00、00、00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00, 00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00, 00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00, 00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | |||
+ | ; ClockTbl($ 400) | ||
+ | ; 0 | ||
+ | 4C,46,46,4D,56,51,50,47,56,41,40,47,5C,57,57,5D,; | ||
+ | 1 | ||
+ | FF,44,4D,FF,FF ,50,47,FF,FF,FF,47,FF,FF,FF,55,FF,; | ||
+ | 2 | ||
+ | 44,46,46,4D,4E,61,4A,59,48,5B,60,5F,5C ,57,57,72,; | ||
+ | 3 | ||
+ | 44,46,46,4D,62,61,4A,59,63,60,5A,49,54,57,57,5D,; | ||
+ | 4 | ||
+ | 70,64,65,66 ,67,68,69,6A,6B,60,6C,6D,FF,FF,71,6E,; | ||
+ | 5 | ||
+ | 73,46,46,45,74,61,61,4F,63,60,5A,49 ,54、57、57、5D,; | ||
+ | 6 | ||
+ | 4C,46、46、45、56、42、61、4F,56、52、5A,49、5C,57、57、5D,; | ||
+ | 7 | ||
+ | 44,46、46 ,4D,FF,FF,50、47,FF,FF,FF,47,FF,FF,FF,55,; | ||
+ | 8 | ||
+ | 4C,46、46、4D,58、4B,4A,59、48、5B,5A ,49、5C,57、57、5D, | ||
+ | ; 9 | ||
+ | 4C,46、46、4D,58、4B,43、47、5E,60、53、47、54、57、57、5D 、 | ||
+ | ;空白 | ||
+ | FF,FF,FF,FF,FF,FF,FF, FF,FF,FF,FF,FF,FF,FF,FF,FF, | ||
+ | |||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00, 00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00, 00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00, 00,00,00,00,00, | ||
+ | |||
+ | ; MessageTbl($ 500) | ||
+ | ;活动演示 | ||
+ | -0A,0C,1D,12、1F,0E,FF,0D,0E,16、18、17、1C,1D,1B,0A, | ||
+ | 1D,12、18、17C ,3F, | ||
+ | ;($ 516) | ||
+ | ;平时时钟 | ||
+ | 1D,12,15,0E ,0D,FF,0C,15,18,0C ,14, | ||
+ | ;($ 521) | ||
+ | ; SPRITE AUDIO | ||
+ | 1C,19,1B ,12,1 ,D ,0E ,FF,0A,1E,0D, | ||
+ | 12,18 ,;($ 52D) | ||
+ | ;基色 | ||
+ | 0B,0A,1C,0E,FF,0C,18,15,18,1B , | ||
+ | ;($ 537) | ||
+ | ;弹跳 | ||
+ | 0B, 18,1E,17,0C,12,17,10,FF,1C,19,1B,12,1D,0E,1C, | ||
+ | ;($ 547) | ||
+ | ;属性表 | ||
+ | 0A,1D,1D,1B,12,0B,1E ,1D,0E,FF,1D,0A,0B,15,0E, | ||
+ | ;($ 556) | ||
+ | ; SPRITE PRIORITY | ||
+ | 1C,19,1B ,12,1D,0E,FF,19,1B,12,18,1B,12, 1D,22, | ||
+ | ;($ 565) | ||
+ | ;调色板更改19,0A ,15,0E | ||
+ | ,1D,1D,0E,FF,0C,11,0A ,17,10,0E , | ||
+ | ;($ 573) | ||
+ | ; SPRITE MIRRORING | ||
+ | 1C,19,1B ,12, 1D,0E,FF,16,12,1B,1B,18,1B,12,17,10 | ||
+ | ;($ 583) | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00 ,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00 ,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00 ,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00 ,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00 ,00、00、00、00、00、00、00、00、00、00、00、00、00, | ||
+ | |||
+ | ; PaletteTbl($ 600)00、38、20、18、00、3F,24、1B,00、52 | ||
+ | ,A4,FF,00、07、04、03、00、26、3F,02、00 | ||
+ | ,C4,C2 ,82、00、60,A0、20、00、0B,19、5D | ||
+ | ,00、00、00、00、00、00、00、00、00、00、00、00、00、00、00、00 , | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | |||
+ | ; SamusTbl($ 640)D0,00,D0,01,D8,10,D8,11,E0,20,E0,21 | ||
+ | ,E0,FF,E8,FF, | ||
+ | E8,31,E8,FF,FF,FF,FF ,FF,D0、02,D0、03,D8、12,D8、13,E0、22,E0、23, | ||
+ | E0,FF,E8、32,E8、33,E8、34,FF,FF,FF,FF , | ||
+ | D0、00,D0、01,D8、10,D8、11,E0、20, | ||
+ | E0、21,E0,FF,E8,FF,E8、31,E8,FF,FF,FF,FF,FF,D0 ,05,D0、06,D8、15,D8、16,E0、25, | ||
+ | E0、26,E0、27,E8、35,E8、36,E8,FF,FF,FF,FF,FF, | ||
+ | |||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00, 00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00, 00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00, 00,00,00,00,00, | ||
+ | 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, | ||
+ | |||
+ | ; SpriteTbl($ 700) | ||
+ | C0,9C,01,28,C0,9D,01,30,C8,9E,01,28,C8,9F,01,30, | ||
+ | C0,9F,C1,78,C0,9E,C1 ,80,C8、9D,C1、78,C8、9C, | ||
+ | C1、80,C0、9C,01,C8,C0、9D,01,D0,C8、9E,01,C8,C8、9F,01,D0 , | ||
+ | FF,9F,C1,C8,FF,9E,C1,D0,FF,9D,C1,C8,FF,9C,C1,D0, | ||
+ | C0、9E,81、28,C0、9F,81、30,C8 ,9C,81、28,C8、9D, | ||
+ | 81、30,C0、9D,41、78,C0、9C,41、80,C8、9F,41、78,C8、9E, | ||
+ | 41、80,C0、9E ,81,C8,C0、9F,81,D0,C8、9C,81,C8,C8、9D,81,D0, | ||
+ | FF,9D,41,C8,FF,9C,41,D0,FF,9F,41 ,C8,FF,9E,41,D0, | ||
+ | C0、9F,C1、28,C0、9E,C1、30,C8、9D,C1、28, | ||
+ | C8、9C,C1、30,C0、9C,01、78 ,C0、9D,01、80,C8、9E,01、78,C8、9F,01、80, | ||
+ | C0、9F,C1,C8,C0、9E,C1,D0,C8、9D,C1,C8,C8、9C,C1,D0, | ||
+ | FF,9C,01,C8,FF,9D,01,D0,FF, 9E,01,C8,FF,9F,01,D0, | ||
+ | C0、9D,41、28,C0、9C,41、30,C8、9F,41、28,C8、9E, | ||
+ | 41、30,C0、9E, 81、78,C0、9F,81、80,C8、9C,81、78,C8、9D, | ||
+ | 81、80,C0、9D,41,C8,C0、9C,41,D0,C8、9F,41, C8,C8、9E,41,D0, | ||
+ | FF,9E,81,C8,FF,9F,81,D0,FF,9C,81,C8,FF,9D,81,D0; | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | #### NMPSM3汇编程序 | ||
+ | 还为NMPSM3编写了汇编程序。它是一个基本的汇编器,但运行良好,已被用于在多个FPGA项目上为NMPSM3编写代码。\\ | ||
+ | |||
+ | ##### NMPSM3.java | ||
+ | <code verilog> | ||
+ | |||
+ | package nmpsm3; | ||
+ | |||
+ | import java.io.RandomAccessFile; | ||
+ | import java.io.IOException; | ||
+ | import java.util.Vector; | ||
+ | |||
+ | //A simple class to store alias associations. | ||
+ | class AliasSet { | ||
+ | AliasSet(String as, String rs) { | ||
+ | aliasString = as; | ||
+ | replacementString = rs; | ||
+ | } | ||
+ | public String aliasString; | ||
+ | public String replacementString; | ||
+ | } | ||
+ | |||
+ | //A simple class to store address labels. | ||
+ | class Labels { | ||
+ | Labels(String ln, int la, int lin) { | ||
+ | labelName = ln; | ||
+ | labelAddress = la; | ||
+ | lineNumber = lin; | ||
+ | } | ||
+ | public String labelName; | ||
+ | public int labelAddress; | ||
+ | public int lineNumber; | ||
+ | } | ||
+ | |||
+ | //A simple class to store error events. | ||
+ | class Error{ | ||
+ | Error(String es, int el) { | ||
+ | errorString = es; | ||
+ | errorLine = el; | ||
+ | } | ||
+ | public String errorString; | ||
+ | public int errorLine; | ||
+ | } | ||
+ | |||
+ | public class NMPSM3 { | ||
+ | |||
+ | //Line number where error occurs. | ||
+ | private int errorLine = 0; | ||
+ | //Current address. | ||
+ | private int currentAddress = 0; | ||
+ | //Program size limit. Min. = 1, max = 65536, default = 512. | ||
+ | private int sizeLimit = 512; | ||
+ | //Input file. | ||
+ | private RandomAccessFile read; | ||
+ | //Output file. | ||
+ | private RandomAccessFile write; | ||
+ | //Output array. Size calculated later. | ||
+ | private String[] output; | ||
+ | //Input vector. | ||
+ | private Vector<String> input = new Vector<String>(); | ||
+ | //Vector of aliases. | ||
+ | private Vector<AliasSet> aliases = new Vector<AliasSet>(); | ||
+ | //Vector of addresses corresponding to each program line. | ||
+ | private Vector<Integer> addresses = new Vector<Integer>(); | ||
+ | //Vector of labels. | ||
+ | private Vector<Labels> labels = new Vector<Labels>(); | ||
+ | //Vector of error messages. | ||
+ | private Vector<Error> error = new Vector<Error>(); | ||
+ | //Reserved words not to be used in labels. | ||
+ | private String[] reserved = {"load", "stor", "jump", "jpnz", "jpz" , "jpnc", | ||
+ | "jpc" , "call", "clnz", "clz" , "clnc", "clc" , | ||
+ | "ret" , "rtnz", "rtz" , "rtnc", "rtc" , "rtie", | ||
+ | "rtid", "in" , "out" , "and" , "or" , "xor" , | ||
+ | "add" , "addc", "sub" , "subc", "test", "comp", | ||
+ | "asl" , "rol" , "lsr" , "ror" , "setc", "clrc", | ||
+ | "ein0", "ein1", "ein2", "ein3", "din0", "din1", | ||
+ | "din2", "din3", "push", "pop"}; | ||
+ | //Invalid label characters. | ||
+ | private String[] invalidChars = {"!" , "@" , "#" , "$" , "%" , "^" , "&" , | ||
+ | "*" , "(" , ")" , "+" , "=" , "`" , "~" , | ||
+ | "\\", "|" , "]" , "[" , "{" , "}" , ";" , | ||
+ | ":" , "\"", "\'", "-" , "<" , "," , ">" , | ||
+ | "." , "/" , "?"}; | ||
+ | //Arrays containing the different types of instructions. | ||
+ | private String[] inst1 = {"ret" , "rtnz", "rtz" , "rtnc", "rtc" , "rtie", | ||
+ | "rtid", "setc", "clrc", "ein0", "ein1", "ein2", | ||
+ | "ein3", "din0", "din1", "din2", "din3"}; | ||
+ | private String[] inst2 = {"jump", "jpnz", "jpz" , "jpnc", "jpc" , "call", | ||
+ | "clnz", "clz" , "clnc", "clc" , "asl" , "rol" , | ||
+ | "lsr" , "ror" , "push", "pop"}; | ||
+ | private String[] inst3 = {"load", "stor", "in" , "out" , "and" , "or" , | ||
+ | "xor" , "add" , "addc", "sub" , "subc", "test", | ||
+ | "comp"}; | ||
+ | //Invalid instructions | ||
+ | private String[] invalidInst = {"stork", "jumpk", "jpnzk", "jpnzi", | ||
+ | "jpzk" , "jpzi" , "jpnck", "jpnci", | ||
+ | "jpck" , "jpci" , "callk", "clnzk", | ||
+ | "clnzi", "clzk" , "clzi" , "clnck", | ||
+ | "clnci", "clck" , "clci" , "ini" , | ||
+ | "outi" , "andi" , "ori" , "xori" , | ||
+ | "addi" , "addci", "subi" , "subci", | ||
+ | "testi", "compi", "aslk" , "asli" , | ||
+ | "rolk" , "roli" , "lsrk" , "lsri" , | ||
+ | "rork" , "rori" , "pushk", "pushi", | ||
+ | "popk" , "popi"}; | ||
+ | //Array of complete commands | ||
+ | private String[] completeInst = {"loadk", "load" , "loadi", "stor" , | ||
+ | "stori", "jump" , "jumpi", "jpnz" , | ||
+ | "jpz" , "jpnc" , "jpc" , "call" , | ||
+ | "calli", "clnz" , "clz" , "clnc" , | ||
+ | "clc" , "ret" , "rtnz" , "rtz" , | ||
+ | "rtnc" , "rtc" , "rtie" , "rtid" , | ||
+ | "ink" , "in" , "outk" , "out" , | ||
+ | "andk" , "and" , "ork" , "or" , | ||
+ | "xork" , "xor" , "addk" , "add" , | ||
+ | "addck", "addc" , "subk" , "sub" , | ||
+ | "subck", "subc" , "testk", "test" , | ||
+ | "compk", "comp" , "asl" , "rol" , | ||
+ | "lsr" , "ror" , "setc" , "clrc" , | ||
+ | "ein0" , "ein1" , "ein2" , "ein3" , | ||
+ | "din0" , "din1" , "din2" , "din3" , | ||
+ | "push" , "pop"}; | ||
+ | //Opcodes for the above instructions. | ||
+ | private String[] opcodes = {"01", "04", "07", "0A", "0D", "10", "13", "16", | ||
+ | "19", "1C", "20", "23", "26", "29", "2C", "30", | ||
+ | "33", "36", "39", "3C", "40", "43", "46", "49", | ||
+ | "4C", "50", "53", "56", "59", "5C", "60", "63", | ||
+ | "66", "69", "6C", "70", "73", "76", "79", "7C", | ||
+ | "80", "83", "86", "89", "8C", "90", "93", "96", | ||
+ | "99", "9C", "A0", "A3", "A6", "A9", "AC", "B0", | ||
+ | "B3", "B6", "B9", "BC", "C0", "C6"}; | ||
+ | |||
+ | NMPSM3(String[] arguments) { | ||
+ | |||
+ | //Check for proper number of arguments. | ||
+ | if (arguments.length < 1 || arguments.length > 2) { | ||
+ | System.out.println("\nThe proper usage of the assembler is as follows:\n" + | ||
+ | "\njava -jar NMPSM3.jar [input.file] {[output.file]}\n\n" + | ||
+ | "A minimum of one argument is required which is the input assembly file.\n" + | ||
+ | "The output file name is optional. If an output file name is not\n" + | ||
+ | "specified, the input file name with a .coe extension is created."); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | |||
+ | try { | ||
+ | //Open input assembly file to read from. | ||
+ | read = new RandomAccessFile(arguments[0], "r"); | ||
+ | } | ||
+ | catch (IOException ioException) { | ||
+ | System.err.println("Error opening file: " + ioException); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | |||
+ | try { | ||
+ | //Fill input vector. | ||
+ | while (read.getFilePointer() != read.length()) { | ||
+ | input.add(read.readLine()); | ||
+ | } | ||
+ | } | ||
+ | catch (IOException ioException) { | ||
+ | System.err.println("Error reading file: " + ioException); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | |||
+ | ////////////////////////Start processing input vector/////////////////////////// | ||
+ | //Remove all comments from input vector. | ||
+ | CommentRemover(); | ||
+ | |||
+ | //Remove all blank lines from input vector. | ||
+ | BlankLineRemover(); | ||
+ | |||
+ | //Replace all commas with spaces. | ||
+ | CommaRemover(); | ||
+ | |||
+ | //Remove consecutive blank spaces from input vector. | ||
+ | SpaceRemover(); | ||
+ | |||
+ | //Create alias vector. | ||
+ | AliasVector(); | ||
+ | |||
+ | //Replace aliases in input vector. | ||
+ | ReplaceAliases(); | ||
+ | |||
+ | //Set program size limit. | ||
+ | ProgramSizer(); | ||
+ | |||
+ | //Fill address vector. | ||
+ | FillAddressVector(); | ||
+ | | ||
+ | //Verify the labels are properly formed and fill the label vector. | ||
+ | LabelChecker(); | ||
+ | |||
+ | //Process the instructions. | ||
+ | ProcessCode(); | ||
+ | |||
+ | //Fill output vector. | ||
+ | FillOutput(); | ||
+ | |||
+ | //Print errors. | ||
+ | PrintErrors(); | ||
+ | | ||
+ | //Check vector. | ||
+ | //VectorPrint(); | ||
+ | //Check addresses. | ||
+ | //AddressPrint(); | ||
+ | |||
+ | /////////////////////////End processing input vector//////////////////////////// | ||
+ | try { | ||
+ | //Open output .coe file to write to. | ||
+ | if(arguments.length == 2) | ||
+ | write = new RandomAccessFile(arguments[1], "rw"); | ||
+ | else | ||
+ | write = new RandomAccessFile(arguments[0].substring(0, arguments[0].indexOf('.')) + ".coe", "rw"); | ||
+ | } | ||
+ | catch (IOException ioException) { | ||
+ | System.err.println("Error opening file: " + ioException); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | |||
+ | //Write to output file. | ||
+ | WriteOutput(); | ||
+ | |||
+ | try { | ||
+ | //Close read file | ||
+ | if (read != null) { | ||
+ | read.close(); | ||
+ | } | ||
+ | //Close write file | ||
+ | if (write != null) { | ||
+ | write.close(); | ||
+ | } | ||
+ | } | ||
+ | catch (IOException ioException) { | ||
+ | System.err.println("Error closing file: " + ioException); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | System.out.println("\nNMPSM3 .coe file created successfully.\n"); | ||
+ | } | ||
+ | |||
+ | ///////////////////////////////Utility methods////////////////////////////////// | ||
+ | void VectorPrint() { | ||
+ | //Print input vector. Used during development. | ||
+ | System.out.println("\nInput Vector:"); | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | System.out.println(input.elementAt(i)); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void AddressPrint() { | ||
+ | //Print addresses vector. Used during development. | ||
+ | System.out.println("\nAddress Vector:"); | ||
+ | for(int i = 0; i < addresses.size(); i++) { | ||
+ | System.out.println(addresses.elementAt(i)); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void CommentRemover() { | ||
+ | //Trim all comments from input vector. | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | String s = input.elementAt(i); | ||
+ | String[] tokenizedString = s.split(";"); | ||
+ | input.setElementAt(tokenizedString[0], i); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void BlankLineRemover() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | String s = input.elementAt(i); | ||
+ | s = s.replaceAll("\t", " "); | ||
+ | s = s.replaceAll("\n", ""); | ||
+ | s = s.trim(); | ||
+ | input.setElementAt(s, i); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void CommaRemover() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | String s = input.elementAt(i); | ||
+ | s = s.replaceAll(",", " "); | ||
+ | input.setElementAt(s, i); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void SpaceRemover() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | String s = input.elementAt(i); | ||
+ | String newString = ""; | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | for(int j = 0; j < tokenizedString.length; j++) { | ||
+ | if(tokenizedString[j].length() != 0) | ||
+ | newString = newString + tokenizedString[j] + " "; | ||
+ | } | ||
+ | newString = newString.trim(); | ||
+ | input.setElementAt(newString, i); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void AliasVector() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | try { | ||
+ | errorLine = i + 1; | ||
+ | String s = input.elementAt(i); | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | if(tokenizedString[0].toLowerCase().equals(".alias")) { | ||
+ | if(tokenizedString.length != 3) | ||
+ | throw new Exception(); | ||
+ | //Add alias to vector. | ||
+ | aliases.addElement(new AliasSet(tokenizedString[1], tokenizedString[2])); | ||
+ | //erase alias from input vector. | ||
+ | input.setElementAt("", i); | ||
+ | } | ||
+ | } | ||
+ | catch (Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid .ALIAS", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void ReplaceAliases() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | String newString = ""; | ||
+ | String temp; | ||
+ | String s = input.elementAt(i); | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | for(int j = 0; j < tokenizedString.length; j++) { | ||
+ | for(int k = 0; k < aliases.size(); k++) { | ||
+ | //Check for alias inside parenthesis. | ||
+ | if(tokenizedString[j].startsWith("(") && tokenizedString[j].endsWith(")")) { | ||
+ | temp = tokenizedString[j].substring(1, tokenizedString[j].length() - 1); | ||
+ | if(aliases.elementAt(k).aliasString.equals(temp)) | ||
+ | tokenizedString[j] = "(" + aliases.elementAt(k).replacementString + ")"; | ||
+ | } | ||
+ | if(aliases.elementAt(k).aliasString.equals(tokenizedString[j])) | ||
+ | tokenizedString[j] = aliases.elementAt(k).replacementString; | ||
+ | } | ||
+ | } | ||
+ | for(int j = 0; j < tokenizedString.length; j++) { | ||
+ | newString = newString + tokenizedString[j] + " "; | ||
+ | } | ||
+ | newString = newString.trim(); | ||
+ | input.setElementAt(newString, i); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void ProgramSizer() { | ||
+ | boolean sizeFound = false; | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | errorLine = i + 1; | ||
+ | String s = input.elementAt(i); | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | try { | ||
+ | //Size directive already found. Throw exception. | ||
+ | if(tokenizedString[0].toLowerCase().equals(".size") && sizeFound == true) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Multiple .SIZE directives", errorLine)); | ||
+ | } | ||
+ | try { | ||
+ | //Check if only one size argument. | ||
+ | if(tokenizedString[0].toLowerCase().equals(".size") && tokenizedString.length != 2) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Incorrect number of .SIZE arguments", errorLine)); | ||
+ | } | ||
+ | try { | ||
+ | //Attempt to convert size argument to an integer. | ||
+ | if(tokenizedString[0].toLowerCase().equals(".size")) { | ||
+ | sizeLimit = NumberConverter(tokenizedString[1]); | ||
+ | sizeFound = true; | ||
+ | //Remove .size directive | ||
+ | input.setElementAt("", i); | ||
+ | } | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid .SIZE argument", errorLine)); | ||
+ | } | ||
+ | try { | ||
+ | //Check if size argument is within the proper range of 1 to 65536. | ||
+ | if(sizeLimit < 1 || sizeLimit > 65536) { | ||
+ | sizeLimit = 65536; | ||
+ | input.setElementAt("", i); | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error(".SIZE argument out of range", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | //Instantiate and size output array. | ||
+ | output = new String[sizeLimit]; | ||
+ | //Initialize array values to $000000000. | ||
+ | for(int i = 0; i < output.length; i++) { | ||
+ | output[i] = "000000000"; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int NumberConverter(String s) { | ||
+ | int number = 0; | ||
+ | //Radix of number | ||
+ | int numberType = 0; | ||
+ | //Check if hex number. | ||
+ | if(s.charAt(0) == '$') { | ||
+ | numberType = 16; | ||
+ | s = s.substring(1); | ||
+ | } | ||
+ | //Check if binary number. | ||
+ | else if(s.charAt(0) == '%') { | ||
+ | numberType = 2; | ||
+ | s = s.substring(1); | ||
+ | } | ||
+ | else | ||
+ | numberType = 10; | ||
+ | //Attempt to parse. Exception will be caught by calling method. | ||
+ | number = Integer.parseInt(s, numberType); | ||
+ | return number; | ||
+ | } | ||
+ | |||
+ | void FillAddressVector() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | errorLine = i + 1; | ||
+ | String s = input.elementAt(i); | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | //Empty element. | ||
+ | if(s.length() == 0) { | ||
+ | addresses.addElement(currentAddress); | ||
+ | } | ||
+ | //Check to see if valid .ORG directive is present. | ||
+ | else if(tokenizedString[0].toLowerCase().equals(".org")) { | ||
+ | try { | ||
+ | if(tokenizedString.length != 2) | ||
+ | throw new Exception(); | ||
+ | currentAddress = NumberConverter(tokenizedString[1]); | ||
+ | addresses.addElement(currentAddress); | ||
+ | //Erase .ORG directive | ||
+ | input.setElementAt("", i); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Incorrect number of .ORG arguments", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | //Check to see if label is present. | ||
+ | else if(tokenizedString[0].contains(":")) { | ||
+ | //Throw exception if more than 1 colon | ||
+ | try { | ||
+ | int charCounter = 0; | ||
+ | for(int j = 0; j < s.length(); j++) | ||
+ | if(s.charAt(j) == ':') | ||
+ | charCounter++; | ||
+ | if(charCounter > 1){ | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Multiple labels", errorLine)); | ||
+ | } | ||
+ | //Check if label only line. | ||
+ | if(tokenizedString.length == 1 && tokenizedString[0].charAt(tokenizedString[0].length() - 1) == ':') | ||
+ | addresses.addElement(currentAddress); | ||
+ | //Else must be a label plus an instruction. | ||
+ | else { | ||
+ | //Add space between label and instruction. | ||
+ | String[] labelTokenizer = s.split(":"); | ||
+ | labelTokenizer[0] = labelTokenizer[0].trim(); | ||
+ | labelTokenizer[1] = labelTokenizer[1].trim(); | ||
+ | input.setElementAt(labelTokenizer[0] + ": " + labelTokenizer[1], i); | ||
+ | addresses.addElement(currentAddress); | ||
+ | currentAddress++; | ||
+ | } | ||
+ | } | ||
+ | //Only possibility left is an instruction only. | ||
+ | else { | ||
+ | addresses.addElement(currentAddress); | ||
+ | currentAddress++; | ||
+ | } | ||
+ | //Throw exception if spaces in label. | ||
+ | try { | ||
+ | for(int k = 1; k < tokenizedString.length; k++) | ||
+ | if(tokenizedString[k].contains(":")) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid label", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void LabelChecker() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | errorLine = i + 1; | ||
+ | String newString = ""; | ||
+ | String s = input.elementAt(i); | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | //Fill labels vector. | ||
+ | if(tokenizedString[0].length() > 0 && tokenizedString[0].charAt(tokenizedString[0].length() - 1) == ':') { | ||
+ | labels.addElement(new Labels(tokenizedString[0], addresses.elementAt(i), errorLine)); | ||
+ | //Remove label from input vector. | ||
+ | if(tokenizedString.length > 1) { | ||
+ | for(int j = 1; j < tokenizedString.length; j++) | ||
+ | newString = newString + tokenizedString[j] + " "; | ||
+ | newString.trim(); | ||
+ | input.setElementAt(newString, i); | ||
+ | } | ||
+ | else | ||
+ | input.setElementAt("", i); | ||
+ | } | ||
+ | } | ||
+ | //Remove colons from labels and throw exceptions on empty labels. | ||
+ | for(int i = 0; i < labels.size(); i++) { | ||
+ | try { | ||
+ | errorLine = labels.elementAt(i).lineNumber; | ||
+ | labels.elementAt(i).labelName = labels.elementAt(i).labelName.split(":")[0]; | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid label", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | //Check for reserved words. | ||
+ | for(int i = 0; i < labels.size(); i++) { | ||
+ | try { | ||
+ | errorLine = labels.elementAt(i).lineNumber; | ||
+ | for(int j = 0; j < reserved.length; j++) | ||
+ | if(labels.elementAt(i).labelName.toLowerCase().equals(reserved[j].toLowerCase())) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Reserved word used in label", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | //Check for invalid characters. | ||
+ | for(int i = 0; i < labels.size(); i++) { | ||
+ | try { | ||
+ | errorLine = labels.elementAt(i).lineNumber; | ||
+ | for(int j = 0; j < invalidChars.length; j++) | ||
+ | if(labels.elementAt(i).labelName.contains(invalidChars[j])) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid character in label", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | //Check to make sure label does not start with a number. | ||
+ | for(int i = 0; i < labels.size(); i++) { | ||
+ | try { | ||
+ | errorLine = labels.elementAt(i).lineNumber; | ||
+ | if(Character.isDigit(labels.elementAt(i).labelName.charAt(0))) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Label starting with a number", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | //Check for duplicate labels. | ||
+ | for(int i = 0; i < labels.size() - 1; i++) { | ||
+ | try { | ||
+ | for(int j = i + 1; j < labels.size(); j++) { | ||
+ | errorLine = labels.elementAt(j).lineNumber; | ||
+ | if(labels.elementAt(i).labelName.equals(labels.elementAt(j).labelName)) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Duplicate label", errorLine)); | ||
+ | //System.err.println("Duplicate label. Line " + errorLine); | ||
+ | //System.exit(1); | ||
+ | } | ||
+ | } | ||
+ | //Check for labels already being used as aliases. | ||
+ | for(int i = 0; i < labels.size(); i++) { | ||
+ | try{ | ||
+ | for(int j = 0; j < aliases.size(); j++) { | ||
+ | errorLine = labels.elementAt(i).lineNumber; | ||
+ | if(labels.elementAt(i).labelName.equals(aliases.elementAt(j).aliasString)) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Label already used as alias", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void ProcessCode() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | int instType, argument1, argument2; | ||
+ | String argHex1, argHex2; | ||
+ | errorLine = i + 1; | ||
+ | String s = input.elementAt(i); | ||
+ | if(s.length() != 0) { | ||
+ | String[] tokenizedString = s.split(" "); | ||
+ | instType = GetInstType(tokenizedString[0]); | ||
+ | //Check to see if instruction is a valid instruction. | ||
+ | try { | ||
+ | if(instType == -1) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Undefined instruction", errorLine)); | ||
+ | } | ||
+ | try { | ||
+ | if(tokenizedString.length != instType) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Incorrect number of arguments", errorLine)); | ||
+ | } | ||
+ | //Check if instruction is a constant instruction and change it accordingly. | ||
+ | if(instType == 3 && tokenizedString[2].startsWith("#")) { | ||
+ | tokenizedString[0] = tokenizedString[0] + "k"; | ||
+ | tokenizedString[2] = tokenizedString[2].substring(1, tokenizedString[2].length()); | ||
+ | //Special case for LOAD rx, #k for loading labels. | ||
+ | if(tokenizedString[0].toLowerCase().equals("loadk")) | ||
+ | for(int j = 0; j < labels.size(); j++) | ||
+ | if(tokenizedString[2].equals(labels.elementAt(j).labelName)) | ||
+ | tokenizedString[2] = "" + labels.elementAt(j).labelAddress; | ||
+ | input.setElementAt((tokenizedString[0] + " " + tokenizedString[1] + " " + tokenizedString[2]), i); | ||
+ | } | ||
+ | if(instType == 2 && tokenizedString[1].startsWith("#")) { | ||
+ | tokenizedString[0] = tokenizedString[0] + "k"; | ||
+ | tokenizedString[1] = tokenizedString[1].substring(1, tokenizedString[1].length()); | ||
+ | input.setElementAt((tokenizedString[0] + " " + tokenizedString[1]), i); | ||
+ | } | ||
+ | //Check if instruction is an indirect instruction and change it accordingly. | ||
+ | if(instType == 3 && tokenizedString[2].startsWith("(") && tokenizedString[2].endsWith(")")) { | ||
+ | tokenizedString[0] = tokenizedString[0] + "i"; | ||
+ | tokenizedString[2] = tokenizedString[2].substring(1, tokenizedString[2].length() - 1); | ||
+ | input.setElementAt((tokenizedString[0] + " " + tokenizedString[1] + " " + tokenizedString[2]), i); | ||
+ | } | ||
+ | if(instType == 2 && tokenizedString[1].startsWith("(") && tokenizedString[1].endsWith(")")) { | ||
+ | tokenizedString[0] = tokenizedString[0] + "i"; | ||
+ | tokenizedString[1] = tokenizedString[1].substring(1, tokenizedString[1].length() - 1); | ||
+ | input.setElementAt((tokenizedString[0] + " " + tokenizedString[1]), i); | ||
+ | } | ||
+ | //Check to see if illegal addressing mode for this instruction. | ||
+ | try { | ||
+ | for(int j = 0; j < invalidInst.length; j++) | ||
+ | if(tokenizedString[0].toLowerCase().equals(invalidInst[j])) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid addressing mode", errorLine)); | ||
+ | } | ||
+ | //Substitute labels for addresses. | ||
+ | if(tokenizedString[0].toLowerCase().equals("jump") || tokenizedString[0].toLowerCase().equals("jpnz") || | ||
+ | tokenizedString[0].toLowerCase().equals("jpz") || tokenizedString[0].toLowerCase().equals("jpnc") || | ||
+ | tokenizedString[0].toLowerCase().equals("jpc") || tokenizedString[0].toLowerCase().equals("call") || | ||
+ | tokenizedString[0].toLowerCase().equals("clnz") || tokenizedString[0].toLowerCase().equals("clz") || | ||
+ | tokenizedString[0].toLowerCase().equals("clnc") || tokenizedString[0].toLowerCase().equals("clc")) | ||
+ | for(int j = 0; j < labels.size(); j++) | ||
+ | if(tokenizedString[1].equals(labels.elementAt(j).labelName)) | ||
+ | input.setElementAt((tokenizedString[0] + " " + labels.elementAt(j).labelAddress), i); | ||
+ | //Validate parameters and replace instructions with opcodes. | ||
+ | try { | ||
+ | //Single argument instruction. | ||
+ | if(instType == 1) | ||
+ | for(int j = 0; j < completeInst.length; j++) | ||
+ | if(tokenizedString[0].toLowerCase().equals(completeInst[j])) | ||
+ | input.setElementAt((opcodes[j] + "0000000"), i); | ||
+ | //Two argument, indirect instruction or direct instruction. | ||
+ | if(instType == 2 && (tokenizedString[0].endsWith("i") || tokenizedString[0].toLowerCase().equals("asl") || | ||
+ | tokenizedString[0].toLowerCase().equals("rol") || tokenizedString[0].toLowerCase().equals("lsr") || | ||
+ | tokenizedString[0].toLowerCase().equals("ror") || tokenizedString[0].toLowerCase().equals("push") || | ||
+ | tokenizedString[0].toLowerCase().equals("pop"))) { | ||
+ | argument1 = NumberConverter(tokenizedString[1]); | ||
+ | try { | ||
+ | if(argument1 >= 0x400) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Register address out of range", errorLine)); | ||
+ | } | ||
+ | //convert integer to hex string. | ||
+ | argHex1 = Integer.toHexString(argument1); | ||
+ | //Add leading zeroes, if necessary. | ||
+ | if(argHex1.length() == 1) | ||
+ | argHex1 = "00" + argHex1; | ||
+ | if(argHex1.length() == 2) | ||
+ | argHex1 = "0" + argHex1; | ||
+ | //Replace command in input vector with opcode. | ||
+ | for(int j = 0; j < completeInst.length; j++) | ||
+ | if(tokenizedString[0].toLowerCase().equals(completeInst[j])) | ||
+ | input.setElementAt((opcodes[j] + argHex1.toUpperCase() + "0000"), i); | ||
+ | } | ||
+ | //Two argument, address instruction. | ||
+ | if(tokenizedString[0].toLowerCase().equals("jump") || tokenizedString[0].toLowerCase().equals("jpnz") || | ||
+ | tokenizedString[0].toLowerCase().equals("jpz") || tokenizedString[0].toLowerCase().equals("jpnc") || | ||
+ | tokenizedString[0].toLowerCase().equals("jpc") || tokenizedString[0].toLowerCase().equals("call") || | ||
+ | tokenizedString[0].toLowerCase().equals("clnz") || tokenizedString[0].toLowerCase().equals("clz") || | ||
+ | tokenizedString[0].toLowerCase().equals("clnc") || tokenizedString[0].toLowerCase().equals("clc")) { | ||
+ | //Retokenize line string. | ||
+ | s = input.elementAt(i); | ||
+ | tokenizedString = s.split(" "); | ||
+ | argument1 = NumberConverter(tokenizedString[1]); | ||
+ | try { | ||
+ | if(argument1 >= 0x10000) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("ROM address out of range", errorLine)); | ||
+ | } | ||
+ | //Jump out of program size limit. | ||
+ | try { | ||
+ | if(argument1 > sizeLimit) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("JUMP/CALL address greater than program size limit", errorLine)); | ||
+ | } | ||
+ | //convert integer to hex string. | ||
+ | argHex1 = Integer.toHexString(argument1); | ||
+ | //Add leading zeroes, if necessary. | ||
+ | if(argHex1.length() == 1) | ||
+ | argHex1 = "000" + argHex1; | ||
+ | if(argHex1.length() == 2) | ||
+ | argHex1 = "00" + argHex1; | ||
+ | if(argHex1.length() == 3) | ||
+ | argHex1 = "0" + argHex1; | ||
+ | //Replace command in input vector with opcode. | ||
+ | for(int j = 0; j < completeInst.length; j++) | ||
+ | if(tokenizedString[0].toLowerCase().equals(completeInst[j])) | ||
+ | input.setElementAt((opcodes[j] + "000" + argHex1.toUpperCase()), i); | ||
+ | } | ||
+ | //Three argument, indirect instruction and immediate instruction. | ||
+ | if(instType == 3) { | ||
+ | //Identify instruction. | ||
+ | for(int j = 0; j < completeInst.length; j++) { | ||
+ | if(tokenizedString[0].toLowerCase().equals(completeInst[j])) { | ||
+ | //First argument same type regardless of instruction type. | ||
+ | argument1 = NumberConverter(tokenizedString[1]); | ||
+ | try { | ||
+ | if(argument1 >= 0x400) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Register address out of range", errorLine)); | ||
+ | } | ||
+ | //Add leading zeroes, if necessary. | ||
+ | argHex1 = Integer.toHexString(argument1); | ||
+ | if(argHex1.length() == 1) | ||
+ | argHex1 = "00" + argHex1; | ||
+ | if(argHex1.length() == 2) | ||
+ | argHex1 = "0" + argHex1; | ||
+ | //Indirect instruction. | ||
+ | if(tokenizedString[0].endsWith("i")) { | ||
+ | argument2 = NumberConverter(tokenizedString[2]); | ||
+ | try { | ||
+ | if(argument2 >= 0x400) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Register address out of range", errorLine)); | ||
+ | } | ||
+ | //Add leading zeroes, if necessary. | ||
+ | argHex2 = Integer.toHexString(argument2); | ||
+ | if(argHex2.length() == 1) | ||
+ | argHex2 = "000" + argHex2; | ||
+ | if(argHex2.length() == 2) | ||
+ | argHex2 = "00" + argHex2; | ||
+ | if(argHex2.length() == 3) | ||
+ | argHex2 = "0" + argHex2; | ||
+ | } | ||
+ | //Immediate instruction. | ||
+ | else if(tokenizedString[0].endsWith("k")){ | ||
+ | argument2 = NumberConverter(tokenizedString[2]); | ||
+ | try { | ||
+ | if(argument2 >= 0x10000) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Constant value out of range", errorLine)); | ||
+ | } | ||
+ | //Add leading zeroes, if necessary. | ||
+ | argHex2 = Integer.toHexString(argument2); | ||
+ | if(argHex2.length() == 1) | ||
+ | argHex2 = "000" + argHex2; | ||
+ | if(argHex2.length() == 2) | ||
+ | argHex2 = "00" + argHex2; | ||
+ | if(argHex2.length() == 3) | ||
+ | argHex2 = "0" + argHex2; | ||
+ | } | ||
+ | //Direct instruction. | ||
+ | else { | ||
+ | argument2 = NumberConverter(tokenizedString[2]); | ||
+ | try { | ||
+ | if(argument2 >= 0x400) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch (Exception excepion) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Register address out of range", errorLine)); | ||
+ | } | ||
+ | //Add leading zeroes, if necessary. | ||
+ | argHex2 = Integer.toHexString(argument2); | ||
+ | if(argHex2.length() == 1) | ||
+ | argHex2 = "000" + argHex2; | ||
+ | if(argHex2.length() == 2) | ||
+ | argHex2 = "00" + argHex2; | ||
+ | if(argHex2.length() == 3) | ||
+ | argHex2 = "0" + argHex2; | ||
+ | } | ||
+ | //Replace command in input vector with opcode. | ||
+ | input.setElementAt((opcodes[j] + argHex1.toUpperCase() + argHex2.toUpperCase()), i); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Invalid parameter", errorLine)); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int GetInstType(String s) { | ||
+ | //Search through the instructions to make sure they are valid and | ||
+ | //determine how many parameters each instruction should have. | ||
+ | for(int i = 0; i < inst1.length; i++) { | ||
+ | if(s.toLowerCase().equals(inst1[i])) | ||
+ | return 1; | ||
+ | } | ||
+ | for(int i = 0; i < inst2.length; i++) { | ||
+ | if(s.toLowerCase().equals(inst2[i])) | ||
+ | return 2; | ||
+ | } | ||
+ | for(int i = 0; i < inst3.length; i++) { | ||
+ | if(s.toLowerCase().equals(inst3[i])) | ||
+ | return 3; | ||
+ | } | ||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | void FillOutput() { | ||
+ | for(int i = 0; i < input.size(); i++) { | ||
+ | errorLine = i + 1; | ||
+ | //Process element only if it contains data. | ||
+ | if(input.elementAt(i).length() != 0) { | ||
+ | //Make sure address is within program size limit. | ||
+ | try { | ||
+ | if(addresses.elementAt(i) >= sizeLimit) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | error.addElement(new Error("Instruction address exceeds program size limit", errorLine)); | ||
+ | } | ||
+ | //Check to see if instruction address is not already occupied. | ||
+ | try { | ||
+ | if(!output[addresses.elementAt(i)].equals("000000000")) | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | catch(Exception exception) { | ||
+ | if(!CheckErrorLine(errorLine)) | ||
+ | error.addElement(new Error("Instruction address already occupied", errorLine)); | ||
+ | } | ||
+ | //Write opcode to output vector. | ||
+ | if(error.isEmpty()) | ||
+ | output[addresses.elementAt(i)] = input.elementAt(i); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void WriteOutput() { | ||
+ | String memInit = "memory_initialization_radix=16;"; | ||
+ | String initVector = "memory_initialization_vector="; | ||
+ | try { | ||
+ | write.setLength(0); //Erase any previous contents. | ||
+ | write.writeBytes(memInit); //Write init strings. | ||
+ | write.writeByte(0x0D); //Notepad new lines. | ||
+ | write.writeByte(0x0A); | ||
+ | write.writeBytes(initVector); | ||
+ | //Write opcodes. | ||
+ | for(int i = 0; i < output.length - 1; i++) { | ||
+ | //New line after every eight opcodes. | ||
+ | if(i % 8 == 0) { | ||
+ | write.writeByte(0x0D); //Notepad new lines. | ||
+ | write.writeByte(0x0A); | ||
+ | } | ||
+ | write.writeBytes(output[i] + ", "); | ||
+ | } | ||
+ | //Write last instruction in file. | ||
+ | if((output.length % 8 == 1) && (output.length > 1)) { | ||
+ | write.writeByte(0x0D); //Notepad new lines. | ||
+ | write.writeByte(0x0A); | ||
+ | } | ||
+ | write.writeBytes(output[output.length - 1] + ";"); | ||
+ | } | ||
+ | catch (IOException ioException) { | ||
+ | System.err.println("Error writing to .coe file: " + ioException); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void PrintErrors() { | ||
+ | if(error.isEmpty()) { | ||
+ | System.out.println("\nNo errors detected."); | ||
+ | return; | ||
+ | } | ||
+ | System.out.println("\nErrors:"); | ||
+ | for(int i = 0; i < error.size(); i++) { | ||
+ | System.out.println(error.elementAt(i).errorString + " " + error.elementAt(i).errorLine); | ||
+ | } | ||
+ | System.out.println("Total errors: " + error.size()); | ||
+ | System.exit(1); | ||
+ | } | ||
+ | |||
+ | boolean CheckErrorLine(int errorLine) { | ||
+ | for(int i = 0; i < error.size(); i++) | ||
+ | if(error.elementAt(i).errorLine == errorLine) | ||
+ | return true; | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | /////////////////////////////////Main method//////////////////////////////////// | ||
+ | public static void main(String[] args) { | ||
+ | NMPSM3 nmpsm3 = new NMPSM3(args); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | #### NMPSM3软件 | ||
+ | 下面的第一个文件是控制项目的汇编语言程序。下一个文件是汇编器的编译版本。第三个文件是一个简单的批处理文件,它运行汇编程序并将NMPSM3代码汇编为.coe文件。\\ | ||
+ | |||
+ | ##### program.asm | ||
+ | <code verilog> | ||
+ | |||
+ | .size 1024 | ||
+ | |||
+ | ;------------------------------------Addressable hardware list------------------------------------- | ||
+ | ;0x0000 - 0x0007 ROM controller. | ||
+ | ;0x0010 Timer 0. | ||
+ | ;0x0011 Timer 1. | ||
+ | ;0x0012 Input MUX - ROM data. | ||
+ | ;0x0013 Input MUX - Switches. | ||
+ | ;0x0020 LED controller. | ||
+ | ;0x0024 - 0x0027 Seven segment controller. | ||
+ | ;0x0030 - 0x0033 Input MUX - Clock data. | ||
+ | ;0x0034 Input MUX - Microphone data. | ||
+ | |||
+ | ;-------------------------------------VGA Controller addresses------------------------------------- | ||
+ | ;0x8000 - 0x87FF Background pattern table A. | ||
+ | ;0x8800 - 0x8FFF Background pattern table B. | ||
+ | ;0x9000 - 0x97FF Sprite pattern table A. | ||
+ | ;0x9800 - 0x9FFF Sprite pattern table B. | ||
+ | ;0xA000 - 0xA3FF Name table. | ||
+ | ;0xA400 - 0xA4FF Unused. | ||
+ | ;0xA500 - 0xA5FF Background attribute table. | ||
+ | ;0xA600 - 0xA60F Background pallettes 0 through 15. | ||
+ | ;0xA610 - 0xA61F Sprite pallettes 0 through 15. | ||
+ | ;0xA700 Base color (background color). | ||
+ | ;0xB000 - 0xB3FF Sprite RAM (256 sprites). | ||
+ | |||
+ | ;--------------------------------------Sprite RAM Memory Map--------------------------------------- | ||
+ | ;0xB000 - 0xb01F Bouncing sprites (8 sprites). | ||
+ | ;0xB020 - 0xB05F Rotation sprites (16 sprites). | ||
+ | ;0xB0D0 - 0xB0FF Samus sprites (12 sprites). | ||
+ | ;0xB100 - 0xB2FF Audio sprites. | ||
+ | |||
+ | ;---------------------------------------------Defines---------------------------------------------- | ||
+ | ;ASCII numbers. | ||
+ | .alias ZERO #$30 | ||
+ | .alias ONE #$31 | ||
+ | .alias TWO #$32 | ||
+ | .alias THREE #$33 | ||
+ | .alias FOUR #$34 | ||
+ | .alias FIVE #$35 | ||
+ | .alias SIX #$36 | ||
+ | .alias SEVEN #$37 | ||
+ | .alias EIGHT #$38 | ||
+ | .alias NINE #$39 | ||
+ | |||
+ | ;ASCII letters. | ||
+ | .alias A #$41 | ||
+ | .alias B #$42 | ||
+ | .alias C #$43 | ||
+ | .alias D #$44 | ||
+ | .alias E #$45 | ||
+ | .alias F #$46 | ||
+ | .alias G #$47 | ||
+ | .alias H #$48 | ||
+ | .alias I #$49 | ||
+ | .alias J #$4A | ||
+ | .alias K #$4B | ||
+ | .alias L #$4C | ||
+ | .alias M #$4D | ||
+ | .alias N #$4E | ||
+ | .alias O #$4F | ||
+ | .alias P #$50 | ||
+ | .alias Q #$51 | ||
+ | .alias R #$52 | ||
+ | .alias S #$53 | ||
+ | .alias T #$54 | ||
+ | .alias U #$55 | ||
+ | .alias V #$56 | ||
+ | .alias W #$57 | ||
+ | .alias X #$58 | ||
+ | .alias Y #$59 | ||
+ | .alias Z #$5A | ||
+ | |||
+ | .alias a #$61 | ||
+ | .alias b #$62 | ||
+ | .alias c #$63 | ||
+ | .alias d #$64 | ||
+ | .alias e #$65 | ||
+ | .alias f #$66 | ||
+ | .alias g #$67 | ||
+ | .alias h #$68 | ||
+ | .alias i #$69 | ||
+ | .alias j #$6A | ||
+ | .alias k #$6B | ||
+ | .alias l #$6C | ||
+ | .alias m #$6D | ||
+ | .alias n #$6E | ||
+ | .alias o #$6F | ||
+ | .alias p #$70 | ||
+ | .alias q #$71 | ||
+ | .alias r #$72 | ||
+ | .alias s #$73 | ||
+ | .alias t #$74 | ||
+ | .alias u #$75 | ||
+ | .alias v #$76 | ||
+ | .alias w #$77 | ||
+ | .alias x #$78 | ||
+ | .alias y #$79 | ||
+ | .alias z #$7A | ||
+ | |||
+ | ;ASCII symbols. | ||
+ | .alias SPACE #$20 | ||
+ | .alias COLON #$3A | ||
+ | .alias COMMA #$2C | ||
+ | .alias PERIOD #$2E | ||
+ | .alias CR #$0D ;Carriage return. | ||
+ | .alias FSLASH #$2F ;Forward slash. | ||
+ | .alias LBAR #$5F ;Underscore. | ||
+ | .alias MBAR #$2D ;Minus sign. | ||
+ | .alias UBAR #$FF ;Upper bar. | ||
+ | .alias STAR #$2A ;Multiply sign. | ||
+ | .alias OPEN_C_BRACE #$7B ;Open curly brace. | ||
+ | |||
+ | ;Output port IDs. | ||
+ | .alias LEDTBL #$0000 ; | ||
+ | .alias TIMELOTBL #$0001 ; | ||
+ | .alias SEG7INDEXTBL #$0002 ; | ||
+ | .alias SEG7TBL #$0003 ; | ||
+ | .alias LOOKUPADDR #$0004 ;ROM addresses. | ||
+ | .alias MESSAGETBL #$0005 ; | ||
+ | .alias PALETTETBL #$0006 ; | ||
+ | .alias SPRITETBL #$0007 ; | ||
+ | .alias SAMUSTBL #$0006 ; | ||
+ | |||
+ | .alias SET_BAUD #$0200 ; | ||
+ | .alias TX_STORE_BYTE #$0201 ; | ||
+ | .alias TX_FLUSH #$0202 ;UART control. | ||
+ | .alias TX_PURGE #$0203 ; | ||
+ | .alias RX_NEXT_BYTE #$0204 ; | ||
+ | .alias RX_PURGE #$0205 ; | ||
+ | |||
+ | .alias DOT0 #$A288 ; | ||
+ | .alias DOT1 #$A294 ;Name table addresses--> | ||
+ | .alias DOT2 #$A2E8 ;for clock dots. | ||
+ | .alias DOT3 #$A2F4 ; | ||
+ | |||
+ | .alias LOSEC #$A29B ; | ||
+ | .alias HISEC #$A296 ;Starting addresses of--> | ||
+ | .alias LOMIN #$A28F ;clock digits in name--> | ||
+ | .alias HIMIN #$A28A ;table. | ||
+ | .alias LOHOUR #$A283 ; | ||
+ | |||
+ | .alias A #$A29F ;Name table positions--> | ||
+ | .alias B #$A2FF ;of A and P in clock. | ||
+ | |||
+ | .alias TIMER0 #$0010 ;Timers | ||
+ | .alias TIMER1 #$0011 ; | ||
+ | |||
+ | .alias LEDIO #$0020 ;LED controller. | ||
+ | .alias LEDIO2 #$0021 ;Upper LED controller. | ||
+ | |||
+ | .alias SEG0 #$0024 ; | ||
+ | .alias SEG1 #$0025 ;7 segment display | ||
+ | .alias SEG2 #$0026 ; | ||
+ | .alias SEG3 #$0027 ; | ||
+ | |||
+ | ;Input port IDs. | ||
+ | .alias UARTDATA #$0003 ; | ||
+ | .alias TXCOUNT #$0004 ;UART ports. | ||
+ | .alias RXCOUNT #$0005 ; | ||
+ | |||
+ | .alias ROMDATA #$0012 ;ROM data | ||
+ | .alias SWITCHES #$0013 ;Switches | ||
+ | |||
+ | .alias SEC #$0030 ; | ||
+ | .alias MIN #$0031 ;Clock data | ||
+ | .alias HOUR #$0032 ; | ||
+ | .alias BLINK #$0033 ; | ||
+ | |||
+ | .alias MICDATA #$0034 ;Mic data | ||
+ | |||
+ | ;RAM aliases. | ||
+ | .alias ledIndex $0000 | ||
+ | .alias timeIndex $0001 | ||
+ | .alias segIndex $0002 | ||
+ | .alias switchReg $0003 | ||
+ | .alias waitReg $0004 | ||
+ | |||
+ | .alias sp0y $0010 ; | ||
+ | .alias sp1y $0011 ; | ||
+ | .alias sp2y $0012 ; | ||
+ | .alias sp3y $0013 ;Bouncing sprite y positions. | ||
+ | .alias sp4y $0014 ; | ||
+ | .alias sp5y $0015 ; | ||
+ | .alias sp6y $0016 ; | ||
+ | .alias sp7y $0017 ; | ||
+ | |||
+ | .alias sp0x $0018 ; | ||
+ | .alias sp1x $0019 ; | ||
+ | .alias sp2x $001A ; | ||
+ | .alias sp3x $001B ;Bouncing sprite x positions. | ||
+ | .alias sp4x $001C ; | ||
+ | .alias sp5x $001D ; | ||
+ | .alias sp6x $001E ; | ||
+ | .alias sp7x $001F ; | ||
+ | |||
+ | .alias sp0m $0020 ; | ||
+ | .alias sp1m $0021 ; | ||
+ | .alias sp2m $0022 ; | ||
+ | .alias sp3m $0023 ;Bouncing sprite move directions. | ||
+ | .alias sp4m $0024 ; | ||
+ | .alias sp5m $0025 ; | ||
+ | .alias sp6m $0026 ; | ||
+ | .alias sp7m $0027 ; | ||
+ | |||
+ | .alias palRegs $0030 ;Thru $4F | ||
+ | .alias tempReg0 $0050 | ||
+ | .alias tempReg1 $0051 | ||
+ | .alias tempReg2 $0052 | ||
+ | .alias tempReg3 $0053 | ||
+ | .alias colCount $0054 | ||
+ | .alias rowCount $0055 | ||
+ | .alias numIn $0056 | ||
+ | .alias numOffset $0057 | ||
+ | .alias AMPMReg0 $0058 | ||
+ | .alias AMPMReg1 $0059 | ||
+ | .alias startReg $005A | ||
+ | .alias stopReg $005B | ||
+ | .alias mIndexReg $005C | ||
+ | .alias bcDelReg $005D | ||
+ | .alias bcReg $005E | ||
+ | .alias checkReg $005F | ||
+ | .alias palDelReg $0060 | ||
+ | .alias mirDelReg $0061 | ||
+ | .alias mirPtrReg $0062 | ||
+ | .alias audPtrReg $0063 | ||
+ | .alias audCtrReg $0064 | ||
+ | .alias audHldReg $0065 | ||
+ | .alias miscReg $0066 | ||
+ | .alias atDelReg $0067 | ||
+ | .alias atStatReg $0068 | ||
+ | .alias callReg $0069 | ||
+ | .alias clearReg $006A | ||
+ | .alias swReg $006B | ||
+ | .alias anDelReg $006C | ||
+ | .alias samROMReg $006D | ||
+ | .alias samXReg $006E | ||
+ | .alias movDelReg $006F | ||
+ | .alias samM0Reg $0090 | ||
+ | .alias samM1Reg $0091 | ||
+ | .alias samM2Reg $0092 | ||
+ | .alias micDelReg $0093 | ||
+ | .alias micStaReg $0094 | ||
+ | .alias micSmpReg $0095 | ||
+ | .alias waitStateReg $0096 | ||
+ | .alias audioRegs $0100 ;Through $17F(128 total). | ||
+ | |||
+ | .alias uartTxByte $0180 ; | ||
+ | .alias uartRxByte $0181 ;UART value registers. | ||
+ | .alias uartTxCount $0182 ; | ||
+ | .alias uartRxCount $0183 ; | ||
+ | |||
+ | .alias bufCurPointer $0184 ;Pointer to current position in uart buffer. | ||
+ | .alias bufEndPointer $0185 ;Pointer to last position in uart buffer. | ||
+ | .alias uartBuf $0186 ;thru $01A1. | ||
+ | |||
+ | ;Constants. | ||
+ | .alias UPRIGHT #$20 | ||
+ | .alias UPLEFT #$60 | ||
+ | .alias DOWNRIGHT #$A0 | ||
+ | .alias DOWNLEFT #$E0 | ||
+ | .alias PALREGS #$30 | ||
+ | .alias AT0 #$1B | ||
+ | .alias AT1 #$C6 | ||
+ | .alias AT2 #$B1 | ||
+ | .alias AT3 #$6C | ||
+ | |||
+ | .alias SPRITEREGS #$0100 ;Start of sprite audio regs. | ||
+ | .alias ENDAUDIOREGS #$0180 ;End of sprite audio regs. | ||
+ | .alias PPUAUDSPSTART #$B100 ;Start address of audio sprites in PPU. | ||
+ | .alias PPUAUDSPEND #$B300 ;End address of audio sprites in PPU. | ||
+ | |||
+ | ;-------------------------------------------Start of code------------------------------------------ | ||
+ | jump Reset ; | ||
+ | jump Interrupt0 ; | ||
+ | jump Interrupt1 ;Reset and interrupt vectors. | ||
+ | jump Interrupt2 ; | ||
+ | jump Interrupt3 ; | ||
+ | |||
+ | Reset: | ||
+ | call ClearRegs | ||
+ | call ClearBouncingSprites | ||
+ | call SetDefaultPalettes | ||
+ | call InitLEDIndex | ||
+ | call Init7SegsIndex | ||
+ | | ||
+ | load micSmpReg, #$0080 | ||
+ | load samROMReg, #$40 | ||
+ | load samXReg , #$E5 | ||
+ | load samM0Reg , #$03 | ||
+ | load samM1Reg , #$03 | ||
+ | load samM2Reg , #$03 | ||
+ | load AMPMReg1 , #$11 | ||
+ | load tempReg0 , #5 | ||
+ | out tempReg0 , TIMER0 | ||
+ | out tempReg0 , TIMER1 | ||
+ | | ||
+ | load uartTxByte #$D9 ;Set UART baud rate to 230400. | ||
+ | out uartTxByte SET_BAUD ; | ||
+ | | ||
+ | ein0 | ||
+ | ein1 | ||
+ | ein2 | ||
+ | |||
+ | MainLoop: | ||
+ | comp waitReg , #1 ;Check to see if current--> | ||
+ | jpz MainLoop ;frame processing is done. | ||
+ | din2 ;Disable VBlank interrupt. | ||
+ | | ||
+ | load waitReg , #1 ;Process current frame data. | ||
+ | add micDelReg, #1 | ||
+ | comp micDelReg, #3 | ||
+ | clz GetAudioData | ||
+ | | ||
+ | ein2 ;Enable VBlank interrupt. | ||
+ | jump MainLoop ;Run main loop forever. | ||
+ | | ||
+ | ;The following function sets all the register values to 0. | ||
+ | ClearRegs: | ||
+ | load 0 #$3FF ; | ||
+ | load 1 #0 ; | ||
+ | ClearRegsLoop: ;Start at top register and--> | ||
+ | stor 1 (0) ;decrement through them setting--> | ||
+ | sub 0 #1 ;them all to 0. | ||
+ | jpnz ClearRegsLoop ; | ||
+ | ret ; | ||
+ | | ||
+ | Interrupt0: | ||
+ | out timeIndex, TIMELOTBL | ||
+ | in tempReg0 , ROMDATA | ||
+ | or tempReg0 , #0 | ||
+ | clz InitLEDIndex | ||
+ | | ||
+ | out timeIndex, TIMELOTBL | ||
+ | in tempReg0 , ROMDATA | ||
+ | out tempReg0 , TIMER0 | ||
+ | | ||
+ | out ledIndex , LEDTBL | ||
+ | in tempReg0 , ROMDATA | ||
+ | out tempReg0 , LEDIO | ||
+ | | ||
+ | add timeIndex, #1 | ||
+ | add ledIndex , #1 | ||
+ | rtie | ||
+ | | ||
+ | InitLEDIndex: | ||
+ | load ledIndex , #0 | ||
+ | load timeIndex, #0 | ||
+ | ret | ||
+ | | ||
+ | Interrupt1: | ||
+ | comp segIndex , #$20 | ||
+ | clz Init7SegsIndex | ||
+ | | ||
+ | load tempReg0 , segIndex | ||
+ | load tempReg2 , SEG0 | ||
+ | call DoSeg | ||
+ | | ||
+ | add tempReg0 , #1 | ||
+ | load tempReg2 , SEG1 | ||
+ | call DoSeg | ||
+ | | ||
+ | add tempReg0 , #1 | ||
+ | load tempReg2 , SEG2 | ||
+ | call DoSeg | ||
+ | | ||
+ | add tempReg0 , #1 | ||
+ | load tempReg2 , SEG3 | ||
+ | call DoSeg | ||
+ | | ||
+ | load tempReg0 , #$B0 | ||
+ | out tempReg0 , TIMER1 | ||
+ | | ||
+ | add segIndex , #1 | ||
+ | rtie | ||
+ | |||
+ | DoSeg: | ||
+ | out tempReg0 , SEG7INDEXTBL | ||
+ | in tempReg1 , ROMDATA | ||
+ | out tempReg1 , SEG7TBL | ||
+ | in tempReg1 , ROMDATA | ||
+ | out tempReg1 , tempReg2 | ||
+ | ret | ||
+ | | ||
+ | Init7SegsIndex: | ||
+ | load segIndex , #0 | ||
+ | ret | ||
+ | | ||
+ | Interrupt2: | ||
+ | Interrupt3: | ||
+ | load waitReg , #0 | ||
+ | call DoMessage | ||
+ | call DoClock | ||
+ | call DoBaseColor | ||
+ | call DoBouncingSprites | ||
+ | call DoPaletteChange | ||
+ | call DoSpriteMirroring | ||
+ | call DoSpriteAudio | ||
+ | call DoAttribChange | ||
+ | call DoSpritePriority | ||
+ | call DoUART ;Check for waiting data in UART. | ||
+ | rtie | ||
+ | | ||
+ | DoFunction: | ||
+ | in switchReg, SWITCHES | ||
+ | and switchReg, swReg | ||
+ | DoSubFunction: | ||
+ | comp switchReg, swReg | ||
+ | jpz RunFunction | ||
+ | jump ClearFunction | ||
+ | RunFunction: | ||
+ | jump (callReg) | ||
+ | ClearFunction: | ||
+ | jump (clearReg) | ||
+ | DoZeroFunction: | ||
+ | in switchReg, SWITCHES | ||
+ | jump DoSubFunction | ||
+ | | ||
+ | DoUART: | ||
+ | call CheckUART ;;Get any waiting bytes from UART. | ||
+ | call EchoByte ;Echo byte back to terminal. | ||
+ | ret | ||
+ | | ||
+ | CheckUART: | ||
+ | in uartRxByte, UARTDATA ;Get UART byte. | ||
+ | comp uartRxByte, #0 ;See if it is a valid byte. | ||
+ | rtz ;If not, return. | ||
+ | | ||
+ | out uartRxByte, LEDIO2 ;Echo byte to the upper LEDs. | ||
+ | out uartRxByte, TX_STORE_BYTE ;Echo byte back to terminal. | ||
+ | out uartRxByte, RX_NEXT_BYTE ;Move to next position. | ||
+ | jump CheckUART | ||
+ | | ||
+ | EchoByte: | ||
+ | out tempReg0, TX_FLUSH ;Flush tx output. | ||
+ | ret ; | ||
+ | | ||
+ | DoClock: | ||
+ | load swReg , #$01 | ||
+ | load callReg , #LoadClock | ||
+ | load clearReg , #ClearClock | ||
+ | jump DoFunction | ||
+ | | ||
+ | LoadClock: | ||
+ | in tempReg0 , BLINK | ||
+ | or tempReg0 , #0 | ||
+ | clnz DrawDots | ||
+ | or tempReg0 , #0 | ||
+ | clz ClearDots | ||
+ | in tempReg0 , HOUR | ||
+ | and tempReg0 , #$00F0 | ||
+ | clnz DrawOne | ||
+ | and tempReg0 , #$00F0 | ||
+ | clz ClearOne | ||
+ | | ||
+ | in tempReg0 , SEC | ||
+ | call NibbleShift | ||
+ | load numOffset, LOSEC | ||
+ | call DisplayDigit | ||
+ | | ||
+ | in tempReg0 , SEC | ||
+ | and tempReg0 , #$F0 | ||
+ | load numOffset, HISEC | ||
+ | call DisplayDigit | ||
+ | | ||
+ | in tempReg0 , MIN | ||
+ | call NibbleShift | ||
+ | load numOffset, LOMIN | ||
+ | call DisplayDigit | ||
+ | | ||
+ | in tempReg0 , MIN | ||
+ | and tempReg0 , #$F0 | ||
+ | load numOffset, HIMIN | ||
+ | call DisplayDigit | ||
+ | | ||
+ | in tempReg0 , HOUR | ||
+ | call NibbleShift | ||
+ | load numOffset, LOHOUR | ||
+ | call DisplayDigit | ||
+ | | ||
+ | call AMPM | ||
+ | load tempReg0 , AMPMReg0 | ||
+ | comp tempReg0 , #0 | ||
+ | clz AM | ||
+ | load tempReg0 , AMPMReg0 | ||
+ | comp tempReg0 , #0 | ||
+ | clnz PM | ||
+ | ret | ||
+ | |||
+ | DrawDots: | ||
+ | load tempReg0 , #$6F | ||
+ | out tempReg0 , DOT0 | ||
+ | out tempReg0 , DOT1 | ||
+ | out tempReg0 , DOT2 | ||
+ | out tempReg0 , DOT3 | ||
+ | ret | ||
+ | |||
+ | ClearDots: | ||
+ | load tempReg0 , #$FF | ||
+ | out tempReg0 , DOT0 | ||
+ | out tempReg0 , DOT1 | ||
+ | out tempReg0 , DOT2 | ||
+ | out tempReg0 , DOT3 | ||
+ | ret | ||
+ | |||
+ | DrawOne: | ||
+ | load tempReg0 , #$44 | ||
+ | out tempReg0 , #$A280 | ||
+ | load tempReg0 , #$4D | ||
+ | out tempReg0 , #$A281 | ||
+ | load tempReg0 , #$50 | ||
+ | out tempReg0 , #$A2A0 | ||
+ | load tempReg0 , #$47 | ||
+ | out tempReg0 , #$A2A1 | ||
+ | out tempReg0 , #$A2C1 | ||
+ | load tempReg0 , #$55 | ||
+ | out tempReg0 , #$A2E1 | ||
+ | ret | ||
+ | | ||
+ | ClearOne: | ||
+ | load tempReg0 , #$FF | ||
+ | out tempReg0 , #$A280 | ||
+ | out tempReg0 , #$A281 | ||
+ | out tempReg0 , #$A2A0 | ||
+ | out tempReg0 , #$A2A1 | ||
+ | out tempReg0 , #$A2C1 | ||
+ | out tempReg0 , #$A2E1 | ||
+ | ret | ||
+ | |||
+ | NibbleShift: | ||
+ | asl tempReg0 | ||
+ | asl tempReg0 | ||
+ | asl tempReg0 | ||
+ | asl tempReg0 | ||
+ | ret | ||
+ | |||
+ | DisplayDigit: | ||
+ | load colCount , #4 | ||
+ | load rowCount , #4 | ||
+ | DoCol: | ||
+ | out tempReg0 , LOOKUPADDR | ||
+ | in numIn , ROMDATA | ||
+ | out numIn , numOffset | ||
+ | add tempReg0 , #1 | ||
+ | add numOffset, #1 | ||
+ | sub colCount , #1 | ||
+ | jpnz DoCol | ||
+ | load colCount , #4 | ||
+ | DoRow: | ||
+ | sub rowCount , #1 | ||
+ | add numOffset , #$1C | ||
+ | or rowCount , #0 | ||
+ | rtz | ||
+ | jump DoCol | ||
+ | |||
+ | AMPM: | ||
+ | load tempReg0 , AMPMReg1 | ||
+ | in tempReg1 , HOUR | ||
+ | stor tempReg1 , AMPMReg1 | ||
+ | comp tempReg0 , #%00010001 | ||
+ | rtnz | ||
+ | comp tempReg1 , #%00010010 | ||
+ | rtnz | ||
+ | | ||
+ | ToggleAMPM: | ||
+ | xor AMPMReg0 , #$00FF | ||
+ | ret | ||
+ | |||
+ | AM: | ||
+ | load tempReg1 , #$0A | ||
+ | out tempReg1 , A | ||
+ | load tempReg1 , #$FF | ||
+ | out tempReg1 , B | ||
+ | ret | ||
+ | | ||
+ | PM: | ||
+ | load tempReg1 , #$FF | ||
+ | out tempReg1 , A | ||
+ | load tempReg1 , #$19 | ||
+ | out tempReg1 , B | ||
+ | ret | ||
+ | | ||
+ | ClearClock: | ||
+ | load startReg , #$A2FF | ||
+ | load stopReg , #$A27F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | |||
+ | ;Draw and clear on screen messages. | ||
+ | DoMessage: | ||
+ | load swReg , #$00 | ||
+ | load callReg , #ClearDemoMessage | ||
+ | load clearReg , #DrawDemoMessage | ||
+ | call DoZeroFunction | ||
+ | load swReg , #$01 | ||
+ | load callReg , #DrawTiledClockMessage | ||
+ | load clearReg , #ClearTiledClockMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$02 | ||
+ | load callReg , #DrawSpriteAudioMessage | ||
+ | load clearReg , #ClearSpriteAudioMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$04 | ||
+ | load callReg , #DrawBaseColorMessage | ||
+ | load clearReg , #ClearBaseColorMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$08 | ||
+ | load callReg , #DrawBouncingSpritesMessage | ||
+ | load clearReg , #ClearBouncingSpritesMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$10 | ||
+ | load callReg , #DrawAttributeTableMessage | ||
+ | load clearReg , #ClearAttributeTableMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$20 | ||
+ | load callReg , #DrawSpritePriorityMessage | ||
+ | load clearReg , #ClearSpritePriorityMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$40 | ||
+ | load callReg , #DrawPaletteChangeMessage | ||
+ | load clearReg , #ClearPaletteChangeMessage | ||
+ | call DoFunction | ||
+ | load swReg , #$80 | ||
+ | load callReg , #DrawSpriteMirroringMessage | ||
+ | load clearReg , #ClearSpriteMirroringMessage | ||
+ | call DoFunction | ||
+ | ret | ||
+ | | ||
+ | DrawDemoMessage: | ||
+ | load mIndexReg , #$15 | ||
+ | load startReg , #$A1F5 | ||
+ | load stopReg , #$A1DF | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearDemoMessage: | ||
+ | load startReg , #$A1F5 | ||
+ | load stopReg , #$A1DF | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawTiledClockMessage: | ||
+ | load mIndexReg, #$20 | ||
+ | load startReg , #$A20A | ||
+ | load stopReg , #$A1FF | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | |||
+ | ClearTiledClockMessage: | ||
+ | load startReg , #$A20A | ||
+ | load stopReg , #$A1FF | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | |||
+ | DrawSpriteAudioMessage: | ||
+ | load mIndexReg, #$2C | ||
+ | load startReg , #$A21B | ||
+ | load stopReg , #$A20F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearSpriteAudioMessage: | ||
+ | load startReg , #$A21B | ||
+ | load stopReg , #$A20F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawBaseColorMessage: | ||
+ | load mIndexReg, #$36 | ||
+ | load startReg , #$A229 | ||
+ | load stopReg , #$A21F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearBaseColorMessage: | ||
+ | load startReg , #$A229 | ||
+ | load stopReg , #$A21F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawBouncingSpritesMessage: | ||
+ | load mIndexReg, #$46 | ||
+ | load startReg , #$A23F | ||
+ | load stopReg , #$A22F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearBouncingSpritesMessage: | ||
+ | load startReg , #$A23F | ||
+ | load stopReg , #$A22F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawAttributeTableMessage: | ||
+ | load mIndexReg, #$55 | ||
+ | load startReg , #$A24E | ||
+ | load stopReg , #$A23F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearAttributeTableMessage: | ||
+ | load startReg , #$A24E | ||
+ | load stopReg , #$A23F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawSpritePriorityMessage: | ||
+ | load mIndexReg, #$64 | ||
+ | load startReg , #$A25E | ||
+ | load stopReg , #$A24F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearSpritePriorityMessage: | ||
+ | load startReg , #$A25E | ||
+ | load stopReg , #$A24F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawPaletteChangeMessage: | ||
+ | load mIndexReg, #$72 | ||
+ | load startReg , #$A26D | ||
+ | load stopReg , #$A25F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearPaletteChangeMessage: | ||
+ | load startReg , #$A26D | ||
+ | load stopReg , #$A25F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawSpriteMirroringMessage: | ||
+ | load mIndexReg, #$82 | ||
+ | load startReg , #$A27F | ||
+ | load stopReg , #$A26F | ||
+ | call DrawMessage | ||
+ | ret | ||
+ | | ||
+ | ClearSpriteMirroringMessage: | ||
+ | load startReg , #$A27F | ||
+ | load stopReg , #$A26F | ||
+ | call ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DrawMessage: | ||
+ | out mIndexReg, MESSAGETBL | ||
+ | in tempReg0 , ROMDATA | ||
+ | out tempReg0 , startReg | ||
+ | sub startReg , #1 | ||
+ | sub mIndexReg, #1 | ||
+ | comp startReg , stopReg | ||
+ | jpnz DrawMessage | ||
+ | ret | ||
+ | |||
+ | ClearMessage: | ||
+ | load mIndexReg, #$FF | ||
+ | out mIndexReg, startReg | ||
+ | sub startReg , #1 | ||
+ | comp startReg , stopReg | ||
+ | jpnz ClearMessage | ||
+ | ret | ||
+ | | ||
+ | DoBaseColor: | ||
+ | in switchReg , SWITCHES | ||
+ | and switchReg , #$04 | ||
+ | comp switchReg , #$04 | ||
+ | clz UpdateBaseColor | ||
+ | comp switchReg , #$04 | ||
+ | clnz ClearBaseColor | ||
+ | ret | ||
+ | | ||
+ | UpdateBaseColor: | ||
+ | add bcDelReg , #1 | ||
+ | comp bcDelReg , #$20 | ||
+ | clz IncrementBaseColor | ||
+ | out bcReg , #$A700 | ||
+ | ret | ||
+ | |||
+ | IncrementBaseColor: | ||
+ | add bcReg , #1 | ||
+ | load bcDelReg , #0 | ||
+ | ret | ||
+ | | ||
+ | ClearBaseColor: | ||
+ | load bcReg , #0 | ||
+ | out bcReg , #$A700 | ||
+ | load bcDelReg , #0 | ||
+ | ret | ||
+ | |||
+ | DoBouncingSprites: | ||
+ | load swReg , #$08 | ||
+ | load callReg , #UpdateBouncingSprites | ||
+ | load clearReg , #ClearBouncingSprites | ||
+ | call DoFunction | ||
+ | call DrawBouncingSprites | ||
+ | ret | ||
+ | |||
+ | UpdateBouncingSprites: | ||
+ | call CheckBouncingSpritesStart | ||
+ | load tempReg0 , #$20 | ||
+ | UpdateBouncingSpritesLoop: | ||
+ | load tempReg3 , (tempReg0) | ||
+ | comp tempReg3 , UPLEFT | ||
+ | clz MoveUpLeft | ||
+ | comp tempReg3 , UPRIGHT | ||
+ | clz MoveUpRight | ||
+ | comp tempReg3 , DOWNLEFT | ||
+ | clz MoveDownLeft | ||
+ | comp tempReg3 , DOWNRIGHT | ||
+ | clz MoveDownRight | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$28 | ||
+ | jpnz UpdateBouncingSpritesLoop | ||
+ | ret | ||
+ | |||
+ | MoveUpRight: | ||
+ | call CheckYMin | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToDownRight | ||
+ | call CheckXMax | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToUpLeft | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | add tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | sub tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | ret | ||
+ | | ||
+ | MoveUpLeft: | ||
+ | call CheckYMin | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToDownLeft | ||
+ | call CheckXMin | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToUpRight | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | sub tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | sub tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | ret | ||
+ | | ||
+ | MoveDownRight: | ||
+ | call CheckYMax | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToUpRight | ||
+ | call CheckXMax | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToDownLeft | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | add tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | add tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | ret | ||
+ | | ||
+ | MoveDownLeft: | ||
+ | call CheckXMin | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToDownRight | ||
+ | call CheckYMax | ||
+ | comp checkReg , #1 | ||
+ | jpz ChangeToUpLeft | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | sub tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | add tempReg2 , #1 | ||
+ | stor tempReg2 , (tempReg1) | ||
+ | ret | ||
+ | | ||
+ | CheckYMin: | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #16 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | comp tempReg2 , #0 | ||
+ | jpz ExtentReached | ||
+ | load checkReg , #0 | ||
+ | ret | ||
+ | | ||
+ | CheckYMax: | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #16 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | comp tempReg2 , #231 | ||
+ | jpz ExtentReached | ||
+ | load checkReg , #0 | ||
+ | ret | ||
+ | | ||
+ | CheckXMin: | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | comp tempReg2 , #0 | ||
+ | jpz ExtentReached | ||
+ | load checkReg , #0 | ||
+ | ret | ||
+ | | ||
+ | CheckXMax: | ||
+ | load tempReg1 , tempReg0 | ||
+ | sub tempReg1 , #8 | ||
+ | load tempReg2 , (tempReg1) | ||
+ | comp tempReg2 , #247 | ||
+ | jpz ExtentReached | ||
+ | load checkReg , #0 | ||
+ | ret | ||
+ | | ||
+ | ExtentReached: | ||
+ | load checkReg , #1 | ||
+ | ret | ||
+ | |||
+ | ChangeToDownRight: | ||
+ | load tempReg1 , DOWNRIGHT | ||
+ | stor tempReg1 , (tempReg0) | ||
+ | ret | ||
+ | | ||
+ | ChangeToDownLeft: | ||
+ | load tempReg1 , DOWNLEFT | ||
+ | stor tempReg1 , (tempReg0) | ||
+ | ret | ||
+ | | ||
+ | ChangeToUpRight: | ||
+ | load tempReg1 , UPRIGHT | ||
+ | stor tempReg1 , (tempReg0) | ||
+ | ret | ||
+ | | ||
+ | ChangeToUpLeft: | ||
+ | load tempReg1 , UPLEFT | ||
+ | stor tempReg1 , (tempReg0) | ||
+ | ret | ||
+ | | ||
+ | ClearBouncingSprites: | ||
+ | load tempReg0 , #$0F | ||
+ | load tempReg1 , #$FF | ||
+ | YClearLoop: | ||
+ | add tempReg0 , #1 | ||
+ | stor tempReg1 , (tempReg0) | ||
+ | comp tempReg0 , #$17 | ||
+ | jpnz YClearLoop | ||
+ | ret | ||
+ | | ||
+ | CheckBouncingSpritesStart: | ||
+ | comp sp0y , #$FF | ||
+ | rtnz | ||
+ | load sp0y , #11 | ||
+ | load sp1y , #22 | ||
+ | load sp2y , #33 | ||
+ | load sp3y , #44 | ||
+ | load sp4y , #55 | ||
+ | load sp5y , #66 | ||
+ | load sp6y , #77 | ||
+ | load sp7y , #88 | ||
+ | load sp0x , #11 | ||
+ | load sp1x , #22 | ||
+ | load sp2x , #33 | ||
+ | load sp3x , #44 | ||
+ | load sp4x , #55 | ||
+ | load sp5x , #66 | ||
+ | load sp6x , #77 | ||
+ | load sp7x , #88 | ||
+ | load sp0m , DOWNRIGHT | ||
+ | load sp1m , DOWNRIGHT | ||
+ | load sp2m , DOWNRIGHT | ||
+ | load sp3m , DOWNRIGHT | ||
+ | load sp4m , DOWNRIGHT | ||
+ | load sp5m , DOWNRIGHT | ||
+ | load sp6m , DOWNRIGHT | ||
+ | load sp7m , DOWNRIGHT | ||
+ | ret | ||
+ | | ||
+ | DrawBouncingSprites: | ||
+ | load tempReg0 , #$10 | ||
+ | load tempReg1 , #$B000 | ||
+ | FillYLoop: | ||
+ | load tempReg2 , (tempReg0) | ||
+ | out tempReg2 , tempReg1 | ||
+ | add tempReg0 , #1 | ||
+ | add tempReg1 , #4 | ||
+ | comp tempReg0 , #$18 | ||
+ | jpnz FillYLoop | ||
+ | | ||
+ | load tempReg0 , #$18 | ||
+ | load tempReg1 , #$B003 | ||
+ | FillXLoop: | ||
+ | load tempReg2 , (tempReg0) | ||
+ | out tempReg2 , tempReg1 | ||
+ | add tempReg0 , #1 | ||
+ | add tempReg1 , #4 | ||
+ | comp tempReg0 , #$20 | ||
+ | jpnz FillXLoop | ||
+ | | ||
+ | load tempReg0 , #$20 | ||
+ | load tempReg1 , #$B002 | ||
+ | FillMLoop: | ||
+ | load tempReg2 , (tempReg0) | ||
+ | out tempReg2 , tempReg1 | ||
+ | add tempReg0 , #1 | ||
+ | add tempReg1 , #4 | ||
+ | comp tempReg0 , #$28 | ||
+ | jpnz FillMLoop | ||
+ | | ||
+ | load tempReg0 , #$04 | ||
+ | load tempReg1 , #$B001 | ||
+ | FillPatternLoop: | ||
+ | out tempReg0 , tempReg1 | ||
+ | add tempReg1 , #4 | ||
+ | comp tempReg1 , #$B021 | ||
+ | jpnz FillPatternLoop | ||
+ | ret | ||
+ | | ||
+ | DoPaletteChange: | ||
+ | load swReg , #$40 | ||
+ | load callReg , #ChangePalettes | ||
+ | load clearReg , #SetDefaultPalettes | ||
+ | jump DoFunction | ||
+ | | ||
+ | ChangePalettes: | ||
+ | add palDelReg, #1 | ||
+ | comp palDelReg, #$10 | ||
+ | rtnz | ||
+ | load palDelReg, #0 | ||
+ | load tempReg0 , #$A600 | ||
+ | load tempReg2 , PALREGS | ||
+ | ChangePalettesLoop: | ||
+ | comp tempReg2 , #$30 | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$34 | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$38 | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$3C | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$40 | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$44 | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$48 | ||
+ | jpz NextPalette | ||
+ | comp tempReg2 , #$4C | ||
+ | jpz NextPalette | ||
+ | load tempReg1 , (tempReg2) | ||
+ | add tempReg1 , #1 | ||
+ | stor tempReg1 , (tempReg2) | ||
+ | out tempReg1 , tempReg0 | ||
+ | NextPalette: | ||
+ | add tempReg0 , #1 | ||
+ | add tempReg2 , #1 | ||
+ | comp tempReg0 , #$A620 | ||
+ | jpnz ChangePalettesLoop | ||
+ | ret | ||
+ | | ||
+ | SetDefaultPalettes: | ||
+ | load tempReg0 , #$A600 | ||
+ | load tempReg3 , PALREGS | ||
+ | load tempReg1 , #0 | ||
+ | SetDefaultPalettesLoop: | ||
+ | out tempReg1 , PALETTETBL | ||
+ | in tempReg2 , ROMDATA | ||
+ | out tempReg2 , tempReg0 | ||
+ | stor tempReg2 , (tempReg3) | ||
+ | add tempReg1 , #1 | ||
+ | add tempReg0 , #1 | ||
+ | add tempReg3 , #1 | ||
+ | comp tempReg0 , #$A620 | ||
+ | jpnz SetDefaultPalettesLoop | ||
+ | ret | ||
+ | | ||
+ | ;------------------------------------Sprite Mirroring Routines------------------------------------- | ||
+ | DoSpriteMirroring: | ||
+ | load swReg , #$80 ;Switch 8 controls the sprite mirroring. | ||
+ | load callReg , #SpriteMirror ;Mirroring entry function. | ||
+ | load clearReg , #ClearSpriteMirror ;Clear mirroring sprites. | ||
+ | jump DoFunction ; | ||
+ | | ||
+ | SpriteMirror: | ||
+ | add mirDelReg, #1 ; | ||
+ | comp mirDelReg, #$04 ;Update mirroring sprites every 4th frame. | ||
+ | rtnz ; | ||
+ | | ||
+ | load tempReg0 , #$B020 ;Set address to PPU mirroring sprite RAM. | ||
+ | | ||
+ | SpriteLoadLoop: | ||
+ | out mirPtrReg, SPRITETBL | ||
+ | in tempReg1 , ROMDATA | ||
+ | out tempReg1 , tempReg0 | ||
+ | add mirPtrReg, #1 | ||
+ | add tempReg0 , #1 | ||
+ | and mirPtrReg, #$FF | ||
+ | comp mirPtrReg, #$40 | ||
+ | jpz FinishSpriteLoadLoop | ||
+ | comp mirPtrReg, #$80 | ||
+ | jpz FinishSpriteLoadLoop | ||
+ | comp mirPtrReg, #$C0 | ||
+ | jpz FinishSpriteLoadLoop | ||
+ | comp mirPtrReg, #$00 | ||
+ | jpz FinishSpriteLoadLoop | ||
+ | jump SpriteLoadLoop | ||
+ | FinishSpriteLoadLoop: | ||
+ | load mirDelReg, #0 | ||
+ | ret | ||
+ | | ||
+ | ClearSpriteMirror: | ||
+ | load tempReg0 , #$B020 | ||
+ | load tempReg1 , #$FF | ||
+ | ClearSpriteMirrorLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$B060 | ||
+ | jpnz ClearSpriteMirrorLoop | ||
+ | load mirDelReg, #0 | ||
+ | load mirPtrReg, #0 | ||
+ | ret | ||
+ | |||
+ | ;--------------------------------------Audio Sprite Routines--------------------------------------- | ||
+ | DoSpriteAudio: | ||
+ | load swReg , #$02 ;2nd switch controls audio sprites. | ||
+ | load callReg , #SpriteAudio ;Audio sprite entry function. | ||
+ | load clearReg , #ClearSpriteAudio ;Clear audio sprites function. | ||
+ | jump DoFunction ; | ||
+ | |||
+ | SpriteAudio: | ||
+ | load tempReg0 , #$A000 | ||
+ | load tempReg1 , #$78 | ||
+ | AudioBackgroundTopLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A020 | ||
+ | jpnz AudioBackgroundTopLoop | ||
+ | load tempReg1 , #$79 | ||
+ | AudioBackgroundMidLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A1A0 | ||
+ | jpnz AudioBackgroundMidLoop | ||
+ | load tempReg1 , #$7A | ||
+ | AudioBackgroundBotLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A1C0 | ||
+ | jpnz AudioBackgroundBotLoop | ||
+ | call DisplayAudioSprites ;Draw audio sprites on the display. | ||
+ | call DisplayMag ;Draw magnification factor on display. | ||
+ | ret ; | ||
+ | | ||
+ | ClearSpriteAudio: | ||
+ | load tempReg1 , #$FF ;Blank sprite. | ||
+ | load tempReg0 , #$A000 ; | ||
+ | | ||
+ | ClearSpriteAudioLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A1C0 | ||
+ | jpnz ClearSpriteAudioLoop | ||
+ | | ||
+ | out tempReg1 , tempReg0 ; | ||
+ | add tempReg0 , #1 ;Clear magnification factor from display. | ||
+ | out tempReg1 , tempReg0 ; | ||
+ | add tempReg0 , #1 ; | ||
+ | out tempReg1 , tempReg0 ; | ||
+ | | ||
+ | load tempReg0 , PPUAUDSPSTART ;Base address in PPU sprite RAM. | ||
+ | load tempReg1 , #$FF ;Move sprite off screen. | ||
+ | | ||
+ | RemoveAudioSprites: | ||
+ | out tempReg1 , tempReg0 ; | ||
+ | add tempReg0 , #1 ;Loop to write #$FF into all--> | ||
+ | comp tempReg0 , PPUAUDSPEND ;audio sprite RAM. This will--> | ||
+ | jpnz RemoveAudioSprites ;move the sprites off screen. | ||
+ | ret ; | ||
+ | | ||
+ | DisplayAudioSprites: | ||
+ | load tempReg0 , PPUAUDSPSTART ;Base address in PPU sprite RAM. | ||
+ | load tempReg1 , #0 ;Sprite X location. | ||
+ | load tempReg2 , SPRITEREGS ;Base address in CPU audio sprite RAM. | ||
+ | load tempReg3 , #$A0 ;Audio sprite pattern table address. | ||
+ | | ||
+ | DisplayAudioSpritesLoop: | ||
+ | load miscReg , (tempReg2) ;Get sprite audio data from CPU memory. | ||
+ | xor miscReg , #$007F ;Compute proper positon on display. | ||
+ | sub miscReg , #$10 ; | ||
+ | out miscReg , tempReg0 ;Set sprite Y position in PPU RAM. | ||
+ | | ||
+ | add tempReg0 , #1 ;Set sprite pattern in PPU RAM. | ||
+ | out tempReg3 , tempReg0 ; | ||
+ | | ||
+ | add tempReg0 , #1 ;Set property bit in PPU RAM. | ||
+ | load miscReg , #2 ;No flipping, foreground sprite,--> | ||
+ | out miscReg , tempReg0 ;pallette %$10. | ||
+ | | ||
+ | add tempReg0 , #1 ;Store sprite X position in PPU RAM. | ||
+ | out tempReg1 , tempReg0 ; | ||
+ | | ||
+ | add tempReg2 , #1 ;Move to next sprite in CPU memory. | ||
+ | add tempReg1 , #2 ;Move x by 2 pixels for next sprite. | ||
+ | add tempReg0 , #1 ;Move to next sprite in PPU RAM. | ||
+ | | ||
+ | comp tempReg0 , PPUAUDSPEND ;Check if more sprites to process(128 total). | ||
+ | jpnz DisplayAudioSpritesLoop ;Loop if more sprites to process. | ||
+ | ret ; | ||
+ | | ||
+ | DisplayMag: | ||
+ | comp micSmpReg, #$0200 | ||
+ | jpnz Check02X | ||
+ | load tempReg1 , #$78 | ||
+ | load tempReg2 , #$01 | ||
+ | load tempReg3 , #$21 | ||
+ | | ||
+ | Check02X: | ||
+ | comp micSmpReg, #$0100 | ||
+ | jpnz Check04X | ||
+ | load tempReg1 , #$78 | ||
+ | load tempReg2 , #$02 | ||
+ | load tempReg3 , #$21 | ||
+ | | ||
+ | Check04X: | ||
+ | comp micSmpReg, #$0080 | ||
+ | jpnz Check08X | ||
+ | load tempReg1 , #$78 | ||
+ | load tempReg2 , #$04 | ||
+ | load tempReg3 , #$21 | ||
+ | | ||
+ | Check08X: | ||
+ | comp micSmpReg, #$0040 | ||
+ | jpnz Check16X | ||
+ | load tempReg1 , #$78 | ||
+ | load tempReg2 , #$08 | ||
+ | load tempReg3 , #$21 | ||
+ | | ||
+ | Check16X: | ||
+ | comp micSmpReg, #$0020 | ||
+ | jpnz Check32X | ||
+ | load tempReg1 , #$01 | ||
+ | load tempReg2 , #$06 | ||
+ | load tempReg3 , #$21 | ||
+ | | ||
+ | Check32X: | ||
+ | comp micSmpReg, #$0010 | ||
+ | jpnz LoadMag | ||
+ | load tempReg1 , #$03 | ||
+ | load tempReg2 , #$02 | ||
+ | load tempReg3 , #$21 | ||
+ | | ||
+ | LoadMag: | ||
+ | load tempReg0 , #$A000 | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | out tempReg2 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | out tempReg3 , tempReg0 | ||
+ | ret | ||
+ | | ||
+ | GetAudioData: | ||
+ | load micDelReg, #0 ;Zero the mic delay register. | ||
+ | load audPtrReg, SPRITEREGS ;Get base address of audio sprites RAM. | ||
+ | | ||
+ | in audHldReg, MICDATA ;Get audio input data. | ||
+ | asl audHldReg ;Check if mag button depressed. | ||
+ | clc MagChangeButtonPushed ;If so, change magnification. | ||
+ | | ||
+ | in audHldReg, MICDATA | ||
+ | asl audHldReg | ||
+ | clnc MagChangeButtonReleased | ||
+ | | ||
+ | GetAudioLoop: | ||
+ | add audCtrReg, #1 ;Delay to for specified sampling time. | ||
+ | comp audCtrReg, micSmpReg ;Check if tie for another sample. | ||
+ | jpnz GetAudioLoop | ||
+ | load audCtrReg, #0 | ||
+ | | ||
+ | in audHldReg, MICDATA ;Get audio data from port. | ||
+ | and audHldReg, #$0FFF ;Keep only audio data bits. | ||
+ | lsr audHldReg ; | ||
+ | lsr audHldReg ;Keep only upper 7 bits. | ||
+ | lsr audHldReg ; | ||
+ | lsr audHldReg ; | ||
+ | lsr audHldReg ; | ||
+ | | ||
+ | sub audHldReg, #8 | ||
+ | stor audHldReg, (audPtrReg) | ||
+ | add audPtrReg, #1 | ||
+ | comp audPtrReg, ENDAUDIOREGS | ||
+ | jpnz GetAudioLoop | ||
+ | load audPtrReg, #0 | ||
+ | ret | ||
+ | | ||
+ | MagChangeButtonReleased: | ||
+ | load micStaReg, #0 | ||
+ | ret | ||
+ | | ||
+ | MagChangeButtonPushed: | ||
+ | rol micStaReg | ||
+ | jpc DebounceDone | ||
+ | load micStaReg, #$8000 | ||
+ | ret | ||
+ | | ||
+ | DebounceDone: | ||
+ | ror micStaReg | ||
+ | ror micStaReg | ||
+ | clnc ChangeMag | ||
+ | load micStaReg, #$8001 | ||
+ | ret | ||
+ | | ||
+ | ChangeMag: | ||
+ | comp micSmpReg, #$0200 ;If at 1x magnification, --> | ||
+ | jpz ChangeTo2X ;change to 2x magnification. | ||
+ | | ||
+ | comp micSmpReg, #$0100 ;If at 2x magnification, --> | ||
+ | jpz ChangeTo4X ;change to 4x magnification. | ||
+ | | ||
+ | comp micSmpReg, #$0080 ;If at 4x magnification, --> | ||
+ | jpz ChangeTo8X ;change to 8x magnification. | ||
+ | | ||
+ | comp micSmpReg, #$0040 ;If at 8x magnification, --> | ||
+ | jpz ChangeTo16X ;change to 16x magnification. | ||
+ | | ||
+ | comp micSmpReg, #$0020 ;If at 16x magnification, --> | ||
+ | jpz ChangeTo32X ;change to 32x magnification. | ||
+ | | ||
+ | comp micSmpReg, #$0010 ;If at 32x magnification, --> | ||
+ | jump ChangeTo1X ;change to 1x magnification. | ||
+ | |||
+ | ChangeTo1X: | ||
+ | load micSmpReg, #$0200 ;Change to 1x magnification. | ||
+ | ret ; | ||
+ | ChangeTo2X: | ||
+ | load micSmpReg, #$0100 ;Change to 2x magnification. | ||
+ | ret ; | ||
+ | ChangeTo4X: | ||
+ | load micSmpReg, #$0080 ;Change to 4x magnification. | ||
+ | ret ; | ||
+ | ChangeTo8X: | ||
+ | load micSmpReg, #$0040 ;Change to 8x magnification. | ||
+ | ret ; | ||
+ | ChangeTo16X: | ||
+ | load micSmpReg, #$0020 ;Change to 16x magnification. | ||
+ | ret ; | ||
+ | ChangeTo32X: | ||
+ | load micSmpReg, #$0010 ;Change to 32x magnification. | ||
+ | ret ; | ||
+ | ;-------------------------------------------------------------------------------------------------- | ||
+ | | ||
+ | DoAttribChange: | ||
+ | load swReg , #$10 | ||
+ | load callReg , #AttributeTable | ||
+ | load clearReg , #ClearAttributeTable | ||
+ | jump DoFunction | ||
+ | |||
+ | AttributeTable: | ||
+ | add atDelReg , #1 | ||
+ | comp atDelReg , #8 | ||
+ | rtnz | ||
+ | load atDelReg , #0 | ||
+ | add atStatReg, #1 | ||
+ | comp atStatReg, #4 | ||
+ | clz ResetAttributeReg | ||
+ | load tempReg0 , #$A580 | ||
+ | SetAttributeTableLoop: | ||
+ | comp atStatReg, #0 | ||
+ | jpnz NextCheck1 | ||
+ | load tempReg1 , AT0 | ||
+ | NextCheck1: | ||
+ | comp atStatReg, #1 | ||
+ | jpnz NextCheck2 | ||
+ | load tempReg1 , AT1 | ||
+ | NextCheck2: | ||
+ | comp atStatReg, #2 | ||
+ | jpnz NextCheck3 | ||
+ | load tempReg1 , AT2 | ||
+ | NextCheck3: | ||
+ | comp atStatReg, #3 | ||
+ | jpnz FinishCheck | ||
+ | load tempReg1 , AT3 | ||
+ | FinishCheck: | ||
+ | out tempReg1, tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A5A0 | ||
+ | jpnz SetAttributeTableLoop | ||
+ | ret | ||
+ | | ||
+ | ResetAttributeReg: | ||
+ | load atStatReg, #0 | ||
+ | ret | ||
+ | | ||
+ | ClearAttributeTable: | ||
+ | load tempReg0 , #$A580 | ||
+ | load tempReg1 , #0 | ||
+ | ClearAttributeTableLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A5A0 | ||
+ | jpnz ClearAttributeTableLoop | ||
+ | ret | ||
+ | | ||
+ | DoSpritePriority: | ||
+ | load swReg , #$20 | ||
+ | load callReg , #UpdateSpritePriority | ||
+ | load clearReg , #ClearSpritePriority | ||
+ | jump DoFunction | ||
+ | | ||
+ | ;anDelReg, samROMReg, samXReg, movDelReg | ||
+ | ;samM0Reg, samM1Reg, samM2Reg | ||
+ | | ||
+ | UpdateSpritePriority: | ||
+ | load tempReg0 , #$A33F | ||
+ | load tempReg1 , #$7C | ||
+ | DrawPillarsLoop: | ||
+ | add tempReg0 , #3 | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | out tempReg1 , tempReg0 | ||
+ | comp tempReg0 , #$A3BF | ||
+ | jpnz DrawPillarsLoop | ||
+ | | ||
+ | add anDelReg , #1 | ||
+ | add movDelReg , #1 | ||
+ | | ||
+ | call CheckSamusMovement | ||
+ | call CheckSamusAnimation | ||
+ | | ||
+ | DrawSamus: | ||
+ | load tempReg0 , #$B0D0 | ||
+ | load tempReg1 , samROMReg | ||
+ | | ||
+ | GetSamusROMLoop: | ||
+ | out tempReg1 , PALETTETBL | ||
+ | in tempReg2 , ROMDATA | ||
+ | out tempReg2 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | add tempReg1 , #1 | ||
+ | out tempReg1 , PALETTETBL | ||
+ | in tempReg2 , ROMDATA | ||
+ | out tempReg2 , tempReg0 | ||
+ | add tempReg0 , #3 | ||
+ | add tempReg1 , #1 | ||
+ | comp tempReg0 , #$B100 | ||
+ | jpnz GetSamusROMLoop | ||
+ | | ||
+ | load tempReg0 , samXReg | ||
+ | | ||
+ | LoadSamusMX: | ||
+ | out samM0Reg , #$B0D2 | ||
+ | out tempReg0 , #$B0D3 | ||
+ | out samM0Reg , #$B0DA | ||
+ | out tempReg0 , #$B0DB | ||
+ | out samM0Reg , #$B0E2 | ||
+ | out tempReg0 , #$B0E3 | ||
+ | out samM0Reg , #$B0EE | ||
+ | out tempReg0 , #$B0EF | ||
+ | | ||
+ | add tempReg0 , #8 | ||
+ | | ||
+ | out samM1Reg , #$B0D6 | ||
+ | out tempReg0 , #$B0D7 | ||
+ | out samM1Reg , #$B0DE | ||
+ | out tempReg0 , #$B0DF | ||
+ | out samM1Reg , #$B0E6 | ||
+ | out tempReg0 , #$B0E7 | ||
+ | out samM1Reg , #$B0F2 | ||
+ | out tempReg0 , #$B0F3 | ||
+ | | ||
+ | add tempReg0 , #8 | ||
+ | | ||
+ | out samM2Reg , #$B0EA | ||
+ | out tempReg0 , #$B0EB | ||
+ | out samM2Reg , #$B0F6 | ||
+ | out tempReg0 , #$B0F7 | ||
+ | | ||
+ | ret | ||
+ | | ||
+ | CheckSamusMovement: | ||
+ | comp movDelReg, #2 | ||
+ | jpz UpdateSamusPosition | ||
+ | ret | ||
+ | | ||
+ | CheckSamusAnimation: | ||
+ | comp anDelReg , #8 | ||
+ | jpz UpdateSamusAnimation | ||
+ | ret | ||
+ | | ||
+ | UpdateSamusAnimation: | ||
+ | add samROMReg, #$18 | ||
+ | comp samROMReg, #$A0 | ||
+ | clz ResetSamusROMReg | ||
+ | load anDelReg , #0 | ||
+ | ret | ||
+ | | ||
+ | ResetSamusROMReg: | ||
+ | load samROMReg, #$40 | ||
+ | ret | ||
+ | | ||
+ | UpdateSamusPosition: | ||
+ | load movDelReg, #0 | ||
+ | sub samXReg , #1 | ||
+ | and samXReg , #$FF | ||
+ | | ||
+ | load tempReg0 , samXReg | ||
+ | | ||
+ | comp tempReg0 , #$20 | ||
+ | clz SwitchM0Priority | ||
+ | comp tempReg0 , #$40 | ||
+ | clz SwitchM0Priority | ||
+ | comp tempReg0 , #$60 | ||
+ | clz SwitchM0Priority | ||
+ | comp tempReg0 , #$80 | ||
+ | clz SwitchM0Priority | ||
+ | comp tempReg0 , #$A0 | ||
+ | clz SwitchM0Priority | ||
+ | comp tempReg0 , #$C0 | ||
+ | clz SwitchM0Priority | ||
+ | comp tempReg0 , #$E0 | ||
+ | clz SwitchM0Priority | ||
+ | | ||
+ | add tempReg0 , #8 | ||
+ | | ||
+ | comp tempReg0 , #$20 | ||
+ | clz SwitchM1Priority | ||
+ | comp tempReg0 , #$40 | ||
+ | clz SwitchM1Priority | ||
+ | comp tempReg0 , #$60 | ||
+ | clz SwitchM1Priority | ||
+ | comp tempReg0 , #$80 | ||
+ | clz SwitchM1Priority | ||
+ | comp tempReg0 , #$A0 | ||
+ | clz SwitchM1Priority | ||
+ | comp tempReg0 , #$C0 | ||
+ | clz SwitchM1Priority | ||
+ | comp tempReg0 , #$E0 | ||
+ | clz SwitchM1Priority | ||
+ | | ||
+ | add tempReg0 , #8 | ||
+ | | ||
+ | comp tempReg0 , #$20 | ||
+ | clz SwitchM2Priority | ||
+ | comp tempReg0 , #$40 | ||
+ | clz SwitchM2Priority | ||
+ | comp tempReg0 , #$60 | ||
+ | clz SwitchM2Priority | ||
+ | comp tempReg0 , #$80 | ||
+ | clz SwitchM2Priority | ||
+ | comp tempReg0 , #$A0 | ||
+ | clz SwitchM2Priority | ||
+ | comp tempReg0 , #$C0 | ||
+ | clz SwitchM2Priority | ||
+ | comp tempReg0 , #$E0 | ||
+ | clz SwitchM2Priority | ||
+ | | ||
+ | ret | ||
+ | | ||
+ | SwitchM0Priority: | ||
+ | xor samM0Reg , #$20 | ||
+ | ret | ||
+ | | ||
+ | SwitchM1Priority: | ||
+ | xor samM1Reg , #$20 | ||
+ | ret | ||
+ | | ||
+ | SwitchM2Priority: | ||
+ | xor samM2Reg , #$20 | ||
+ | ret | ||
+ | | ||
+ | ClearSpritePriority: | ||
+ | load tempReg0 , #$A320 | ||
+ | load tempReg1 , #$FF | ||
+ | ClearPillarsLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$A3C0 | ||
+ | jpnz ClearPillarsLoop | ||
+ | load tempReg0 , #$B0D0 | ||
+ | ClearWalkingSpritesLoop: | ||
+ | out tempReg1 , tempReg0 | ||
+ | add tempReg0 , #1 | ||
+ | comp tempReg0 , #$B100 | ||
+ | jpnz ClearWalkingSpritesLoop | ||
+ | load samROMReg, #$40 | ||
+ | load samXReg , #$E5 | ||
+ | load samM0Reg , #$03 | ||
+ | load samM1Reg , #$03 | ||
+ | load samM2Reg , #$03 | ||
+ | ret | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### NMPSM3.jar (Download) | ||
+ | [[https://www.nicholasmikstas.com/s/NMPSM3.jar|NMPSM3.jar (Download)]] | ||
+ | \\ | ||
+ | |||
+ | \\ | ||
+ | ##### NMPSM3.bat | ||
+ | <code verilog> | ||
+ | |||
+ | java -jar NMPSM3.jar program.asm | ||
+ | @echo off | ||
+ | pause | ||
+ | |||
+ | </code> | ||
+ | \\ | ||
+ | |||
+ | ##### program.coe | ||
+ | <code verilog> | ||
+ | |||
+ | memory_initialization_radix = 16; | ||
+ | memory_initialization_vector = | ||
+ | 100000005,100000028,100000038,100000052,100000052,230000022,2300001FE,230000262, | ||
+ | 230000035,230000050,010950080,0106D0040,0106E00E5,010900003,010910003,010920003, | ||
+ | 010590011,010500005,530500010,530500011,0118000D9,531800200,A60000000,A90000000, | ||
+ | AC0000000,8C0040001,190000019,B90000000,010040001,6C0930001,8C0930003,2C00002F4, | ||
+ | AC0000000,100000019,0100003FF,010010000,0D0010000,790000001,160000024,3.6, | ||
+ | 530010001,4C0500012,600500000,2C0000035,530010001,4C0500012,530500010,5.3亿, | ||
+ | 4C0500012, 530500020、6C0010001、6C0000001、460460、010000000、010010000、360000000, | ||
+ | 8C0020020,2C0000050,040500002,010520024,23000004A,6C0500001,010520025,23000004A, | ||
+ | 6C0500001,010520026,23000004A,6C0500001,010520027,23000004A,0105000B0,530500011, | ||
+ | 6C0020001,4.6亿,530500002,4C0510012,530510003,4C0510012,560510052,3.6亿, | ||
+ | 010020000, 3.6亿,010040000,2300000E8,230000073,23000016C,23000017F,23000023F, | ||
+ | 23000026F,230000291,230000331,230000357,230000067,4.6亿,4C0030013,5C003006B, | ||
+ | 90003006B,190000063,100000064,130690000,1306A0000,4C0030013,100000060,23000006A, | ||
+ | 230000071,3.6亿, 4C1810003、8C1810000、3C0000000、531810021、531810201、531810204、10000006A, | ||
+ | 530500202、360000000、0106B0001、010690077、0106A00E4、10000005E,4C0500033, | ||
+ | 600500000,29000009D,600500000,2C00000A3,4C0500032,5905000F0,2900000A9,5905000F0, | ||
+ | 2C00000B5,4C0500030,2300000BD,01057A29B,2300000C2,4C0500030,5905000F0,01057A296, | ||
+ | 2300000C2,4C0500031,2300000BD,01057A28F,2300000C2,4C0500031,5905000F0,01057A28A, | ||
+ | 2300000C2, 4C0500032,2300000BD,01057A283,2300000C2,2300000D1,040500058,8C0500000, | ||
+ | 2C00000DA,040500058,8C0500000,2900000DF,3.6亿,01050006F,53050A288,53050A294, | ||
+ | 53050A2E8,53050A2F4,3.6亿,0105000FF,53050A288,53050A294,53050A2E8,53050A2F4, | ||
+ | 3.6亿,010500044, 53050A280,01050004D, | ||
+ | 53050A281,010500050,53050A2A0,010500047,53050A2A1,53050A2C1,010500055,53050A2E1,360000000,0105000FF,53050A280,53050A281, | ||
+ | 53050A2A0,53050A2A1,53050A2C1,53050A2E1,3.6亿,930500000,930500000,930500000, | ||
+ | 930500000,3.6亿,010540004,010550004,530500004,4C0560012,560560057,6C0500001, | ||
+ | 6C0570001,790540001,1600000C4,010540004,790550001,6C057001C,600550000,3C0000000, | ||
+ | 1000000C4, 040500059,4C0510032,0A0510059,8C0500011,3.9亿,8C0510012,3.9亿, | ||
+ | 6605800FF,3.6亿,01051000A,530510041,0105100FF,530510042,3.6亿,0105100FF, | ||
+ | 530510041,010510019,530510042,3.6亿,0105AA2FF,0105BA27F,230000166,3.6亿, | ||
+ | 0106B0000,010690112, 0106A010D,230000065、0106B0001、010690116、0106A011B,23000005E, | ||
+ | 0106B0002、01069011F,0106A0124、23000005E,0106B0004、010690128、0106A012D,23000005E, | ||
+ | 0106B0008,010690131,0106A0136,23000005E,0106B0010,01069013A,0106A013F,23000005E, | ||
+ | 0106B0020,010690143,0106A0148,23000005E,0106B0040,01069014C,0106A0151,23000005E, | ||
+ | 0106B0080,010690155,0106A015A,23000005E,3.6亿,0105C0015,0105AA1F5,0105BA1DF, | ||
+ | 23000015E, 360000000、0105AA1F5、0105BA1DF,230000166、360000000、0105C0020、0105AA20A,0105BA1FF,23000015E,360000000、0105AA20A, | ||
+ | 0105BA1FF | ||
+ | ,230000166、360000000、0105C002C,0105AA21B,0105BA20F, | ||
+ | 23000015E,360000000、0105AA2000, 0105BA21F,23000015E, | ||
+ | 360000000、0105AA229、0105BA21F,230000166、360000000、0105C0046、0105AA23F,0105BA22F,23000015E,360000000、0105AA23F,0105BA22F, | ||
+ | 230000166,3.6亿,0105C0055,0105AA24E,0105BA23F,23000015E,3.6亿,0105AA24E, | ||
+ | 0105BA23F,230000166,3.6亿,0105C0064,0105AA25E,0105BA24F,23000015E,3.6亿, | ||
+ | 0105AA25E,0105BA24F,230000166,3.6亿,0105C0072,0105AA26D,0105BA25F,23000015E, | ||
+ | 3.6亿, 0105AA26D,0105BA25F,230000166,3.6亿,0105C0082,0105AA27F,0105BA26F, | ||
+ | 23000015E,3.6亿,0105AA27F,0105BA26F,230000166,3.6亿,5305C0005,4C0500012, | ||
+ | 56050005A,7905A0001,7905C0001,9005A005B,16000015E,3.6亿,0105C00FF,5605C005A, | ||
+ | 7905A0001,9005A005B, 160000166、360000000、4C0030013、590030004、8C0030004、2C0000173、8C0030004、29000017B, | ||
+ | 360000000、6C05D0001、8C05D0020、2C0000178、5305EA700、360000000, | ||
+ | 6C05E0001,0105D0000,3.6亿,0105E0000,5305EA700,0105D0000,3.6亿,0106B0008, | ||
+ | 010690185,0106A01FE,23000005E,230000220,3.6亿,230000205,010500020,070530050, | ||
+ | 8C0530060,2C00001A4,8C0530020,2C0000194,8C05300E0,2C00001C4,8C05300A0,2C00001B4, | ||
+ | 6C0500001, 8C0500028,160000187,3.6亿,2300001D4,8C05F0001,1900001F2,2300001E9, | ||
+ | 8C05F0001,1900001FB,040510050,790510008,070520051,6C0520001,0D0520051,790510008, | ||
+ | 070520051,790520001,0D0520051,3.6亿,2300001D4,8C05F0001,1900001F5,2300001E2, | ||
+ | 8C05F0001,1900001F8, 040510050、790510008、070520051、790520001、0D0520051、790510008、070520051、790520001、0D0520051、360000000、2300001DB | ||
+ | ,8C05F0001、1900001F8、2300001E9, | ||
+ | 8C05F0001,1900001F5,040510050,790510008,070520051,6C0520001,0D0520051,790510008, | ||
+ | 070520051,6C0520001,0D0520051,3.6亿,2300001E2,8C05F0001,1900001F2,2300001DB, | ||
+ | 8C05F0001,1900001FB,040510050,790510008,070520051,790520001,0D0520051,790510008, | ||
+ | 070520051, 6C0520001,0D0520051,3.6亿,040510050,790510010,070520051,8C0520000, | ||
+ | 1900001F0,0105F0000,3.6亿,040510050,790510010,070520051,8C05200E7,1900001F0, | ||
+ | 0105F0000,3.6亿,040510050,790510008,070520051,8C0520000,1900001F0,0105F0000, | ||
+ | 3.6亿,040510050, 790510008、070520051、8C05200F7、1900001F0、0105F0000、360000000、0105F0001、360000000、0105100A0、0D0510050、360000000、0105100E0、0D0510050、360000000 | ||
+ | , | ||
+ | 010510020,0D0510050,3.6亿,010510060,0D0510050,3.6亿,01050000F,0105100FF, | ||
+ | 6C0500001,0D0510050,8C0500017,160000200,3.6亿,8C01000FF,3.9亿,01010000B, | ||
+ | 010110016,010120021,01013002C,010140037,010150042,01016004D,010170058,01018000B, | ||
+ | 010190016, 0101A0021,0101B002C,0101C0037,0101D0042,0101E004D,0101F0058,0102000A0, | ||
+ | 0102100A0,0102200A0,0102300A0,0102400A0,0102500A0,0102600A0,0102700A0,3.6亿, | ||
+ | 010500010,01051B000,070520050,560520051,6C0500001,6C0510004,8C0500018,160000222, | ||
+ | 010500018,01051B003, 070520050、560520051、6C0500001、6C0510004、8C0500020、16000022A | ||
+ | ,010500020、01051B002、070520050、560520051、6C0500001、6C0510004、8C0500028、160000232, | ||
+ | 010500004,01051B001,560500051,6C0510004,8C051B021,16000023A,3.6亿,0106B0040, | ||
+ | 010690243,0106A0262,10000005E,6C0600001,8C0600010,3.9亿,010600000,01050A600, | ||
+ | 010520030,8C0520030,19000025D,8C0520034,19000025D,8C0520038,19000025D,8C052003C, | ||
+ | 19000025D, 8C0520040,19000025D,8C0520044,19000025D,8C0520048,19000025D,8C052004C, | ||
+ | 19000025D,070510052,6C0510001,0D0510052,560510050,6C0500001,6C0520001,8C050A620, | ||
+ | 160000249,3.6亿,01050A600,010530030,010510000,530510006,4C0520012,560520050, | ||
+ | 0D0520053,6C0510001, 6C0500001、6C0530001、8C050A620、160000265、360000000、0106B0080、010690273、0106A0288、10000005E | ||
+ | ,6C0610001、8C0610004、390000000、0150B020、530620007, | ||
+ | 4C0510012,560510050,6C0620001,6C0500001,5906200FF,8C0620040,190000286,8C0620080, | ||
+ | 190000286,8C06200C0,190000286,8C0620000,190000286,100000277,010610000,3.6亿, | ||
+ | 01050B020,0105100FF,560510050,6C0500001,8C050B060,16000028A,010610000,010620000, | ||
+ | 3.6亿, 0106B0002,010690295,0106A02A8,10000005E,01050A000,010510078,560510050, | ||
+ | 6C0500001,8C050A020,160000297,010510079,560510050,6C0500001,8C050A1A0,16000029C, | ||
+ | 01051007A,560510050,6C0500001,8C050A1C0,1600002A1,2300002BA,2300002CF,3.6亿, | ||
+ | 0105100FF,01050A000, 560510050、6C0500001、8C050A1C0、1600002AA, | ||
+ | 560510050、6C0500001、560510050、6C0500001、560510050、01050B100、0105100FF,560510050、6C0500001、8C050B300, | ||
+ | 1600002B5,3.6亿,01050B100,010510000,010520100,0105300A0,070660052,66066007F, | ||
+ | 790660010,560660050,6C0500001,560530050,6C0500001,010660002,560660050,6C0500001, | ||
+ | 560510050,6C0520001,6C0510002,6C0500001,8C050B300,1600002BE,3.6亿,8C0950200, | ||
+ | 1600002D4, 010510078,010520001,010530021,8C0950100,1600002D9,010510078,010520002, | ||
+ | 010530021,8C0950080,1600002DE,010510078,010520004,010530021,8C0950040,1600002E3, | ||
+ | 010510078,010520008,010530021,8C0950020,1600002E8,010510001,010520006,010530021, | ||
+ | 8C0950010,1600002ED, 010510003,010520002,010530021,01050A000,560510050,6C0500001, | ||
+ | 560520050,6C0500001,560530050,3.6亿,010930000,010630100,4C0650034,930650000, | ||
+ | 330000310,4C0650034,930650000,30000030E,6C0640001,900640095,1600002FC,010640000, | ||
+ | 4C0650034,590650FFF,990650000,990650000,990650000,990650000,990650000,790650008, | ||
+ | 0D0650063,6C0630001,8C0630180,1600002FC,010630000,3.6亿,010940000,3.6亿, | ||
+ | 960940000, 200000314,010948000,3.6亿,9C0940000,9C0940000,300000319,010948001, | ||
+ | 3.6亿,8C0950200,190000327,8C0950100,190000329,8C0950080,19000032B,8C0950040, | ||
+ | 19000032D,8C0950020,19000032F,8C0950010,100000325,010950200,3.6亿,010950100, | ||
+ | 3.6亿,010950080, 3.6亿,010950040,3.6亿,010950020,3.6亿,010950010, | ||
+ | 3.6亿,0106B0010,010690335,0106A0350,10000005E,6C0670001,8C0670008,3.9亿, | ||
+ | 010670000,6C0680001,8C0680004,2C000034E,01050A580,8C0680000,160000340,01051001B, | ||
+ | 8C0680001,160000343,0105100C6,8C0680002,160000346,0105100B1,8C0680003,160000349, | ||
+ | 01051006C,560510050,6C0500001,8C050A5A0,16000033D,3.6亿,010680000,3.6亿, | ||
+ | 01050A580, 010510000,560510050,6C0500001,8C050A5A0,160000352,3.6亿,0106B0020, | ||
+ | 01069035B,0106A03D1,10000005E,01050A33F,01051007C,6C0500003,560510050,6C0500001, | ||
+ | 560510050,8C050A3BF,16000035D,6C06C0001,6C06F0001,23000038D,230000390,01050B0D0, | ||
+ | 04051006D,530510006, 4C0520012、560520050、6C0500001、6C0510001、530510006、4C0520012、560520050、6C0500003、6C0510001、8C050B100、160000369、04050006E | ||
+ | ,53090B0D2、53050B0D3, | ||
+ | 53090B0DA,53050B0DB,53090B0E2,53050B0E3,53090B0EE,53050B0EF,6C0500008,53091B0D6, | ||
+ | 53050B0D7,53091B0DE,53050B0DF,53091B0E6,53050B0E7,53091B0F2,53050B0F3,6C0500008, | ||
+ | 53092B0EA,53050B0EB,53092B0F6,53050B0F7,3.6亿,8C06F0002,19000039A,3.6亿, | ||
+ | 8C06C0008, 190000393、360000000、6C06D0018、8C06D00A0、2C0000398、0106C0000、360000000、0106D0040、360000000、0106F0000、7906E0001、5906E00FF,04050006E,8C0500020、2C00003CB,8C0500040、2C00003CB,8C0C0C, | ||
+ | 0C0C0C,0C0C0C,0C0C0C, | ||
+ | 0C0C0C,0C0C0C,0C0C0C,0C0C0C,0C0C0C,0C0C0C,0C0C0C,0C0C0C, | ||
+ | 0C0C0C,0C0C0C0C05000C 8C05000E0、2C00003CB,6C0500008、8C0500020、2C00003CD,8C0500040、2C00003CD, | ||
+ | 8C0500060、2C00003CD,8C0500080、2C00003CD,8C05000A0、2C00003CD,8C05000C0, | ||
+ | 2C00003CD,8C05000E0,2C00003CD,6C0500008,8C0500020,2C00003CF,8C0500040,2C00003CF, | ||
+ | 8C0500060,2C00003CF,8C0500080,2C00003CF,8C05000A0,2C00003CF,8C05000C0,2C00003CF, | ||
+ | 8C05000E0,2C00003CF,3.6亿,660900020,3.6亿,660910020,3.6亿,660920020, | ||
+ | 3.6亿, 01050A320,0105100FF,560510050,6C0500001,8C050A3C0,1600003D3,01050B0D0, | ||
+ | 560510050,6C0500001,8C050B100,1600003D8,0106D0040,0106E00E5,010900003,010910003, | ||
+ | 010920003,3.6亿,000000000,000000000,000000000,000000000,000000000,000000000, | ||
+ | 000000000,000000000, 000000000,000000000,000000000,000000000,000000000,000000000, | ||
+ | 000000000,000000000,000000000,000000000,000000000,000000000,000000000,000000000, | ||
+ | 000000000,000000000,000000000,000000000,000000000,000000000,000000000,000000000; | ||
+ | |||
+ | </code> | ||
+ | \\ | ||