1 2// Benchmark source: 3// https://github.com/daveshah1/up5k-demos/tree/master/nes 4 5// =================================================================== 6 7module scan_double(input clk, 8 input [14:0] inputpixel, 9 input reset_frame, 10 input reset_line, 11 input [9:0] read_x, 12 output reg [14:0] outpixel); 13reg [1:0] frac; 14reg [14:0] linebuf[0:255]; 15reg [8:0] write_x; 16 17always @(posedge clk) 18begin 19 if(reset_line) 20 begin 21 frac <= 2'b00; 22 write_x <= 9'd0; 23 end else begin 24 frac <= frac + 1; 25 if (frac == 2) 26 if (write_x < 256) 27 write_x <= write_x + 1; 28 end 29end 30 31wire write_en = ((frac == 2) && (write_x < 256)) ? 1'b1 : 1'b0; 32 33always @(posedge clk) 34begin 35 outpixel <= linebuf[read_x[8:1]]; 36 if(write_en) 37 linebuf[write_x[7:0]] <= inputpixel; 38end 39 40 41 42endmodule/** 43 * PLL configuration 44 * 45 * This Verilog module was generated automatically 46 * using the icepll tool from the IceStorm project. 47 * Use at your own risk. 48 * 49 * Given input frequency: 16.000 MHz 50 * Requested output frequency: 21.477 MHz 51 * Achieved output frequency: 21.500 MHz 52 */ 53 54module pll( 55 input clock_in, 56 output clock_out, 57 output locked 58 ); 59 60assign clock_out = clock_in; 61assign locked = 1'b1; 62 63endmodule 64/* 65This memory device contains both system memory 66and cartridge data. 67*/ 68 69module main_mem( 70 input clock, reset, 71 72 input reload, 73 input [3:0] index, 74 75 output load_done, 76 output [31:0] flags_out, 77 //NES interface 78 input [21:0] mem_addr, 79 input mem_rd_cpu, mem_rd_ppu, 80 input mem_wr, 81 output reg [7:0] mem_q_cpu, mem_q_ppu, 82 input [7:0] mem_d, 83 84 //Flash load interface 85 output flash_csn, 86 output flash_sck, 87 output flash_mosi, 88 input flash_miso); 89 90// Compress the 4MB logical address space to our limited available space 91// In the future a more sophisticated memory system will keep games in 92// SQI flash to expand the space available 93 94// Also may consider changing this based on mapper to make the most 95// of limited memory 96 97wire prgrom_en, chrrom_en, vram_en, cpuram_en, cartram_en; 98 99// Mapping 100// 0... : PRG : lower 64kB SPRAM 101// 10.. : CHR : upper 64kB SPRAM 102// 1100 : CHR-VRAM : dedicated 2kB RAM 103// 1110 : CPU-RAM : dedicated 2kB RAM 104// 1111 : CART-RAM : dedicated 2kB RAM 105 106assign prgrom_en = !mem_addr[21]; 107assign chrrom_en = mem_addr[21] & !mem_addr[20]; 108assign vram_en = mem_addr[21] & mem_addr[20] & !mem_addr[19] & !mem_addr[18]; 109assign cpuram_en = mem_addr[21] & mem_addr[20] & mem_addr[19] & !mem_addr[18]; 110assign cartram_en = mem_addr[21] & mem_addr[20] & mem_addr[19] & mem_addr[18]; 111 112wire [20:0] segment_addr = prgrom_en ? mem_addr[20:0] : (chrrom_en ? {1'b0, mem_addr[19:0]} : {3'b0, mem_addr[17:0]}); 113 114wire [7:0] cpuram_read_data, vram_read_data, cart_read_data; 115wire rden = mem_rd_cpu | mem_rd_ppu; 116 117always@(posedge clock or posedge reset) 118begin 119 if (reset == 1'b1) begin 120 mem_q_cpu <= 0; 121 mem_q_ppu <= 0; 122 end else begin 123 if (mem_rd_cpu) 124 mem_q_cpu <= cpuram_en ? cpuram_read_data : (vram_en ? vram_read_data : cart_read_data); 125 if (mem_rd_ppu) 126 mem_q_ppu <= cpuram_en ? cpuram_read_data : (vram_en ? vram_read_data : cart_read_data); 127 end; 128end 129 130cart_mem cart_i ( 131 .clock(clock), 132 .reset(reset), 133 .reload(reload), 134 .index(index), 135 .cart_ready(load_done), 136 .flags_out(flags_out), 137 .address(segment_addr), 138 .prg_sel(prgrom_en), 139 .chr_sel(chrrom_en), 140 .ram_sel(cartram_en), 141 .rden(rden), 142 .wren(mem_wr), 143 .write_data(mem_d), 144 .read_data(cart_read_data), 145 146 //Flash load interface 147 .flash_csn(flash_csn), 148 .flash_sck(flash_sck), 149 .flash_mosi(flash_mosi), 150 .flash_miso(flash_miso) 151); 152 153generic_ram #( 154 .WIDTH(8), 155 .WORDS(2048) 156) cpuram_i ( 157 .clock(clock), 158 .reset(reset), 159 .address(segment_addr[10:0]), 160 .wren(mem_wr&cpuram_en), 161 .write_data(mem_d), 162 .read_data(cpuram_read_data) 163); 164 165generic_ram #( 166 .WIDTH(8), 167 .WORDS(2048) 168) vram_i ( 169 .clock(clock), 170 .reset(reset), 171 .address(segment_addr[10:0]), 172 .wren(mem_wr&vram_en), 173 .write_data(mem_d), 174 .read_data(vram_read_data) 175); 176 177endmodule// Copyright (c) 2012-2013 Ludvig Strigeus 178// This program is GPL Licensed. See COPYING for the full license. 179 180// Module handles updating the loopy scroll register 181module LoopyGen ( 182 input clk, input ce, 183 input is_rendering, 184 input [2:0] ain, // input address from CPU 185 input [7:0] din, // data input 186 input read, // read 187 input write, // write 188 input is_pre_render, // Is this the pre-render scanline 189 input [8:0] cycle, 190 output [14:0] loopy, 191 output [2:0] fine_x_scroll); // Current loopy value 192 // Controls how much to increment on each write 193 reg ppu_incr; // 0 = 1, 1 = 32 194 // Current VRAM address 195 reg [14:0] loopy_v; 196 // Temporary VRAM address 197 reg [14:0] loopy_t; 198 // Fine X scroll (3 bits) 199 reg [2:0] loopy_x; 200 // Latch 201 reg ppu_address_latch; 202 initial begin 203 ppu_incr = 0; 204 loopy_v = 0; 205 loopy_t = 0; 206 loopy_x = 0; 207 ppu_address_latch = 0; 208 end 209 // Handle updating loopy_t and loopy_v 210 always @(posedge clk) if (ce) begin 211 if (is_rendering) begin 212 // Increment course X scroll right after attribute table byte was fetched. 213 if (cycle[2:0] == 3 && (cycle < 256 || cycle >= 320 && cycle < 336)) begin 214 loopy_v[4:0] <= loopy_v[4:0] + 1; 215 loopy_v[10] <= loopy_v[10] ^ (loopy_v[4:0] == 31); 216 end 217 218 // Vertical Increment 219 if (cycle == 251) begin 220 loopy_v[14:12] <= loopy_v[14:12] + 1; 221 if (loopy_v[14:12] == 7) begin 222 if (loopy_v[9:5] == 29) begin 223 loopy_v[9:5] <= 0; 224 loopy_v[11] <= !loopy_v[11]; 225 end else begin 226 loopy_v[9:5] <= loopy_v[9:5] + 1; 227 end 228 end 229 end 230 231 // Horizontal Reset at cycle 257 232 if (cycle == 256) 233 {loopy_v[10], loopy_v[4:0]} <= {loopy_t[10], loopy_t[4:0]}; 234 235 // On cycle 256 of each scanline, copy horizontal bits from loopy_t into loopy_v 236 // On cycle 304 of the pre-render scanline, copy loopy_t into loopy_v 237 if (cycle == 304 && is_pre_render) begin 238 loopy_v <= loopy_t; 239 end 240 end 241 if (write && ain == 0) begin 242 loopy_t[10] <= din[0]; 243 loopy_t[11] <= din[1]; 244 ppu_incr <= din[2]; 245 end else if (write && ain == 5) begin 246 if (!ppu_address_latch) begin 247 loopy_t[4:0] <= din[7:3]; 248 loopy_x <= din[2:0]; 249 end else begin 250 loopy_t[9:5] <= din[7:3]; 251 loopy_t[14:12] <= din[2:0]; 252 end 253 ppu_address_latch <= !ppu_address_latch; 254 end else if (write && ain == 6) begin 255 if (!ppu_address_latch) begin 256 loopy_t[13:8] <= din[5:0]; 257 loopy_t[14] <= 0; 258 end else begin 259 loopy_t[7:0] <= din; 260 loopy_v <= {loopy_t[14:8], din}; 261 end 262 ppu_address_latch <= !ppu_address_latch; 263 end else if (read && ain == 2) begin 264 ppu_address_latch <= 0; //Reset PPU address latch 265 end else if ((read || write) && ain == 7 && !is_rendering) begin 266 // Increment address every time we accessed a reg 267 loopy_v <= loopy_v + (ppu_incr ? 32 : 1); 268 end 269 end 270 assign loopy = loopy_v; 271 assign fine_x_scroll = loopy_x; 272endmodule 273 274 275// Generates the current scanline / cycle counters 276module ClockGen(input clk, input ce, input reset, 277 input is_rendering, 278 output reg [8:0] scanline, 279 output reg [8:0] cycle, 280 output reg is_in_vblank, 281 output end_of_line, 282 output at_last_cycle_group, 283 output exiting_vblank, 284 output entering_vblank, 285 output reg is_pre_render); 286 reg second_frame; 287 288 // Scanline 0..239 = picture scan lines 289 // Scanline 240 = dummy scan line 290 // Scanline 241..260 = VBLANK 291 // Scanline -1 = Pre render scanline (Fetches objects for next line) 292 assign at_last_cycle_group = (cycle[8:3] == 42); 293 // Every second pre-render frame is only 340 cycles instead of 341. 294 assign end_of_line = at_last_cycle_group && cycle[3:0] == (is_pre_render && second_frame && is_rendering ? 3 : 4); 295 // Set the clock right before vblank begins 296 assign entering_vblank = end_of_line && scanline == 240; 297 // Set the clock right before vblank ends 298 assign exiting_vblank = end_of_line && scanline == 260; 299 // New value for is_in_vblank flag 300 wire new_is_in_vblank = entering_vblank ? 1'b1 : exiting_vblank ? 1'b0 : is_in_vblank; 301 // Set if the current line is line 0..239 302 always @(posedge clk) if (reset) begin 303 cycle <= 0; 304 is_in_vblank <= 1; 305 end else if (ce) begin 306 cycle <= end_of_line ? 0 : cycle + 1; 307 is_in_vblank <= new_is_in_vblank; 308 end 309// always @(posedge clk) if (ce) begin 310// $write("%x %x %x %x %x\n", new_is_in_vblank, entering_vblank, exiting_vblank, is_in_vblank, entering_vblank ? 1'b1 : exiting_vblank ? 1'b0 : is_in_vblank); 311 312// end 313 always @(posedge clk) if (reset) begin 314 scanline <= 0; 315 is_pre_render <= 0; 316 second_frame <= 0; 317 end else if (ce && end_of_line) begin 318 // Once the scanline counter reaches end of 260, it gets reset to -1. 319 scanline <= exiting_vblank ? 9'b111111111 : scanline + 1; 320 // The pre render flag is set while we're on scanline -1. 321 is_pre_render <= exiting_vblank; 322 323 if (exiting_vblank) 324 second_frame <= !second_frame; 325 end 326 327endmodule // ClockGen 328 329// 8 of these exist, they are used to output sprites. 330module Sprite(input clk, input ce, 331 input enable, 332 input [3:0] load, 333 input [26:0] load_in, 334 output [26:0] load_out, 335 output [4:0] bits); // Low 4 bits = pixel, high bit = prio 336 reg [1:0] upper_color; // Upper 2 bits of color 337 reg [7:0] x_coord; // X coordinate where we want things 338 reg [7:0] pix1, pix2; // Shift registers, output when x_coord == 0 339 reg aprio; // Current prio 340 wire active = (x_coord == 0); 341 always @(posedge clk) if (ce) begin 342 if (enable) begin 343 if (!active) begin 344 // Decrease until x_coord is zero. 345 x_coord <= x_coord - 8'h01; 346 end else begin 347 pix1 <= pix1 >> 1; 348 pix2 <= pix2 >> 1; 349 end 350 end 351 if (load[3]) pix1 <= load_in[26:19]; 352 if (load[2]) pix2 <= load_in[18:11]; 353 if (load[1]) x_coord <= load_in[10:3]; 354 if (load[0]) {upper_color, aprio} <= load_in[2:0]; 355 end 356 assign bits = {aprio, upper_color, active && pix2[0], active && pix1[0]}; 357 assign load_out = {pix1, pix2, x_coord, upper_color, aprio}; 358endmodule // SpriteGen 359 360// This contains all 8 sprites. Will return the pixel value of the highest prioritized sprite. 361// When load is set, and clocked, load_in is loaded into sprite 7 and all others are shifted down. 362// Sprite 0 has highest prio. 363// 226 LUTs, 68 Slices 364module SpriteSet(input clk, input ce, // Input clock 365 input enable, // Enable pixel generation 366 input [3:0] load, // Which parts of the state to load/shift. 367 input [26:0] load_in, // State to load with 368 output [4:0] bits, // Output bits 369 output is_sprite0); // Set to true if sprite #0 was output 370 371 wire [26:0] load_out7, load_out6, load_out5, load_out4, load_out3, load_out2, load_out1, load_out0; 372 wire [4:0] bits7, bits6, bits5, bits4, bits3, bits2, bits1, bits0; 373 Sprite sprite7(clk, ce, enable, load, load_in, load_out7, bits7); 374 Sprite sprite6(clk, ce, enable, load, load_out7, load_out6, bits6); 375 Sprite sprite5(clk, ce, enable, load, load_out6, load_out5, bits5); 376 Sprite sprite4(clk, ce, enable, load, load_out5, load_out4, bits4); 377 Sprite sprite3(clk, ce, enable, load, load_out4, load_out3, bits3); 378 Sprite sprite2(clk, ce, enable, load, load_out3, load_out2, bits2); 379 Sprite sprite1(clk, ce, enable, load, load_out2, load_out1, bits1); 380 Sprite sprite0(clk, ce, enable, load, load_out1, load_out0, bits0); 381 // Determine which sprite is visible on this pixel. 382 assign bits = bits0[1:0] != 0 ? bits0 : 383 bits1[1:0] != 0 ? bits1 : 384 bits2[1:0] != 0 ? bits2 : 385 bits3[1:0] != 0 ? bits3 : 386 bits4[1:0] != 0 ? bits4 : 387 bits5[1:0] != 0 ? bits5 : 388 bits6[1:0] != 0 ? bits6 : 389 bits7; 390 assign is_sprite0 = bits0[1:0] != 0; 391endmodule // SpriteSet 392 393module SpriteRAM(input clk, input ce, 394 input reset_line, // OAM evaluator needs to be reset before processing is started. 395 input sprites_enabled, // Set to 1 if evaluations are enabled 396 input exiting_vblank, // Set to 1 when exiting vblank so spr_overflow can be reset 397 input obj_size, // Set to 1 if objects are 16 pixels. 398 input [8:0] scanline, // Current scan line (compared against Y) 399 input [8:0] cycle, // Current cycle. 400 output reg [7:0] oam_bus, // Current value on the OAM bus, returned to NES through $2004. 401 input oam_ptr_load, // Load oam with specified value, when writing to NES $2003. 402 input oam_load, // Load oam_ptr with specified value, when writing to NES $2004. 403 input [7:0] data_in, // New value for oam or oam_ptr 404 output reg spr_overflow, // Set to true if we had more than 8 objects on a scan line. Reset when exiting vblank. 405 output reg sprite0); // True if sprite#0 is included on the scan line currently being painted. 406 reg [7:0] sprtemp[0:31]; // Sprite Temporary Memory. 32 bytes. 407 reg [7:0] oam[0:255]; // Sprite OAM. 256 bytes. 408 reg [7:0] oam_ptr; // Pointer into oam_ptr. 409 reg [2:0] p; // Upper 3 bits of pointer into temp, the lower bits are oam_ptr[1:0]. 410 reg [1:0] state; // Current state machine state 411 wire [7:0] oam_data = oam[oam_ptr]; 412 // Compute the current address we read/write in sprtemp. 413 reg [4:0] sprtemp_ptr; 414 // Check if the current Y coordinate is inside. 415 wire [8:0] spr_y_coord = scanline - {1'b0, oam_data}; 416 wire spr_is_inside = (spr_y_coord[8:4] == 0) && (obj_size || spr_y_coord[3] == 0); 417 reg [7:0] new_oam_ptr; // [wire] New value for oam ptr 418 reg [1:0] oam_inc; // [wire] How much to increment oam ptr 419 reg sprite0_curr; // If sprite0 is included on the line being processed. 420 reg oam_wrapped; // [wire] if new_oam or new_p wrapped. 421 422 wire [7:0] sprtemp_data = sprtemp[sprtemp_ptr]; 423 always @* begin 424 // Compute address to read/write in temp sprite ram 425 casez({cycle[8], cycle[2]}) 426 2'b0_?: sprtemp_ptr = {p, oam_ptr[1:0]}; 427 2'b1_0: sprtemp_ptr = {cycle[5:3], cycle[1:0]}; // 1-4. Read Y, Tile, Attribs 428 2'b1_1: sprtemp_ptr = {cycle[5:3], 2'b11}; // 5-8. Keep reading X. 429 endcase 430 end 431 432 always @* begin 433 /* verilator lint_off CASEOVERLAP */ 434 // Compute value to return to cpu through $2004. And also the value that gets written to temp sprite ram. 435 casez({sprites_enabled, cycle[8], cycle[6], state, oam_ptr[1:0]}) 436 7'b1_10_??_??: oam_bus = sprtemp_data; // At cycle 256-319 we output what's in sprite temp ram 437 7'b1_??_00_??: oam_bus = 8'b11111111; // On the first 64 cycles (while inside state 0), we output 0xFF. 438 7'b1_??_01_00: oam_bus = {4'b0000, spr_y_coord[3:0]}; // Y coord that will get written to temp ram. 439 7'b?_??_??_10: oam_bus = {oam_data[7:5], 3'b000, oam_data[1:0]}; // Bits 2-4 of attrib are always zero when reading oam. 440 default: oam_bus = oam_data; // Default to outputting from oam. 441 endcase 442 end 443 444 always @* begin 445 // Compute incremented oam counters 446 casez ({oam_load, state, oam_ptr[1:0]}) 447 5'b1_??_??: oam_inc = {oam_ptr[1:0] == 3, 1'b1}; // Always increment by 1 when writing to oam. 448 5'b0_00_??: oam_inc = 2'b01; // State 0: On the the first 64 cycles we fill temp ram with 0xFF, increment low bits. 449 5'b0_01_00: oam_inc = {!spr_is_inside, spr_is_inside}; // State 1: Copy Y coordinate and increment oam by 1 if it's inside, otherwise 4. 450 5'b0_01_??: oam_inc = {oam_ptr[1:0] == 3, 1'b1}; // State 1: Copy remaining 3 bytes of the oam. 451 // State 3: We've had more than 8 sprites. Set overflow flag if we found a sprite that overflowed. 452 // NES BUG: It increments both low and high counters. 453 5'b0_11_??: oam_inc = 2'b11; 454 // While in the final state, keep incrementing the low bits only until they're zero. 455 5'b0_10_??: oam_inc = {1'b0, oam_ptr[1:0] != 0}; 456 endcase 457 /* verilator lint_on CASEOVERLAP */ 458 new_oam_ptr[1:0] = oam_ptr[1:0] + {1'b0, oam_inc[0]}; 459 {oam_wrapped, new_oam_ptr[7:2]} = {1'b0, oam_ptr[7:2]} + {6'b0, oam_inc[1]}; 460 end 461 always @(posedge clk) if (ce) begin 462 463 // Some bits of the OAM are hardwired to zero. 464 if (oam_load) 465 oam[oam_ptr] <= (oam_ptr & 3) == 2 ? data_in & 8'hE3: data_in; 466 if (cycle[0] && sprites_enabled || oam_load || oam_ptr_load) begin 467 oam_ptr <= oam_ptr_load ? data_in : new_oam_ptr; 468 end 469 // Set overflow flag? 470 if (sprites_enabled && state == 2'b11 && spr_is_inside) 471 spr_overflow <= 1; 472 // Remember if sprite0 is included on the scanline, needed for hit test later. 473 sprite0_curr <= (state == 2'b01 && oam_ptr[7:2] == 0 && spr_is_inside || sprite0_curr); 474 475// if (scanline == 0 && cycle[0] && (state == 2'b01 || state == 2'b00)) 476// $write("Drawing sprite %d/%d. bus=%d oam_ptr=%X->%X oam_data=%X p=%d (%d %d %d)\n", scanline, cycle, oam_bus, oam_ptr, new_oam_ptr, oam_data, p, 477// cycle[0] && sprites_enabled, oam_load, oam_ptr_load); 478 479 // Always writing to temp ram while we're in state 0 or 1. 480 if (!state[1]) sprtemp[sprtemp_ptr] <= oam_bus; 481 // Update state machine on every second cycle. 482 if (cycle[0]) begin 483 // Increment p whenever oam_ptr carries in state 0 or 1. 484 if (!state[1] && oam_ptr[1:0] == 2'b11) p <= p + 1; 485 // Set sprite0 if sprite1 was included on the scan line 486 casez({state, (p == 7) && (oam_ptr[1:0] == 2'b11), oam_wrapped}) 487 4'b00_0_?: state <= 2'b00; // State #0: Keep filling 488 4'b00_1_?: state <= 2'b01; // State #0: Until we filled 64 items. 489 4'b01_?_1: state <= 2'b10; // State #1: Goto State 2 if processed all OAM 490 4'b01_1_0: state <= 2'b11; // State #1: Goto State 3 if we found 8 sprites 491 4'b01_0_0: state <= 2'b01; // State #1: Keep comparing Y coordinates. 492 4'b11_?_1: state <= 2'b10; // State #3: Goto State 2 if processed all OAM 493 4'b11_?_0: state <= 2'b11; // State #3: Keep comparing Y coordinates 494 4'b10_?_?: state <= 2'b10; // Stuck in state 2. 495 endcase 496 end 497 if (reset_line) begin 498 state <= 0; 499 p <= 0; 500 oam_ptr <= 0; 501 sprite0_curr <= 0; 502 sprite0 <= sprite0_curr; 503 end 504 if (exiting_vblank) 505 spr_overflow <= 0; 506 end 507endmodule // SpriteRAM 508 509 510// Generates addresses in VRAM where we'll fetch sprite graphics from, 511// and populates load, load_in so the SpriteGen can be loaded. 512// 10 LUT, 4 Slices 513module SpriteAddressGen(input clk, input ce, 514 input enabled, // If unset, |load| will be all zeros. 515 input obj_size, // 0: Sprite Height 8, 1: Sprite Height 16. 516 input obj_patt, // Object pattern table selection 517 input [2:0] cycle, // Current load cycle. At #4, first bitmap byte is loaded. At #6, second bitmap byte is. 518 input [7:0] temp, // Input temp data from SpriteTemp. #0 = Y Coord, #1 = Tile, #2 = Attribs, #3 = X Coord 519 output [12:0] vram_addr,// Low bits of address in VRAM that we'd like to read. 520 input [7:0] vram_data, // Byte of VRAM in the specified address 521 output [3:0] load, // Which subset of load_in that is now valid, will be loaded into SpritesGen. 522 output [26:0] load_in); // Bits to load into SpritesGen. 523 reg [7:0] temp_tile; // Holds the tile that we will get 524 reg [3:0] temp_y; // Holds the Y coord (will be swapped based on FlipY). 525 reg flip_x, flip_y; // If incoming bitmap data needs to be flipped in the X or Y direction. 526 wire load_y = (cycle == 0); 527 wire load_tile = (cycle == 1); 528 wire load_attr = (cycle == 2) && enabled; 529 wire load_x = (cycle == 3) && enabled; 530 wire load_pix1 = (cycle == 5) && enabled; 531 wire load_pix2 = (cycle == 7) && enabled; 532 reg dummy_sprite; // Set if attrib indicates the sprite is invalid. 533 // Flip incoming vram data based on flipx. Zero out the sprite if it's invalid. The bits are already flipped once. 534 wire [7:0] vram_f = dummy_sprite ? 0 : 535 !flip_x ? {vram_data[0], vram_data[1], vram_data[2], vram_data[3], vram_data[4], vram_data[5], vram_data[6], vram_data[7]} : 536 vram_data; 537 wire [3:0] y_f = temp_y ^ {flip_y, flip_y, flip_y, flip_y}; 538 assign load = {load_pix1, load_pix2, load_x, load_attr}; 539 assign load_in = {vram_f, vram_f, temp, temp[1:0], temp[5]}; 540 // If $2000.5 = 0, the tile index data is used as usual, and $2000.3 541 // selects the pattern table to use. If $2000.5 = 1, the MSB of the range 542 // result value become the LSB of the indexed tile, and the LSB of the tile 543 // index value determines pattern table selection. The lower 3 bits of the 544 // range result value are always used as the fine vertical offset into the 545 // selected pattern. 546 assign vram_addr = {obj_size ? temp_tile[0] : obj_patt, 547 temp_tile[7:1], obj_size ? y_f[3] : temp_tile[0], cycle[1], y_f[2:0] }; 548 always @(posedge clk) if (ce) begin 549 if (load_y) temp_y <= temp[3:0]; 550 if (load_tile) temp_tile <= temp; 551 if (load_attr) {flip_y, flip_x, dummy_sprite} <= {temp[7:6], temp[4]}; 552 end 553// always @(posedge clk) begin 554// if (load[3]) $write("Loading pix1: %x\n", load_in[26:19]); 555// if (load[2]) $write("Loading pix2: %x\n", load_in[18:11]); 556// if (load[1]) $write("Loading x: %x\n", load_in[10:3]); 557// 558// if (valid_sprite && enabled) 559// $write("%d. Found %d. Flip:%d%d, Addr: %x, Vram: %x!\n", cycle, temp, flip_x, flip_y, vram_addr, vram_data); 560// end 561 562endmodule // SpriteAddressGen 563 564module BgPainter(input clk, input ce, 565 input enable, // Shift registers activated 566 input [2:0] cycle, 567 input [2:0] fine_x_scroll, 568 input [14:0] loopy, 569 output [7:0] name_table, // VRAM name table to read next. 570 input [7:0] vram_data, 571 output [3:0] pixel); 572 reg [15:0] playfield_pipe_1; // Name table pixel pipeline #1 573 reg [15:0] playfield_pipe_2; // Name table pixel pipeline #2 574 reg [8:0] playfield_pipe_3; // Attribute table pixel pipe #1 575 reg [8:0] playfield_pipe_4; // Attribute table pixel pipe #2 576 reg [7:0] current_name_table; // Holds the current name table byte 577 reg [1:0] current_attribute_table; // Holds the 2 current attribute table bits 578 reg [7:0] bg0; // Pixel data for last loaded background 579 wire [7:0] bg1 = vram_data; 580 initial begin 581 playfield_pipe_1 = 0; 582 playfield_pipe_2 = 0; 583 playfield_pipe_3 = 0; 584 playfield_pipe_4 = 0; 585 current_name_table = 0; 586 current_attribute_table = 0; 587 bg0 = 0; 588 end 589 always @(posedge clk) if (ce) begin 590 case (cycle[2:0]) 591 1: current_name_table <= vram_data; 592 3: current_attribute_table <= (!loopy[1] && !loopy[6]) ? vram_data[1:0] : 593 ( loopy[1] && !loopy[6]) ? vram_data[3:2] : 594 (!loopy[1] && loopy[6]) ? vram_data[5:4] : 595 vram_data[7:6]; 596 5: bg0 <= vram_data; // Pattern table bitmap #0 597// 7: bg1 <= vram_data; // Pattern table bitmap #1 598 endcase 599 if (enable) begin 600 playfield_pipe_1[14:0] <= playfield_pipe_1[15:1]; 601 playfield_pipe_2[14:0] <= playfield_pipe_2[15:1]; 602 playfield_pipe_3[7:0] <= playfield_pipe_3[8:1]; 603 playfield_pipe_4[7:0] <= playfield_pipe_4[8:1]; 604 // Load the new values into the shift registers at the last pixel. 605 if (cycle[2:0] == 7) begin 606 playfield_pipe_1[15:8] <= {bg0[0], bg0[1], bg0[2], bg0[3], bg0[4], bg0[5], bg0[6], bg0[7]}; 607 playfield_pipe_2[15:8] <= {bg1[0], bg1[1], bg1[2], bg1[3], bg1[4], bg1[5], bg1[6], bg1[7]}; 608 playfield_pipe_3[8] <= current_attribute_table[0]; 609 playfield_pipe_4[8] <= current_attribute_table[1]; 610 end 611 end 612 end 613 assign name_table = current_name_table; 614 wire [3:0] i = {1'b0, fine_x_scroll}; 615 assign pixel = {playfield_pipe_4[i], playfield_pipe_3[i], 616 playfield_pipe_2[i], playfield_pipe_1[i]}; 617endmodule // BgPainter 618 619module PixelMuxer(input [3:0] bg, input [3:0] obj, input obj_prio, output [3:0] out, output is_obj); 620 wire bg_flag = bg[0] | bg[1]; 621 wire obj_flag = obj[0] | obj[1]; 622 assign is_obj = !(obj_prio && bg_flag) && obj_flag; 623 assign out = is_obj ? obj : bg; 624endmodule 625 626 627module PaletteRam(input clk, input ce, input [4:0] addr, input [5:0] din, output [5:0] dout, input write); 628 reg [5:0] palette [0:31]; 629 initial begin 630 palette[0] = 6'h0F; 631 palette[1] = 6'h2C; 632 palette[2] = 6'h10; 633 palette[3] = 6'h1C; 634 palette[4] = 6'h0F; 635 palette[5] = 6'h37; 636 palette[6] = 6'h27; 637 palette[7] = 6'h07; 638 palette[8] = 6'h0F; 639 palette[9] = 6'h28; 640 palette[10] = 6'h16; 641 palette[11] = 6'h07; 642 palette[12] = 6'h0F; 643 palette[13] = 6'h28; 644 palette[14] = 6'h0F; 645 palette[15] = 6'h2C; 646 palette[16] = 6'h0F; 647 palette[17] = 6'h0F; 648 palette[18] = 6'h2C; 649 palette[19] = 6'h11; 650 palette[20] = 6'h0F; 651 palette[21] = 6'h0F; 652 palette[22] = 6'h20; 653 palette[23] = 6'h38; 654 palette[24] = 6'h0F; 655 palette[25] = 6'h0F; 656 palette[26] = 6'h15; 657 palette[27] = 6'h27; 658 palette[28] = 6'h0F; 659 palette[29] = 6'h0F; 660 palette[30] = 6'h11; 661 palette[31] = 6'h3C; 662 end 663 // Force read from backdrop channel if reading from any addr 0. 664 wire [4:0] addr2 = (addr[1:0] == 0) ? 0 : addr; 665 assign dout = palette[addr2]; 666 always @(posedge clk) if (ce && write) begin 667 // Allow writing only to x0 668 if (!(addr[3:2] != 0 && addr[1:0] == 0)) 669 palette[addr2] <= din; 670 end 671endmodule // PaletteRam 672 673module PPU(input clk, input ce, input reset, // input clock 21.48 MHz / 4. 1 clock cycle = 1 pixel 674 output [5:0] color, // output color value, one pixel outputted every clock 675 input [7:0] din, // input data from bus 676 output [7:0] dout, // output data to CPU 677 input [2:0] ain, // input address from CPU 678 input read, // read 679 input write, // write 680 output nmi, // one while inside vblank 681 output vram_r, // read from vram active 682 output vram_w, // write to vram active 683 output [13:0] vram_a, // vram address 684 input [7:0] vram_din, // vram input 685 output [7:0] vram_dout, 686 output [8:0] scanline, 687 output [8:0] cycle, 688 output [19:0] mapper_ppu_flags); 689 // These are stored in control register 0 690 reg obj_patt; // Object pattern table 691 reg bg_patt; // Background pattern table 692 reg obj_size; // 1 if sprites are 16 pixels high, else 0. 693 reg vbl_enable; // Enable VBL flag 694 // These are stored in control register 1 695 reg grayscale; // Disable color burst 696 reg playfield_clip; // 0: Left side 8 pixels playfield clipping 697 reg object_clip; // 0: Left side 8 pixels object clipping 698 reg enable_playfield; // Enable playfield display 699 reg enable_objects; // Enable objects display 700 reg [2:0] color_intensity; // Color intensity 701 702 initial begin 703 obj_patt = 0; 704 bg_patt = 0; 705 obj_size = 0; 706 vbl_enable = 0; 707 grayscale = 0; 708 playfield_clip = 0; 709 object_clip = 0; 710 enable_playfield = 0; 711 enable_objects = 0; 712 color_intensity = 0; 713 end 714 715 reg nmi_occured; // True if NMI has occured but not cleared. 716 reg [7:0] vram_latch; 717 // Clock generator 718 wire is_in_vblank; // True if we're in VBLANK 719 //wire [8:0] scanline; // Current scanline 720 //wire [8:0] cycle; // Current cycle inside of the line 721 wire end_of_line; // At the last pixel of a line 722 wire at_last_cycle_group; // At the very last cycle group of the scan line. 723 wire exiting_vblank; // At the very last cycle of the vblank 724 wire entering_vblank; // 725 wire is_pre_render_line; // True while we're on the pre render scanline 726 wire is_rendering = (enable_playfield || enable_objects) && !is_in_vblank && scanline != 240; 727 728 ClockGen clock(clk, ce, reset, is_rendering, scanline, cycle, is_in_vblank, end_of_line, at_last_cycle_group, 729 exiting_vblank, entering_vblank, is_pre_render_line); 730 731 732 // The loopy module handles updating of the loopy address 733 wire [14:0] loopy; 734 wire [2:0] fine_x_scroll; 735 LoopyGen loopy0(clk, ce, is_rendering, ain, din, read, write, is_pre_render_line, cycle, loopy, fine_x_scroll); 736 // Set to true if the current ppu_addr pointer points into 737 // palette ram. 738 wire is_pal_address = (loopy[13:8] == 6'b111111); 739 740 // Paints background 741 wire [7:0] bg_name_table; 742 wire [3:0] bg_pixel_noblank; 743 BgPainter bg_painter(clk, ce, !at_last_cycle_group, cycle[2:0], fine_x_scroll, loopy, bg_name_table, vram_din, bg_pixel_noblank); 744 745 // Blank out BG in the leftmost 8 pixels? 746 wire show_bg_on_pixel = (playfield_clip || (cycle[7:3] != 0)) && enable_playfield; 747 wire [3:0] bg_pixel = {bg_pixel_noblank[3:2], show_bg_on_pixel ? bg_pixel_noblank[1:0] : 2'b00}; 748 749 // This will set oam_ptr to 0 right before the scanline 240 and keep it there throughout vblank. 750 wire before_line = (enable_playfield || enable_objects) && (exiting_vblank || end_of_line && !is_in_vblank); 751 wire [7:0] oam_bus; 752 wire sprite_overflow; 753 wire obj0_on_line; // True if sprite#0 is included on the current line 754 SpriteRAM sprite_ram(clk, ce, 755 before_line, // Condition for resetting the sprite line state. 756 is_rendering, // Condition for enabling sprite ram logic. Check so we're not on 757 exiting_vblank, 758 obj_size, 759 scanline, cycle, 760 oam_bus, 761 write && (ain == 3), // Write to oam_ptr 762 write && (ain == 4), // Write to oam[oam_ptr] 763 din, 764 sprite_overflow, 765 obj0_on_line); 766 wire [4:0] obj_pixel_noblank; 767 wire [12:0] sprite_vram_addr; 768 wire is_obj0_pixel; // True if obj_pixel originates from sprite0. 769 wire [3:0] spriteset_load; // Which subset of the |load_in| to load into SpriteSet 770 wire [26:0] spriteset_load_in; // Bits to load into SpriteSet 771 // Between 256..319 (64 cycles), fetches bitmap data for the 8 sprites and fills in the SpriteSet 772 // so that it can start drawing on the next frame. 773 SpriteAddressGen address_gen(clk, ce, 774 cycle[8] && !cycle[6], // Load sprites between 256..319 775 obj_size, obj_patt, // Object size and pattern table 776 cycle[2:0], // Cycle counter 777 oam_bus, // Info from temp buffer. 778 sprite_vram_addr, // [out] VRAM Address that we want data from 779 vram_din, // [in] Data at the specified address 780 spriteset_load, 781 spriteset_load_in); // Which parts of SpriteGen to load 782 // Between 0..255 (256 cycles), draws pixels. 783 // Between 256..319 (64 cycles), will be populated for next line 784 SpriteSet sprite_gen(clk, ce, !cycle[8], spriteset_load, spriteset_load_in, obj_pixel_noblank, is_obj0_pixel); 785 // Blank out obj in the leftmost 8 pixels? 786 wire show_obj_on_pixel = (object_clip || (cycle[7:3] != 0)) && enable_objects; 787 wire [4:0] obj_pixel = {obj_pixel_noblank[4:2], show_obj_on_pixel ? obj_pixel_noblank[1:0] : 2'b00}; 788 789 reg sprite0_hit_bg; // True if sprite#0 has collided with the BG in the last frame. 790 always @(posedge clk) if (ce) begin 791 if (exiting_vblank) 792 sprite0_hit_bg <= 0; 793 else if (is_rendering && // Object rendering is enabled 794 !cycle[8] && // X Pixel 0..255 795 cycle[7:0] != 255 && // X pixel != 255 796 !is_pre_render_line && // Y Pixel 0..239 797 obj0_on_line && // True if sprite#0 is included on the scan line. 798 is_obj0_pixel && // True if the pixel came from tempram #0. 799 show_obj_on_pixel && 800 bg_pixel[1:0] != 0) begin // Background pixel nonzero. 801 sprite0_hit_bg <= 1; 802 803 end 804 805// if (!cycle[8] && is_visible_line && obj0_on_line && is_obj0_pixel) 806// $write("Sprite0 hit bg scan %d!!\n", scanline); 807 808// if (is_obj0_pixel) 809// $write("drawing obj0 pixel %d/%d\n", scanline, cycle); 810 end 811 812 wire [3:0] pixel; 813 wire pixel_is_obj; 814 PixelMuxer pixel_muxer(bg_pixel, obj_pixel[3:0], obj_pixel[4], pixel, pixel_is_obj); 815 816 // Compute the value to put on the VRAM address bus 817 assign vram_a = !is_rendering ? loopy[13:0] : // VRAM 818 (cycle[2:1] == 0) ? {2'b10, loopy[11:0]} : // Name table 819 (cycle[2:1] == 1) ? {2'b10, loopy[11:10], 4'b1111, loopy[9:7], loopy[4:2]} : // Attribute table 820 cycle[8] && !cycle[6] ? {1'b0, sprite_vram_addr} : 821 {1'b0, bg_patt, bg_name_table, cycle[1], loopy[14:12]}; // Pattern table bitmap #0, #1 822 // Read from VRAM, either when user requested a manual read, or when we're generating pixels. 823 assign vram_r = read && (ain == 7) || 824 is_rendering && cycle[0] == 0 && !end_of_line; 825 826 // Write to VRAM? 827 assign vram_w = write && (ain == 7) && !is_pal_address && !is_rendering; 828 829 wire [5:0] color2; 830 PaletteRam palette_ram(clk, ce, 831 is_rendering ? {pixel_is_obj, pixel[3:0]} : (is_pal_address ? loopy[4:0] : 5'b0000), // Read addr 832 din[5:0], // Value to write 833 color2, // Output color 834 write && (ain == 7) && is_pal_address); // Condition for writing 835 assign color = grayscale ? {color2[5:4], 4'b0} : color2; 836// always @(posedge clk) 837// if (scanline == 194 && cycle < 8 && color == 15) begin 838// $write("Pixel black %x %x %x %x %x\n", bg_pixel,obj_pixel,pixel,pixel_is_obj,color); 839// end 840 841 842 always @(posedge clk) if (ce) begin 843// if (!is_in_vblank && write) 844// $write("%d/%d: $200%d <= %x\n", scanline, cycle, ain, din); 845 if (write) begin 846 case (ain) 847 0: begin // PPU Control Register 1 848 // t:....BA.. ........ = d:......BA 849 obj_patt <= din[3]; 850 bg_patt <= din[4]; 851 obj_size <= din[5]; 852 vbl_enable <= din[7]; 853 854 //$write("PPU Control #0 <= %X\n", din); 855 end 856 1: begin // PPU Control Register 2 857 grayscale <= din[0]; 858 playfield_clip <= din[1]; 859 object_clip <= din[2]; 860 enable_playfield <= din[3]; 861 enable_objects <= din[4]; 862 color_intensity <= din[7:5]; 863 if (!din[3] && scanline == 59) 864 $write("Disabling playfield at cycle %d\n", cycle); 865 end 866 endcase 867 end 868 869 // Reset frame specific counters upon exiting vblank 870 if (exiting_vblank) 871 nmi_occured <= 0; 872 // Set the 873 if (entering_vblank) 874 nmi_occured <= 1; 875 // Reset NMI register when reading from Status 876 if (read && ain == 2) 877 nmi_occured <= 0; 878 end 879 880 // If we're triggering a VBLANK NMI 881 assign nmi = nmi_occured && vbl_enable; 882 883 // One cycle after vram_r was asserted, the value 884 // is available on the bus. 885 reg vram_read_delayed; 886 always @(posedge clk) if (ce) begin 887 if (vram_read_delayed) 888 vram_latch <= vram_din; 889 vram_read_delayed = vram_r; 890 end 891 892 // Value currently being written to video ram 893 assign vram_dout = din; 894 895 reg [7:0] latched_dout; 896 always @* begin 897 case (ain) 898 2: latched_dout = {nmi_occured, 899 sprite0_hit_bg, 900 sprite_overflow, 901 5'b00000}; 902 4: latched_dout = oam_bus; 903 default: if (is_pal_address) begin 904 latched_dout = {2'b00, color}; 905 end else begin 906 latched_dout = vram_latch; 907 end 908 endcase 909 end 910 911 assign dout = latched_dout; 912 913 914 assign mapper_ppu_flags = {scanline, cycle, obj_size, is_rendering}; 915 916endmodule // PPU 917// Copyright (c) 2012-2013 Ludvig Strigeus 918// This program is GPL Licensed. See COPYING for the full license. 919 920//`include "cpu.v" 921//`include "apu.v" 922//`include "ppu.v" 923//`include "mmu.v" 924 925// Sprite DMA Works as follows. 926// When the CPU writes to $4014 DMA is initiated ASAP. 927// DMA runs for 512 cycles, the first cycle it reads from address 928// xx00 - xxFF, into a latch, and the second cycle it writes to $2004. 929 930// Facts: 931// 1) Sprite DMA always does reads on even cycles and writes on odd cycles. 932// 2) There are 1-2 cycles of cpu_read=1 after cpu_read=0 until Sprite DMA starts (pause_cpu=1, aout_enable=0) 933// 3) Sprite DMA reads the address value on the last clock of cpu_read=0 934 935/* 936 937=== DMC State Machine === 938 939// 940if (dmc_state == 0 && dmc_trigger && cpu_read && !odd_cycle) dmc_state <= 1; 941if (dmc_state == 1) dmc_state <= (spr_state[1] ? 3 : 2); 942pause_cpu = dmc_state[1] && cpu_read; 943if (dmc_state == 2 && cpu_read && !odd_cycle) dmc_state <= 3; 944aout_enable = (dmc_state == 3 && !odd_cycle) 945dmc_ack = (dmc_state == 3 && !odd_cycle) 946read = 1 947if (dmc_state == 3 && !odd_cycle) dmc_state <= 0; 948 949== Sprite State Machine == 950if (sprite_trigger) { sprite_dma_addr <= data_from_cpu; spr_state <= 1; } 951pause_cpu = spr_state[0] && cpu_read; 952if (spr_state == 1 && cpu_read && odd_cycle) spr_state <= 3; 953if (spr_state == 3 && !odd_cycle) { if (dmc_state == 3) spr_state <= 1; else DO_READ; } 954if (spr_state == 3 && odd_cycle) { DO_WRITE; } 955 956 957// 4) If DMC interrupts Sprite, then it runs on the even cycle, and the odd cycle will be idle (pause_cpu=1, aout_enable=0) 958// 5) When DMC triggers && interrupts CPU, there will be 2-3 cycles (pause_cpu=1, aout_enable=0) before DMC DMA starts. 959*/ 960 961 962module DmaController(input clk, input ce, input reset, 963 input odd_cycle, // Current cycle even or odd? 964 input sprite_trigger, // Sprite DMA trigger? 965 input dmc_trigger, // DMC DMA trigger? 966 input cpu_read, // CPU is in a read cycle? 967 input [7:0] data_from_cpu, // Data written by CPU? 968 input [7:0] data_from_ram, // Data read from RAM? 969 input [15:0] dmc_dma_addr, // DMC DMA Address 970 output [15:0] aout, // Address to access 971 output aout_enable, // DMA controller wants bus control 972 output read, // 1 = read, 0 = write 973 output [7:0] data_to_ram, // Value to write to RAM 974 output dmc_ack, // ACK the DMC DMA 975 output pause_cpu); // CPU is paused 976 reg dmc_state; 977 reg [1:0] spr_state; 978 reg [7:0] sprite_dma_lastval; 979 reg [15:0] sprite_dma_addr; // sprite dma source addr 980 wire [8:0] new_sprite_dma_addr = sprite_dma_addr[7:0] + 8'h01; 981 always @(posedge clk) if (reset) begin 982 dmc_state <= 0; 983 spr_state <= 0; 984 sprite_dma_lastval <= 0; 985 sprite_dma_addr <= 0; 986 end else if (ce) begin 987 if (dmc_state == 0 && dmc_trigger && cpu_read && !odd_cycle) dmc_state <= 1; 988 if (dmc_state == 1 && !odd_cycle) dmc_state <= 0; 989 990 if (sprite_trigger) begin sprite_dma_addr <= {data_from_cpu, 8'h00}; spr_state <= 1; end 991 if (spr_state == 1 && cpu_read && odd_cycle) spr_state <= 3; 992 if (spr_state[1] && !odd_cycle && dmc_state == 1) spr_state <= 1; 993 if (spr_state[1] && odd_cycle) sprite_dma_addr[7:0] <= new_sprite_dma_addr[7:0]; 994 if (spr_state[1] && odd_cycle && new_sprite_dma_addr[8]) spr_state <= 0; 995 if (spr_state[1]) sprite_dma_lastval <= data_from_ram; 996 end 997 assign pause_cpu = (spr_state[0] || dmc_trigger) && cpu_read; 998 assign dmc_ack = (dmc_state == 1 && !odd_cycle); 999 assign aout_enable = dmc_ack || spr_state[1]; 1000 assign read = !odd_cycle; 1001 assign data_to_ram = sprite_dma_lastval; 1002 assign aout = dmc_ack ? dmc_dma_addr : !odd_cycle ? sprite_dma_addr : 16'h2004; 1003endmodule 1004 1005// Multiplexes accesses by the PPU and the PRG into a single memory, used for both 1006// ROM and internal memory. 1007// PPU has priority, its read/write will be honored asap, while the CPU's reads 1008// will happen only every second cycle when the PPU is idle. 1009// Data read by PPU will be available on the next clock cycle. 1010// Data read by CPU will be available within at most 2 clock cycles. 1011 1012module MemoryMultiplex(input clk, input ce, input reset, 1013 input [21:0] prg_addr, input prg_read, input prg_write, input [7:0] prg_din, 1014 input [21:0] chr_addr, input chr_read, input chr_write, input [7:0] chr_din, 1015 // Access signals for the SRAM. 1016 output [21:0] memory_addr, // address to access 1017 output memory_read_cpu, // read into CPU latch 1018 output memory_read_ppu, // read into PPU latch 1019 output memory_write, // is a write operation 1020 output [7:0] memory_dout); 1021 reg saved_prg_read, saved_prg_write; 1022 assign memory_addr = (chr_read || chr_write) ? chr_addr : prg_addr; 1023 assign memory_write = (chr_read || chr_write) ? chr_write : saved_prg_write; 1024 assign memory_read_ppu = chr_read; 1025 assign memory_read_cpu = !(chr_read || chr_write) && (prg_read || saved_prg_read); 1026 assign memory_dout = chr_write ? chr_din : prg_din; 1027 always @(posedge clk) if (reset) begin 1028 saved_prg_read <= 0; 1029 saved_prg_write <= 0; 1030 end else if (ce) begin 1031 if (chr_read || chr_write) begin 1032 saved_prg_read <= prg_read || saved_prg_read; 1033 saved_prg_write <= prg_write || saved_prg_write; 1034 end else begin 1035 saved_prg_read <= 0; 1036 saved_prg_write <= prg_write; 1037 end 1038 end 1039endmodule 1040 1041 1042module NES(input clk, input reset, input ce, 1043 input [31:0] mapper_flags, 1044 output [15:0] sample, // sample generated from APU 1045 output [5:0] color, // pixel generated from PPU 1046 output joypad_strobe,// Set to 1 to strobe joypads. Then set to zero to keep the value. 1047 output [1:0] joypad_clock, // Set to 1 for each joypad to clock it. 1048 input [3:0] joypad_data, // Data for each joypad + 1 powerpad. 1049 input [4:0] audio_channels, // Enabled audio channels 1050 1051 1052 // Access signals for the SRAM. 1053 output [21:0] memory_addr, // address to access 1054 output memory_read_cpu, // read into CPU latch 1055 input [7:0] memory_din_cpu, // next cycle, contents of latch A (CPU's data) 1056 output memory_read_ppu, // read into CPU latch 1057 input [7:0] memory_din_ppu, // next cycle, contents of latch B (PPU's data) 1058 output memory_write, // is a write operation 1059 output [7:0] memory_dout, 1060 1061 output [8:0] cycle, 1062 output [8:0] scanline, 1063 1064 output reg [31:0] dbgadr, 1065 output [1:0] dbgctr 1066 ); 1067 reg [7:0] from_data_bus; 1068 wire [7:0] cpu_dout; 1069 wire odd_or_even; // Is this an odd or even clock cycle? 1070 1071 // The CPU runs at one third the speed of the PPU. 1072 // CPU is clocked at cycle #2. PPU is clocked at cycle #0, #1, #2. 1073 // CPU does its memory I/O on cycle #0. It will be available in time for cycle #2. 1074 reg [1:0] cpu_cycle_counter; 1075 always @(posedge clk) begin 1076 if (reset) 1077 cpu_cycle_counter <= 0; 1078 else if (ce) 1079 cpu_cycle_counter <= (cpu_cycle_counter == 2) ? 0 : cpu_cycle_counter + 1; 1080 end 1081 1082 // Sample the NMI flag on cycle #0, otherwise if NMI happens on cycle #0 or #1, 1083 // the CPU will use it even though it shouldn't be used until the next CPU cycle. 1084 wire nmi; 1085 reg nmi_active; 1086 always @(posedge clk) begin 1087 if (reset) 1088 nmi_active <= 0; 1089 else if (ce && cpu_cycle_counter == 0) 1090 nmi_active <= nmi; 1091 end 1092 1093 wire apu_ce = ce && (cpu_cycle_counter == 2); 1094 1095 // -- CPU 1096 wire [15:0] cpu_addr; 1097 wire cpu_mr, cpu_mw; 1098 wire pause_cpu; 1099 reg apu_irq_delayed; 1100 reg mapper_irq_delayed; 1101 CPU cpu(clk, apu_ce && !pause_cpu, reset, from_data_bus, apu_irq_delayed | mapper_irq_delayed, nmi_active, cpu_dout, cpu_addr, cpu_mr, cpu_mw); 1102 1103 // -- DMA 1104 wire [15:0] dma_aout; 1105 wire dma_aout_enable; 1106 wire dma_read; 1107 wire [7:0] dma_data_to_ram; 1108 wire apu_dma_request, apu_dma_ack; 1109 wire [15:0] apu_dma_addr; 1110 1111 // Determine the values on the bus outgoing from the CPU chip (after DMA / APU) 1112 wire [15:0] addr = dma_aout_enable ? dma_aout : cpu_addr; 1113 wire [7:0] dbus = dma_aout_enable ? dma_data_to_ram : cpu_dout; 1114 wire mr_int = dma_aout_enable ? dma_read : cpu_mr; 1115 wire mw_int = dma_aout_enable ? !dma_read : cpu_mw; 1116 1117 DmaController dma(clk, apu_ce, reset, 1118 odd_or_even, // Even or odd cycle 1119 (addr == 'h4014 && mw_int), // Sprite trigger 1120 apu_dma_request, // DMC Trigger 1121 cpu_mr, // CPU in a read cycle? 1122 cpu_dout, // Data from cpu 1123 from_data_bus, // Data from RAM etc. 1124 apu_dma_addr, // DMC addr 1125 dma_aout, 1126 dma_aout_enable, 1127 dma_read, 1128 dma_data_to_ram, 1129 apu_dma_ack, 1130 pause_cpu); 1131 1132 // -- Audio Processing Unit 1133 wire apu_cs = addr >= 'h4000 && addr < 'h4018; 1134 wire [7:0] apu_dout; 1135 wire apu_irq; 1136 APU apu(clk, apu_ce, reset, 1137 addr[4:0], dbus, apu_dout, 1138 mw_int && apu_cs, mr_int && apu_cs, 1139 audio_channels, 1140 sample, 1141 apu_dma_request, 1142 apu_dma_ack, 1143 apu_dma_addr, 1144 from_data_bus, 1145 odd_or_even, 1146 apu_irq); 1147 1148 // Joypads are mapped into the APU's range. 1149 wire joypad1_cs = (addr == 'h4016); 1150 wire joypad2_cs = (addr == 'h4017); 1151 assign joypad_strobe = (joypad1_cs && mw_int && cpu_dout[0]); 1152 assign joypad_clock = {joypad2_cs && mr_int, joypad1_cs && mr_int}; 1153 1154 1155 // -- PPU 1156 // PPU _reads_ need to happen on the same cycle the cpu runs on, to guarantee we 1157 // see proper values of register $2002. 1158 wire mr_ppu = mr_int && (cpu_cycle_counter == 2); 1159 wire mw_ppu = mw_int && (cpu_cycle_counter == 0); 1160 wire ppu_cs = addr >= 'h2000 && addr < 'h4000; 1161 wire [7:0] ppu_dout; // Data from PPU to CPU 1162 wire chr_read, chr_write; // If PPU reads/writes from VRAM 1163 wire [13:0] chr_addr; // Address PPU accesses in VRAM 1164 wire [7:0] chr_from_ppu; // Data from PPU to VRAM 1165 wire [7:0] chr_to_ppu; 1166 wire [19:0] mapper_ppu_flags; // PPU flags for mapper cheating 1167 PPU ppu(clk, ce, reset, color, dbus, ppu_dout, addr[2:0], 1168 ppu_cs && mr_ppu, ppu_cs && mw_ppu, 1169 nmi, 1170 chr_read, chr_write, chr_addr, chr_to_ppu, chr_from_ppu, 1171 scanline, cycle, mapper_ppu_flags); 1172 1173 // -- Memory mapping logic 1174 wire [15:0] prg_addr = addr; 1175 wire [7:0] prg_din = dbus; 1176 wire prg_read = mr_int && (cpu_cycle_counter == 0) && !apu_cs && !ppu_cs; 1177 wire prg_write = mw_int && (cpu_cycle_counter == 0) && !apu_cs && !ppu_cs; 1178 wire prg_allow, vram_a10, vram_ce, chr_allow; 1179 wire [21:0] prg_linaddr, chr_linaddr; 1180 wire [7:0] prg_dout_mapper, chr_from_ppu_mapper; 1181 wire cart_ce = (cpu_cycle_counter == 0) && ce; 1182 wire mapper_irq; 1183 wire has_chr_from_ppu_mapper; 1184 MultiMapper multi_mapper(clk, cart_ce, ce, reset, mapper_ppu_flags, mapper_flags, 1185 prg_addr, prg_linaddr, prg_read, prg_write, prg_din, prg_dout_mapper, from_data_bus, prg_allow, 1186 chr_read, chr_addr, chr_linaddr, chr_from_ppu_mapper, has_chr_from_ppu_mapper, chr_allow, vram_a10, vram_ce, mapper_irq); 1187 assign chr_to_ppu = has_chr_from_ppu_mapper ? chr_from_ppu_mapper : memory_din_ppu; 1188 1189 // Mapper IRQ seems to be delayed by one PPU clock. 1190 // APU IRQ seems delayed by one APU clock. 1191 always @(posedge clk) if (reset) begin 1192 mapper_irq_delayed <= 0; 1193 apu_irq_delayed <= 0; 1194 end else begin 1195 if (ce) 1196 mapper_irq_delayed <= mapper_irq; 1197 if (apu_ce) 1198 apu_irq_delayed <= apu_irq; 1199 end 1200 1201 // -- Multiplexes CPU and PPU accesses into one single RAM 1202 MemoryMultiplex mem(clk, ce, reset, prg_linaddr, prg_read && prg_allow, prg_write && prg_allow, prg_din, 1203 chr_linaddr, chr_read, chr_write && (chr_allow || vram_ce), chr_from_ppu, 1204 memory_addr, memory_read_cpu, memory_read_ppu, memory_write, memory_dout); 1205 1206 always @* begin 1207 if (reset) 1208 from_data_bus <= 0; 1209 else if (apu_cs) begin 1210 if (joypad1_cs) 1211 from_data_bus = {7'b0100000, joypad_data[0]}; 1212 else if (joypad2_cs) 1213 from_data_bus = {3'b010, joypad_data[3:2] ,2'b00, joypad_data[1]}; 1214 else 1215 from_data_bus = apu_dout; 1216 end else if (ppu_cs) begin 1217 from_data_bus = ppu_dout; 1218 end else if (prg_allow) begin 1219 from_data_bus = memory_din_cpu; 1220 end else begin 1221 from_data_bus = prg_dout_mapper; 1222 end 1223 end 1224 1225endmodule 1226// Copyright (c) 2012-2013 Ludvig Strigeus 1227// This program is GPL Licensed. See COPYING for the full license. 1228 1229//`include "MicroCode.v" 1230 1231module MyAddSub(input [7:0] A,B, 1232 input CI,ADD, 1233 output [7:0] S, 1234 output CO,OFL); 1235 wire C0,C1,C2,C3,C4,C5,C6; 1236 wire C6O; 1237 wire [7:0] I = A ^ B ^ {8{~ADD}}; 1238 MUXCY_L MUXCY_L0 (.LO(C0),.CI(CI),.DI(A[0]),.S(I[0]) ); 1239 MUXCY_L MUXCY_L1 (.LO(C1),.CI(C0),.DI(A[1]),.S(I[1]) ); 1240 MUXCY_L MUXCY_L2 (.LO(C2),.CI(C1),.DI(A[2]),.S(I[2]) ); 1241 MUXCY_L MUXCY_L3 (.LO(C3),.CI(C2),.DI(A[3]),.S(I[3]) ); 1242 MUXCY_L MUXCY_L4 (.LO(C4),.CI(C3),.DI(A[4]),.S(I[4]) ); 1243 MUXCY_L MUXCY_L5 (.LO(C5),.CI(C4),.DI(A[5]),.S(I[5]) ); 1244 MUXCY_D MUXCY_D6 (.LO(C6),.O(C6O),.CI(C5),.DI(A[6]),.S(I[6]) ); 1245 MUXCY MUXCY_7 (.O(CO),.CI(C6),.DI(A[7]),.S(I[7]) ); 1246 XORCY XORCY0 (.O(S[0]),.CI(CI),.LI(I[0])); 1247 XORCY XORCY1 (.O(S[1]),.CI(C0),.LI(I[1])); 1248 XORCY XORCY2 (.O(S[2]),.CI(C1),.LI(I[2])); 1249 XORCY XORCY3 (.O(S[3]),.CI(C2),.LI(I[3])); 1250 XORCY XORCY4 (.O(S[4]),.CI(C3),.LI(I[4])); 1251 XORCY XORCY5 (.O(S[5]),.CI(C4),.LI(I[5])); 1252 XORCY XORCY6 (.O(S[6]),.CI(C5),.LI(I[6])); 1253 XORCY XORCY7 (.O(S[7]),.CI(C6),.LI(I[7])); 1254 XOR2_nes X1(.O(OFL),.I0(C6O),.I1(CO)); 1255endmodule 1256 1257module NewAlu(input [10:0] OP, // ALU Operation 1258 input [7:0] A, // Registers input 1259 input [7:0] X, // "" 1260 input [7:0] Y, // "" 1261 input [7:0] S, // "" 1262 input [7:0] M, // Secondary input to ALU 1263 input [7:0] T, // Secondary input to ALU 1264 // -- Flags Input 1265 input CI, // Carry In 1266 input VI, // Overflow In 1267 // -- Flags output 1268 output reg CO, // Carry out 1269 output reg VO, // Overflow out 1270 output reg SO, // Sign out 1271 output reg ZO, // zero out 1272 // -- Result output 1273 output reg [7:0] Result,// Result out 1274 output reg [7:0] IntR); // Intermediate result out 1275 // Crack the ALU Operation 1276 wire [1:0] o_left_input, o_right_input; 1277 wire [2:0] o_first_op, o_second_op; 1278 wire o_fc; 1279 assign {o_left_input, o_right_input, o_first_op, o_second_op, o_fc} = OP; 1280 1281 // Determine left, right inputs to Add/Sub ALU. 1282 reg [7:0] L, R; 1283 reg CR; 1284 always begin 1285 casez(o_left_input) 1286 0: L = A; 1287 1: L = Y; 1288 2: L = X; 1289 3: L = A & X; 1290 endcase 1291 casez(o_right_input) 1292 0: R = M; 1293 1: R = T; 1294 2: R = L; 1295 3: R = S; 1296 endcase 1297 CR = CI; 1298 casez(o_first_op[2:1]) 1299 0: {CR, IntR} = {R, CI & o_first_op[0]}; // SHL, ROL 1300 1: {IntR, CR} = {CI & o_first_op[0], R}; // SHR, ROR 1301 2: IntR = R; // Passthrough 1302 3: IntR = R + (o_first_op[0] ? 8'b1 : 8'b11111111); // INC/DEC 1303 endcase 1304 end 1305 wire [7:0] AddR; 1306 wire AddCO, AddVO; 1307 MyAddSub addsub(.A(L),.B(IntR),.CI(o_second_op[0] ? CR : 1'b1),.ADD(!o_second_op[2]), .S(AddR), .CO(AddCO), .OFL(AddVO)); 1308 // Produce the output of the second stage. 1309 always begin 1310 casez(o_second_op) 1311 0: {CO, Result} = {CR, L | IntR}; 1312 1: {CO, Result} = {CR, L & IntR}; 1313 2: {CO, Result} = {CR, L ^ IntR}; 1314 3, 6, 7: {CO, Result} = {AddCO, AddR}; 1315 4, 5: {CO, Result} = {CR, IntR}; 1316 endcase 1317 // Final result 1318 ZO = (Result == 0); 1319 // Compute overflow flag 1320 VO = VI; 1321 casez(o_second_op) 1322 1: if (!o_fc) VO = IntR[6]; // Set V to 6th bit for BIT 1323 3: VO = AddVO; // ADC always sets V 1324 7: if (o_fc) VO = AddVO; // Only SBC sets V. 1325 endcase 1326 // Compute sign flag. It's always the uppermost bit of the result, 1327 // except for BIT that sets it to the 7th input bit 1328 SO = (o_second_op == 1 && !o_fc) ? IntR[7] : Result[7]; 1329 end 1330endmodule 1331 1332module AddressGenerator(input clk, input ce, 1333 input [4:0] Operation, 1334 input [1:0] MuxCtrl, 1335 input [7:0] DataBus, T, X, Y, 1336 output [15:0] AX, 1337 output Carry); 1338 // Actual contents of registers 1339 reg [7:0] AL, AH; 1340 // Last operation generated a carry? 1341 reg SavedCarry; 1342 assign AX = {AH, AL}; 1343 1344 wire [2:0] ALCtrl = Operation[4:2]; 1345 wire [1:0] AHCtrl = Operation[1:0]; 1346 1347 // Possible new value for AL. 1348 wire [7:0] NewAL; 1349 assign {Carry,NewAL} = {1'b0, (MuxCtrl[1] ? T : AL)} + {1'b0, (MuxCtrl[0] ? Y : X)}; 1350 1351 // The other one 1352 wire TmpVal = (!AHCtrl[1] | SavedCarry); 1353 wire [7:0] TmpAdd = (AHCtrl[1] ? AH : AL) + {7'b0, TmpVal}; 1354 1355 always @(posedge clk) if (ce) begin 1356 SavedCarry <= Carry; 1357 if (ALCtrl[2]) 1358 case(ALCtrl[1:0]) 1359 0: AL <= NewAL; 1360 1: AL <= DataBus; 1361 2: AL <= TmpAdd; 1362 3: AL <= T; 1363 endcase 1364 1365 case(AHCtrl[1:0]) 1366 0: AH <= AH; 1367 1: AH <= 0; 1368 2: AH <= TmpAdd; 1369 3: AH <= DataBus; 1370 endcase 1371 end 1372endmodule 1373 1374module ProgramCounter(input clk, input ce, 1375 input [1:0] LoadPC, 1376 input GotInterrupt, 1377 input [7:0] DIN, 1378 input [7:0] T, 1379 output reg [15:0] PC, output JumpNoOverflow); 1380 reg [15:0] NewPC; 1381 assign JumpNoOverflow = ((PC[8] ^ NewPC[8]) == 0) & LoadPC[0] & LoadPC[1]; 1382 1383 always begin 1384 // Load PC Control 1385 case (LoadPC) 1386 0,1: NewPC = PC + {15'b0, (LoadPC[0] & ~GotInterrupt)}; 1387 2: NewPC = {DIN,T}; 1388 3: NewPC = PC + {{8{T[7]}},T}; 1389 endcase 1390 end 1391 1392 always @(posedge clk) 1393 if (ce) 1394 PC <= NewPC; 1395endmodule 1396 1397 1398module CPU(input clk, input ce, input reset, 1399 input [7:0] DIN, 1400 input irq, 1401 input nmi, 1402 output reg [7:0] dout, output reg [15:0] aout, 1403 output reg mr, 1404 output reg mw); 1405 reg [7:0] A, X, Y; 1406 reg [7:0] SP, T, P; 1407 reg [7:0] IR; 1408 reg [2:0] State; 1409 reg GotInterrupt; 1410 1411 reg IsResetInterrupt; 1412 wire [15:0] PC; 1413 reg JumpTaken; 1414 wire JumpNoOverflow; 1415 1416 // De-multiplex microcode 1417 wire [37:0] MicroCode; 1418 wire [1:0] LoadSP = MicroCode[1:0]; // 7 LUT 1419 wire [1:0] LoadPC = MicroCode[3:2]; // 12 LUT 1420 wire [1:0] AddrBus = MicroCode[5:4]; // 18 LUT 1421 wire [2:0] MemWrite = MicroCode[8:6]; // 10 LUT 1422 wire [4:0] AddrCtrl = MicroCode[13:9]; 1423 wire FlagCtrl = MicroCode[14]; // RegWrite + FlagCtrl = 22 LUT 1424 wire [1:0] LoadT = MicroCode[16:15]; // 13 LUT 1425 wire [1:0] StateCtrl = MicroCode[18:17]; 1426 wire [2:0] FlagsCtrl = MicroCode[21:19]; 1427 wire [15:0] IrFlags = MicroCode[37:22]; 1428 1429 // Load Instruction Register? Force BRK on Interrupt. 1430 wire [7:0] NextIR = (State == 0) ? (GotInterrupt ? 8'd0 : DIN) : IR; 1431 wire IsBranchCycle1 = (IR[4:0] == 5'b10000) && State[0]; 1432 1433 // Compute next state. 1434 reg [2:0] NextState; 1435 always begin 1436 case (StateCtrl) 1437 0: NextState = State + 3'd1; 1438 1: NextState = (AXCarry ? 3'd4 : 3'd5); 1439 2: NextState = (IsBranchCycle1 && JumpTaken) ? 2 : 0; // Override next state if the branch is taken. 1440 3: NextState = (JumpNoOverflow ? 3'd0 : 3'd4); 1441 endcase 1442 end 1443 1444 wire [15:0] AX; 1445 wire AXCarry; 1446AddressGenerator addgen(clk, ce, AddrCtrl, {IrFlags[0], IrFlags[1]}, DIN, T, X, Y, AX, AXCarry); 1447 1448// Microcode table has a 1 clock latency (block ram). 1449MicroCodeTable micro2(clk, ce, reset, NextIR, NextState, MicroCode); 1450 1451 wire [7:0] AluR; 1452 wire [7:0] AluIntR; 1453 wire CO, VO, SO,ZO; 1454NewAlu new_alu(IrFlags[15:5], A,X,Y,SP,DIN,T, P[0], P[6], CO, VO, SO, ZO, AluR, AluIntR); 1455 1456// Registers 1457always @(posedge clk or posedge reset) if (reset) begin 1458 A <= 0; 1459 X <= 0; 1460 Y <= 0; 1461end else if (ce) begin 1462 if (FlagCtrl & IrFlags[2]) X <= AluR; 1463 if (FlagCtrl & IrFlags[3]) A <= AluR; 1464 if (FlagCtrl & IrFlags[4]) Y <= AluR; 1465end 1466 1467// Program counter 1468ProgramCounter pc(clk, ce, LoadPC, GotInterrupt, DIN, T, PC, JumpNoOverflow); 1469 1470reg IsNMIInterrupt; 1471reg LastNMI; 1472// NMI is triggered at any time, except during reset, or when we're in the middle of 1473// reading the vector address 1474wire turn_nmi_on = (AddrBus != 3) && !IsResetInterrupt && nmi && !LastNMI; 1475// Controls whether we'll remember the state in LastNMI 1476wire nmi_remembered = (AddrBus != 3) && !IsResetInterrupt ? nmi : LastNMI; 1477// NMI flag is cleared right after we read the vector address 1478wire turn_nmi_off = (AddrBus == 3) && (State[0] == 0); 1479// Controls whether IsNmiInterrupt will get set 1480wire nmi_active = turn_nmi_on ? 1 : turn_nmi_off ? 0 : IsNMIInterrupt; 1481always @(posedge clk or posedge reset) begin 1482 if (reset) begin 1483 IsNMIInterrupt <= 0; 1484 LastNMI <= 0; 1485 end else if (ce) begin 1486 IsNMIInterrupt <= nmi_active; 1487 LastNMI <= nmi_remembered; 1488 end 1489end 1490 1491// Generate outputs from module... 1492always begin 1493 dout = 8'bX; 1494 case (MemWrite[1:0]) 1495 'b00: dout = T; 1496 'b01: dout = AluR; 1497 'b10: dout = {P[7:6], 1'b1, !GotInterrupt, P[3:0]}; 1498 'b11: dout = State[0] ? PC[7:0] : PC[15:8]; 1499 endcase 1500 mw = MemWrite[2] && !IsResetInterrupt; // Prevent writing while handling a reset 1501 mr = !mw; 1502end 1503 1504always begin 1505 case (AddrBus) 1506 0: aout = PC; 1507 1: aout = AX; 1508 2: aout = {8'h01, SP}; 1509 // irq/BRK vector FFFE 1510 // nmi vector FFFA 1511 // Reset vector FFFC 1512 3: aout = {13'b1111_1111_1111_1, !IsNMIInterrupt, !IsResetInterrupt, ~State[0]}; 1513 endcase 1514end 1515 1516 1517always @(posedge clk) begin 1518 if (reset) begin 1519 // Reset runs the BRK instruction as usual. 1520 State <= 0; 1521 IR <= 0; 1522 GotInterrupt <= 1; 1523 IsResetInterrupt <= 1; 1524 P <= 'h24; 1525 SP <= 0; 1526 T <= 0; 1527 JumpTaken <= 0; 1528 end else if (ce) begin 1529 // Stack pointer control. 1530 // The operand is an optimization that either 1531 // returns -1,0,1 depending on LoadSP 1532 case (LoadSP) 1533 0,2,3: SP <= SP + { {7{LoadSP[0]}}, LoadSP[1] }; 1534 1: SP <= X; 1535 endcase 1536 1537 // LoadT control 1538 case (LoadT) 1539 2: T <= DIN; 1540 3: T <= AluIntR; 1541 endcase 1542 1543 if (FlagCtrl) begin 1544 case(FlagsCtrl) 1545 0: P <= P; // No Op 1546 1: {P[0], P[1], P[6], P[7]} <= {CO, ZO, VO, SO}; // ALU 1547 2: P[2] <= 1; // BRK 1548 3: P[6] <= 0; // CLV 1549 4: {P[7:6],P[3:0]} <= {DIN[7:6], DIN[3:0]}; // RTI/PLP 1550 5: P[0] <= IR[5]; // CLC/SEC 1551 6: P[2] <= IR[5]; // CLI/SEI 1552 7: P[3] <= IR[5]; // CLD/SED 1553 endcase 1554 end 1555 1556 // Compute if the jump is to be taken. Result is stored in a flipflop, so 1557 // it won't be available until next cycle. 1558 // NOTE: Using DIN here. DIN is IR at cycle 0. This means JumpTaken will 1559 // contain the Jump status at cycle 1. 1560 case (DIN[7:5]) 1561 0: JumpTaken <= ~P[7]; // BPL 1562 1: JumpTaken <= P[7]; // BMI 1563 2: JumpTaken <= ~P[6]; // BVC 1564 3: JumpTaken <= P[6]; // BVS 1565 4: JumpTaken <= ~P[0]; // BCC 1566 5: JumpTaken <= P[0]; // BCS 1567 6: JumpTaken <= ~P[1]; // BNE 1568 7: JumpTaken <= P[1]; // BEQ 1569 endcase 1570 1571 // Check the interrupt status on the last cycle of the current instruction, 1572 // (or on cycle #1 of any branch instruction) 1573 if (StateCtrl == 2'b10) begin 1574 GotInterrupt <= (irq & ~P[2]) | nmi_active; 1575 IsResetInterrupt <= 0; 1576 end 1577 1578 IR <= NextIR; 1579 State <= NextState; 1580 end 1581end 1582endmodule 1583// Copyright (c) 2012-2013 Ludvig Strigeus 1584// This program is GPL Licensed. See COPYING for the full license. 1585 1586module LenCtr_Lookup(input [4:0] X, output [7:0] Yout); 1587reg [6:0] Y; 1588always @* 1589begin 1590 case(X) 1591 0: Y = 7'h05; 1592 1: Y = 7'h7F; 1593 2: Y = 7'h0A; 1594 3: Y = 7'h01; 1595 4: Y = 7'h14; 1596 5: Y = 7'h02; 1597 6: Y = 7'h28; 1598 7: Y = 7'h03; 1599 8: Y = 7'h50; 1600 9: Y = 7'h04; 1601 10: Y = 7'h1E; 1602 11: Y = 7'h05; 1603 12: Y = 7'h07; 1604 13: Y = 7'h06; 1605 14: Y = 7'h0D; 1606 15: Y = 7'h07; 1607 16: Y = 7'h06; 1608 17: Y = 7'h08; 1609 18: Y = 7'h0C; 1610 19: Y = 7'h09; 1611 20: Y = 7'h18; 1612 21: Y = 7'h0A; 1613 22: Y = 7'h30; 1614 23: Y = 7'h0B; 1615 24: Y = 7'h60; 1616 25: Y = 7'h0C; 1617 26: Y = 7'h24; 1618 27: Y = 7'h0D; 1619 28: Y = 7'h08; 1620 29: Y = 7'h0E; 1621 30: Y = 7'h10; 1622 31: Y = 7'h0F; 1623 endcase 1624end 1625assign Yout = {Y, 1'b0}; 1626endmodule 1627 1628module SquareChan(input clk, input ce, input reset, input sq2, 1629 input [1:0] Addr, 1630 input [7:0] DIN, 1631 input MW, 1632 input LenCtr_Clock, 1633 input Env_Clock, 1634 input Enabled, 1635 input [7:0] LenCtr_In, 1636 output reg [3:0] Sample, 1637 output IsNonZero); 1638reg [7:0] LenCtr; 1639 1640// Register 1 1641reg [1:0] Duty; 1642reg EnvLoop, EnvDisable, EnvDoReset; 1643reg [3:0] Volume, Envelope, EnvDivider; 1644wire LenCtrHalt = EnvLoop; // Aliased bit 1645assign IsNonZero = (LenCtr != 0); 1646// Register 2 1647reg SweepEnable, SweepNegate, SweepReset; 1648reg [2:0] SweepPeriod, SweepDivider, SweepShift; 1649 1650reg [10:0] Period; 1651reg [11:0] TimerCtr; 1652reg [2:0] SeqPos; 1653wire [10:0] ShiftedPeriod = (Period >> SweepShift); 1654wire [10:0] PeriodRhs = (SweepNegate ? (~ShiftedPeriod + {10'b0, sq2}) : ShiftedPeriod); 1655wire [11:0] NewSweepPeriod = Period + PeriodRhs; 1656wire ValidFreq = Period[10:3] >= 8 && (SweepNegate || !NewSweepPeriod[11]); 1657 1658always @(posedge clk) if (reset) begin 1659 LenCtr <= 0; 1660 Duty <= 0; 1661 EnvDoReset <= 0; 1662 EnvLoop <= 0; 1663 EnvDisable <= 0; 1664 Volume <= 0; 1665 Envelope <= 0; 1666 EnvDivider <= 0; 1667 SweepEnable <= 0; 1668 SweepNegate <= 0; 1669 SweepReset <= 0; 1670 SweepPeriod <= 0; 1671 SweepDivider <= 0; 1672 SweepShift <= 0; 1673 Period <= 0; 1674 TimerCtr <= 0; 1675 SeqPos <= 0; 1676 end else if (ce) begin 1677 // Check if writing to the regs of this channel 1678 // NOTE: This needs to be done before the clocking below. 1679 if (MW) begin 1680 case(Addr) 1681 0: begin 1682// if (sq2) $write("SQ0: Duty=%d, EnvLoop=%d, EnvDisable=%d, Volume=%d\n", DIN[7:6], DIN[5], DIN[4], DIN[3:0]); 1683 Duty <= DIN[7:6]; 1684 EnvLoop <= DIN[5]; 1685 EnvDisable <= DIN[4]; 1686 Volume <= DIN[3:0]; 1687 end 1688 1: begin 1689// if (sq2) $write("SQ1: SweepEnable=%d, SweepPeriod=%d, SweepNegate=%d, SweepShift=%d, DIN=%X\n", DIN[7], DIN[6:4], DIN[3], DIN[2:0], DIN); 1690 SweepEnable <= DIN[7]; 1691 SweepPeriod <= DIN[6:4]; 1692 SweepNegate <= DIN[3]; 1693 SweepShift <= DIN[2:0]; 1694 SweepReset <= 1; 1695 end 1696 2: begin 1697// if (sq2) $write("SQ2: Period=%d. DIN=%X\n", DIN, DIN); 1698 Period[7:0] <= DIN; 1699 end 1700 3: begin 1701 // Upper bits of the period 1702// if (sq2) $write("SQ3: PeriodUpper=%d LenCtr=%x DIN=%X\n", DIN[2:0], LenCtr_In, DIN); 1703 Period[10:8] <= DIN[2:0]; 1704 LenCtr <= LenCtr_In; 1705 EnvDoReset <= 1; 1706 SeqPos <= 0; 1707 end 1708 endcase 1709 end 1710 1711 1712 // Count down the square timer... 1713 if (TimerCtr == 0) begin 1714 // Timer was clocked 1715 TimerCtr <= {Period, 1'b0}; 1716 SeqPos <= SeqPos - 1; 1717 end else begin 1718 TimerCtr <= TimerCtr - 1; 1719 end 1720 1721 // Clock the length counter? 1722 if (LenCtr_Clock && LenCtr != 0 && !LenCtrHalt) begin 1723 LenCtr <= LenCtr - 1; 1724 end 1725 1726 // Clock the sweep unit? 1727 if (LenCtr_Clock) begin 1728 if (SweepDivider == 0) begin 1729 SweepDivider <= SweepPeriod; 1730 if (SweepEnable && SweepShift != 0 && ValidFreq) 1731 Period <= NewSweepPeriod[10:0]; 1732 end else begin 1733 SweepDivider <= SweepDivider - 1; 1734 end 1735 if (SweepReset) 1736 SweepDivider <= SweepPeriod; 1737 SweepReset <= 0; 1738 end 1739 1740 // Clock the envelope generator? 1741 if (Env_Clock) begin 1742 if (EnvDoReset) begin 1743 EnvDivider <= Volume; 1744 Envelope <= 15; 1745 EnvDoReset <= 0; 1746 end else if (EnvDivider == 0) begin 1747 EnvDivider <= Volume; 1748 if (Envelope != 0 || EnvLoop) 1749 Envelope <= Envelope - 1; 1750 end else begin 1751 EnvDivider <= EnvDivider - 1; 1752 end 1753 end 1754 1755 // Length counter forced to zero if disabled. 1756 if (!Enabled) 1757 LenCtr <= 0; 1758end 1759 1760reg DutyEnabled; 1761always @* begin 1762 // Determine if the duty is enabled or not 1763 case (Duty) 1764 0: DutyEnabled = (SeqPos == 7); 1765 1: DutyEnabled = (SeqPos >= 6); 1766 2: DutyEnabled = (SeqPos >= 4); 1767 3: DutyEnabled = (SeqPos < 6); 1768 endcase 1769 1770 // Compute the output 1771 if (LenCtr == 0 || !ValidFreq || !DutyEnabled) 1772 Sample = 0; 1773 else 1774 Sample = EnvDisable ? Volume : Envelope; 1775end 1776endmodule 1777 1778 1779 1780module TriangleChan(input clk, input ce, input reset, 1781 input [1:0] Addr, 1782 input [7:0] DIN, 1783 input MW, 1784 input LenCtr_Clock, 1785 input LinCtr_Clock, 1786 input Enabled, 1787 input [7:0] LenCtr_In, 1788 output [3:0] Sample, 1789 output IsNonZero); 1790 // 1791 reg [10:0] Period, TimerCtr; 1792 reg [4:0] SeqPos; 1793 // 1794 // Linear counter state 1795 reg [6:0] LinCtrPeriod, LinCtr; 1796 reg LinCtrl, LinHalt; 1797 wire LinCtrZero = (LinCtr == 0); 1798 // 1799 // Length counter state 1800 reg [7:0] LenCtr; 1801 wire LenCtrHalt = LinCtrl; // Aliased bit 1802 wire LenCtrZero = (LenCtr == 0); 1803 assign IsNonZero = !LenCtrZero; 1804 // 1805 always @(posedge clk) if (reset) begin 1806 Period <= 0; 1807 TimerCtr <= 0; 1808 SeqPos <= 0; 1809 LinCtrPeriod <= 0; 1810 LinCtr <= 0; 1811 LinCtrl <= 0; 1812 LinHalt <= 0; 1813 LenCtr <= 0; 1814 end else if (ce) begin 1815 // Check if writing to the regs of this channel 1816 if (MW) begin 1817 case (Addr) 1818 0: begin 1819 LinCtrl <= DIN[7]; 1820 LinCtrPeriod <= DIN[6:0]; 1821 end 1822 2: begin 1823 Period[7:0] <= DIN; 1824 end 1825 3: begin 1826 Period[10:8] <= DIN[2:0]; 1827 LenCtr <= LenCtr_In; 1828 LinHalt <= 1; 1829 end 1830 endcase 1831 end 1832 1833 // Count down the period timer... 1834 if (TimerCtr == 0) begin 1835 TimerCtr <= Period; 1836 end else begin 1837 TimerCtr <= TimerCtr - 1; 1838 end 1839 // 1840 // Clock the length counter? 1841 if (LenCtr_Clock && !LenCtrZero && !LenCtrHalt) begin 1842 LenCtr <= LenCtr - 1; 1843 end 1844 // 1845 // Clock the linear counter? 1846 if (LinCtr_Clock) begin 1847 if (LinHalt) 1848 LinCtr <= LinCtrPeriod; 1849 else if (!LinCtrZero) 1850 LinCtr <= LinCtr - 1; 1851 if (!LinCtrl) 1852 LinHalt <= 0; 1853 end 1854 // 1855 // Length counter forced to zero if disabled. 1856 if (!Enabled) 1857 LenCtr <= 0; 1858 // 1859 // Clock the sequencer position 1860 if (TimerCtr == 0 && !LenCtrZero && !LinCtrZero) 1861 SeqPos <= SeqPos + 1; 1862 end 1863 // Generate the output 1864 assign Sample = SeqPos[3:0] ^ {4{~SeqPos[4]}}; 1865 // 1866endmodule 1867 1868 1869module NoiseChan(input clk, input ce, input reset, 1870 input [1:0] Addr, 1871 input [7:0] DIN, 1872 input MW, 1873 input LenCtr_Clock, 1874 input Env_Clock, 1875 input Enabled, 1876 input [7:0] LenCtr_In, 1877 output [3:0] Sample, 1878 output IsNonZero); 1879 // 1880 // Envelope volume 1881 reg EnvLoop, EnvDisable, EnvDoReset; 1882 reg [3:0] Volume, Envelope, EnvDivider; 1883 // Length counter 1884 wire LenCtrHalt = EnvLoop; // Aliased bit 1885 reg [7:0] LenCtr; 1886 // 1887 reg ShortMode; 1888 reg [14:0] Shift = 1; 1889 1890 assign IsNonZero = (LenCtr != 0); 1891 // 1892 // Period stuff 1893 reg [3:0] Period; 1894 reg [11:0] NoisePeriod, TimerCtr; 1895 always @* begin 1896 case (Period) 1897 0: NoisePeriod = 12'h004; 1898 1: NoisePeriod = 12'h008; 1899 2: NoisePeriod = 12'h010; 1900 3: NoisePeriod = 12'h020; 1901 4: NoisePeriod = 12'h040; 1902 5: NoisePeriod = 12'h060; 1903 6: NoisePeriod = 12'h080; 1904 7: NoisePeriod = 12'h0A0; 1905 8: NoisePeriod = 12'h0CA; 1906 9: NoisePeriod = 12'h0FE; 1907 10: NoisePeriod = 12'h17C; 1908 11: NoisePeriod = 12'h1FC; 1909 12: NoisePeriod = 12'h2FA; 1910 13: NoisePeriod = 12'h3F8; 1911 14: NoisePeriod = 12'h7F2; 1912 15: NoisePeriod = 12'hFE4; 1913 endcase 1914 end 1915 // 1916 always @(posedge clk) if (reset) begin 1917 EnvLoop <= 0; 1918 EnvDisable <= 0; 1919 EnvDoReset <= 0; 1920 Volume <= 0; 1921 Envelope <= 0; 1922 EnvDivider <= 0; 1923 LenCtr <= 0; 1924 ShortMode <= 0; 1925 Shift <= 1; 1926 Period <= 0; 1927 TimerCtr <= 0; 1928 end else if (ce) begin 1929 // Check if writing to the regs of this channel 1930 if (MW) begin 1931 case (Addr) 1932 0: begin 1933 EnvLoop <= DIN[5]; 1934 EnvDisable <= DIN[4]; 1935 Volume <= DIN[3:0]; 1936 end 1937 2: begin 1938 ShortMode <= DIN[7]; 1939 Period <= DIN[3:0]; 1940 end 1941 3: begin 1942 LenCtr <= LenCtr_In; 1943 EnvDoReset <= 1; 1944 end 1945 endcase 1946 end 1947 // Count down the period timer... 1948 if (TimerCtr == 0) begin 1949 TimerCtr <= NoisePeriod; 1950 // Clock the shift register. Use either 1951 // bit 1 or 6 as the tap. 1952 Shift <= { 1953 Shift[0] ^ (ShortMode ? Shift[6] : Shift[1]), 1954 Shift[14:1]}; 1955 end else begin 1956 TimerCtr <= TimerCtr - 1; 1957 end 1958 // Clock the length counter? 1959 if (LenCtr_Clock && LenCtr != 0 && !LenCtrHalt) begin 1960 LenCtr <= LenCtr - 1; 1961 end 1962 // Clock the envelope generator? 1963 if (Env_Clock) begin 1964 if (EnvDoReset) begin 1965 EnvDivider <= Volume; 1966 Envelope <= 15; 1967 EnvDoReset <= 0; 1968 end else if (EnvDivider == 0) begin 1969 EnvDivider <= Volume; 1970 if (Envelope != 0) 1971 Envelope <= Envelope - 1; 1972 else if (EnvLoop) 1973 Envelope <= 15; 1974 end else 1975 EnvDivider <= EnvDivider - 1; 1976 end 1977 if (!Enabled) 1978 LenCtr <= 0; 1979 end 1980 // Produce the output signal 1981 assign Sample = 1982 (LenCtr == 0 || Shift[0]) ? 1983 0 : 1984 (EnvDisable ? Volume : Envelope); 1985endmodule 1986 1987module DmcChan(input clk, input ce, input reset, 1988 input odd_or_even, 1989 input [2:0] Addr, 1990 input [7:0] DIN, 1991 input MW, 1992 output [6:0] Sample, 1993 output DmaReq, // 1 when DMC wants DMA 1994 input DmaAck, // 1 when DMC byte is on DmcData. DmcDmaRequested should go low. 1995 output [15:0] DmaAddr, // Address DMC wants to read 1996 input [7:0] DmaData, // Input data to DMC from memory. 1997 output Irq, 1998 output IsDmcActive); 1999 reg IrqEnable; 2000 reg IrqActive; 2001 reg Loop; // Looping enabled 2002 reg [3:0] Freq; // Current value of frequency register 2003 reg [6:0] Dac = 0; // Current value of DAC 2004 reg [7:0] SampleAddress; // Base address of sample 2005 reg [7:0] SampleLen; // Length of sample 2006 reg [7:0] ShiftReg; // Shift register 2007 reg [8:0] Cycles; // Down counter, is the period 2008 reg [14:0] Address; // 15 bits current address, 0x8000-0xffff 2009 reg [11:0] BytesLeft; // 12 bits bytes left counter 0 - 4081. 2010 reg [2:0] BitsUsed; // Number of bits left in the SampleBuffer. 2011 reg [7:0] SampleBuffer; // Next value to be loaded into shift reg 2012 reg HasSampleBuffer; // Sample buffer is nonempty 2013 reg HasShiftReg; // Shift reg is non empty 2014 reg [8:0] NewPeriod[0:15]; 2015 reg DmcEnabled; 2016 reg [1:0] ActivationDelay; 2017 assign DmaAddr = {1'b1, Address}; 2018 assign Sample = Dac; 2019 assign Irq = IrqActive; 2020 assign IsDmcActive = DmcEnabled; 2021 2022 assign DmaReq = !HasSampleBuffer && DmcEnabled && !ActivationDelay[0]; 2023 2024 initial begin 2025 NewPeriod[0] = 428; 2026 NewPeriod[1] = 380; 2027 NewPeriod[2] = 340; 2028 NewPeriod[3] = 320; 2029 NewPeriod[4] = 286; 2030 NewPeriod[5] = 254; 2031 NewPeriod[6] = 226; 2032 NewPeriod[7] = 214; 2033 NewPeriod[8] = 190; 2034 NewPeriod[9] = 160; 2035 NewPeriod[10] = 142; 2036 NewPeriod[11] = 128; 2037 NewPeriod[12] = 106; 2038 NewPeriod[13] = 84; 2039 NewPeriod[14] = 72; 2040 NewPeriod[15] = 54; 2041 end 2042 // Shift register initially loaded with 07 2043 always @(posedge clk) begin 2044 if (reset) begin 2045 IrqEnable <= 0; 2046 IrqActive <= 0; 2047 Loop <= 0; 2048 Freq <= 0; 2049 Dac <= 0; 2050 SampleAddress <= 0; 2051 SampleLen <= 0; 2052 ShiftReg <= 8'hff; 2053 Cycles <= 439; 2054 Address <= 0; 2055 BytesLeft <= 0; 2056 BitsUsed <= 0; 2057 SampleBuffer <= 0; 2058 HasSampleBuffer <= 0; 2059 HasShiftReg <= 0; 2060 DmcEnabled <= 0; 2061 ActivationDelay <= 0; 2062 end else if (ce) begin 2063 if (ActivationDelay == 3 && !odd_or_even) ActivationDelay <= 1; 2064 if (ActivationDelay == 1) ActivationDelay <= 0; 2065 2066 if (MW) begin 2067 case (Addr) 2068 0: begin // $4010 il-- ffff IRQ enable, loop, frequency index 2069 IrqEnable <= DIN[7]; 2070 Loop <= DIN[6]; 2071 Freq <= DIN[3:0]; 2072 if (!DIN[7]) IrqActive <= 0; 2073 end 2074 1: begin // $4011 -ddd dddd DAC 2075 // This will get missed if the Dac <= far below runs, that is by design. 2076 Dac <= DIN[6:0]; 2077 end 2078 2: begin // $4012 aaaa aaaa sample address 2079 SampleAddress <= DIN[7:0]; 2080 end 2081 3: begin // $4013 llll llll sample length 2082 SampleLen <= DIN[7:0]; 2083 end 2084 5: begin // $4015 write ---D NT21 Enable DMC (D) 2085 IrqActive <= 0; 2086 DmcEnabled <= DIN[4]; 2087 // If the DMC bit is set, the DMC sample will be restarted only if not already active. 2088 if (DIN[4] && !DmcEnabled) begin 2089 Address <= {1'b1, SampleAddress, 6'b000000}; 2090 BytesLeft <= {SampleLen, 4'b0000}; 2091 ActivationDelay <= 3; 2092 end 2093 end 2094 endcase 2095 end 2096 2097 Cycles <= Cycles - 1; 2098 if (Cycles == 1) begin 2099 Cycles <= NewPeriod[Freq]; 2100 if (HasShiftReg) begin 2101 if (ShiftReg[0]) begin 2102 Dac[6:1] <= (Dac[6:1] != 6'b111111) ? Dac[6:1] + 6'b000001 : Dac[6:1]; 2103 end else begin 2104 Dac[6:1] <= (Dac[6:1] != 6'b000000) ? Dac[6:1] + 6'b111111 : Dac[6:1]; 2105 end 2106 end 2107 ShiftReg <= {1'b0, ShiftReg[7:1]}; 2108 BitsUsed <= BitsUsed + 1; 2109 if (BitsUsed == 7) begin 2110 HasShiftReg <= HasSampleBuffer; 2111 ShiftReg <= SampleBuffer; 2112 HasSampleBuffer <= 0; 2113 end 2114 end 2115 2116 // Acknowledge DMA? 2117 if (DmaAck) begin 2118 Address <= Address + 1; 2119 BytesLeft <= BytesLeft - 1; 2120 HasSampleBuffer <= 1; 2121 SampleBuffer <= DmaData; 2122 if (BytesLeft == 0) begin 2123 Address <= {1'b1, SampleAddress, 6'b000000}; 2124 BytesLeft <= {SampleLen, 4'b0000}; 2125 DmcEnabled <= Loop; 2126 if (!Loop && IrqEnable) 2127 IrqActive <= 1; 2128 end 2129 end 2130 end 2131 end 2132endmodule 2133 2134module ApuLookupTable(input clk, input [7:0] in_a, input [7:0] in_b, output [15:0] out); 2135 reg [15:0] lookup[0:511]; 2136 reg [15:0] tmp_a, tmp_b; 2137 initial begin 2138 lookup[ 0] = 0; lookup[ 1] = 760; lookup[ 2] = 1503; lookup[ 3] = 2228; 2139 lookup[ 4] = 2936; lookup[ 5] = 3627; lookup[ 6] = 4303; lookup[ 7] = 4963; 2140 lookup[ 8] = 5609; lookup[ 9] = 6240; lookup[ 10] = 6858; lookup[ 11] = 7462; 2141 lookup[ 12] = 8053; lookup[ 13] = 8631; lookup[ 14] = 9198; lookup[ 15] = 9752; 2142 lookup[ 16] = 10296; lookup[ 17] = 10828; lookup[ 18] = 11349; lookup[ 19] = 11860; 2143 lookup[ 20] = 12361; lookup[ 21] = 12852; lookup[ 22] = 13334; lookup[ 23] = 13807; 2144 lookup[ 24] = 14270; lookup[ 25] = 14725; lookup[ 26] = 15171; lookup[ 27] = 15609; 2145 lookup[ 28] = 16039; lookup[ 29] = 16461; lookup[ 30] = 16876; lookup[256] = 0; 2146 lookup[257] = 439; lookup[258] = 874; lookup[259] = 1306; lookup[260] = 1735; 2147 lookup[261] = 2160; lookup[262] = 2581; lookup[263] = 2999; lookup[264] = 3414; 2148 lookup[265] = 3826; lookup[266] = 4234; lookup[267] = 4639; lookup[268] = 5041; 2149 lookup[269] = 5440; lookup[270] = 5836; lookup[271] = 6229; lookup[272] = 6618; 2150 lookup[273] = 7005; lookup[274] = 7389; lookup[275] = 7769; lookup[276] = 8147; 2151 lookup[277] = 8522; lookup[278] = 8895; lookup[279] = 9264; lookup[280] = 9631; 2152 lookup[281] = 9995; lookup[282] = 10356; lookup[283] = 10714; lookup[284] = 11070; 2153 lookup[285] = 11423; lookup[286] = 11774; lookup[287] = 12122; lookup[288] = 12468; 2154 lookup[289] = 12811; lookup[290] = 13152; lookup[291] = 13490; lookup[292] = 13825; 2155 lookup[293] = 14159; lookup[294] = 14490; lookup[295] = 14818; lookup[296] = 15145; 2156 lookup[297] = 15469; lookup[298] = 15791; lookup[299] = 16110; lookup[300] = 16427; 2157 lookup[301] = 16742; lookup[302] = 17055; lookup[303] = 17366; lookup[304] = 17675; 2158 lookup[305] = 17981; lookup[306] = 18286; lookup[307] = 18588; lookup[308] = 18888; 2159 lookup[309] = 19187; lookup[310] = 19483; lookup[311] = 19777; lookup[312] = 20069; 2160 lookup[313] = 20360; lookup[314] = 20648; lookup[315] = 20935; lookup[316] = 21219; 2161 lookup[317] = 21502; lookup[318] = 21783; lookup[319] = 22062; lookup[320] = 22339; 2162 lookup[321] = 22615; lookup[322] = 22889; lookup[323] = 23160; lookup[324] = 23431; 2163 lookup[325] = 23699; lookup[326] = 23966; lookup[327] = 24231; lookup[328] = 24494; 2164 lookup[329] = 24756; lookup[330] = 25016; lookup[331] = 25274; lookup[332] = 25531; 2165 lookup[333] = 25786; lookup[334] = 26040; lookup[335] = 26292; lookup[336] = 26542; 2166 lookup[337] = 26791; lookup[338] = 27039; lookup[339] = 27284; lookup[340] = 27529; 2167 lookup[341] = 27772; lookup[342] = 28013; lookup[343] = 28253; lookup[344] = 28492; 2168 lookup[345] = 28729; lookup[346] = 28964; lookup[347] = 29198; lookup[348] = 29431; 2169 lookup[349] = 29663; lookup[350] = 29893; lookup[351] = 30121; lookup[352] = 30349; 2170 lookup[353] = 30575; lookup[354] = 30800; lookup[355] = 31023; lookup[356] = 31245; 2171 lookup[357] = 31466; lookup[358] = 31685; lookup[359] = 31904; lookup[360] = 32121; 2172 lookup[361] = 32336; lookup[362] = 32551; lookup[363] = 32764; lookup[364] = 32976; 2173 lookup[365] = 33187; lookup[366] = 33397; lookup[367] = 33605; lookup[368] = 33813; 2174 lookup[369] = 34019; lookup[370] = 34224; lookup[371] = 34428; lookup[372] = 34630; 2175 lookup[373] = 34832; lookup[374] = 35032; lookup[375] = 35232; lookup[376] = 35430; 2176 lookup[377] = 35627; lookup[378] = 35823; lookup[379] = 36018; lookup[380] = 36212; 2177 lookup[381] = 36405; lookup[382] = 36597; lookup[383] = 36788; lookup[384] = 36978; 2178 lookup[385] = 37166; lookup[386] = 37354; lookup[387] = 37541; lookup[388] = 37727; 2179 lookup[389] = 37912; lookup[390] = 38095; lookup[391] = 38278; lookup[392] = 38460; 2180 lookup[393] = 38641; lookup[394] = 38821; lookup[395] = 39000; lookup[396] = 39178; 2181 lookup[397] = 39355; lookup[398] = 39532; lookup[399] = 39707; lookup[400] = 39881; 2182 lookup[401] = 40055; lookup[402] = 40228; lookup[403] = 40399; lookup[404] = 40570; 2183 lookup[405] = 40740; lookup[406] = 40909; lookup[407] = 41078; lookup[408] = 41245; 2184 lookup[409] = 41412; lookup[410] = 41577; lookup[411] = 41742; lookup[412] = 41906; 2185 lookup[413] = 42070; lookup[414] = 42232; lookup[415] = 42394; lookup[416] = 42555; 2186 lookup[417] = 42715; lookup[418] = 42874; lookup[419] = 43032; lookup[420] = 43190; 2187 lookup[421] = 43347; lookup[422] = 43503; lookup[423] = 43659; lookup[424] = 43813; 2188 lookup[425] = 43967; lookup[426] = 44120; lookup[427] = 44273; lookup[428] = 44424; 2189 lookup[429] = 44575; lookup[430] = 44726; lookup[431] = 44875; lookup[432] = 45024; 2190 lookup[433] = 45172; lookup[434] = 45319; lookup[435] = 45466; lookup[436] = 45612; 2191 lookup[437] = 45757; lookup[438] = 45902; lookup[439] = 46046; lookup[440] = 46189; 2192 lookup[441] = 46332; lookup[442] = 46474; lookup[443] = 46615; lookup[444] = 46756; 2193 lookup[445] = 46895; lookup[446] = 47035; lookup[447] = 47173; lookup[448] = 47312; 2194 lookup[449] = 47449; lookup[450] = 47586; lookup[451] = 47722; lookup[452] = 47857; 2195 lookup[453] = 47992; lookup[454] = 48127; lookup[455] = 48260; lookup[456] = 48393; 2196 lookup[457] = 48526; lookup[458] = 48658; 2197 end 2198 always @(posedge clk) begin 2199 tmp_a <= lookup[{1'b0, in_a}]; 2200 tmp_b <= lookup[{1'b1, in_b}]; 2201 end 2202 assign out = tmp_a + tmp_b; 2203endmodule 2204 2205 2206module APU(input clk, input ce, input reset, 2207 input [4:0] ADDR, // APU Address Line 2208 input [7:0] DIN, // Data to APU 2209 output [7:0] DOUT, // Data from APU 2210 input MW, // Writes to APU 2211 input MR, // Reads from APU 2212 input [4:0] audio_channels, // Enabled audio channels 2213 output [15:0] Sample, 2214 2215 output DmaReq, // 1 when DMC wants DMA 2216 input DmaAck, // 1 when DMC byte is on DmcData. DmcDmaRequested should go low. 2217 output [15:0] DmaAddr, // Address DMC wants to read 2218 input [7:0] DmaData, // Input data to DMC from memory. 2219 2220 output odd_or_even, 2221 output IRQ); // IRQ asserted 2222 2223// Which channels are enabled? 2224reg [3:0] Enabled; 2225 2226// Output samples from the 4 channels 2227wire [3:0] Sq1Sample,Sq2Sample,TriSample,NoiSample; 2228 2229// Output samples from the DMC channel 2230wire [6:0] DmcSample; 2231wire DmcIrq; 2232wire IsDmcActive; 2233 2234// Generate internal memory write signals 2235wire ApuMW0 = MW && ADDR[4:2]==0; // SQ1 2236wire ApuMW1 = MW && ADDR[4:2]==1; // SQ2 2237wire ApuMW2 = MW && ADDR[4:2]==2; // TRI 2238wire ApuMW3 = MW && ADDR[4:2]==3; // NOI 2239wire ApuMW4 = MW && ADDR[4:2]>=4; // DMC 2240wire ApuMW5 = MW && ADDR[4:2]==5; // Control registers 2241 2242wire Sq1NonZero, Sq2NonZero, TriNonZero, NoiNonZero; 2243 2244// Common input to all channels 2245wire [7:0] LenCtr_In; 2246LenCtr_Lookup len(DIN[7:3], LenCtr_In); 2247 2248 2249// Frame sequencer registers 2250reg FrameSeqMode; 2251reg [15:0] Cycles; 2252reg ClkE, ClkL; 2253reg Wrote4017; 2254reg [1:0] IrqCtr; 2255reg InternalClock; // APU Differentiates between Even or Odd clocks 2256assign odd_or_even = InternalClock; 2257 2258 2259// Generate each channel 2260SquareChan Sq1(clk, ce, reset, 0, ADDR[1:0], DIN, ApuMW0, ClkL, ClkE, Enabled[0], LenCtr_In, Sq1Sample, Sq1NonZero); 2261SquareChan Sq2(clk, ce, reset, 1, ADDR[1:0], DIN, ApuMW1, ClkL, ClkE, Enabled[1], LenCtr_In, Sq2Sample, Sq2NonZero); 2262TriangleChan Tri(clk, ce, reset, ADDR[1:0], DIN, ApuMW2, ClkL, ClkE, Enabled[2], LenCtr_In, TriSample, TriNonZero); 2263NoiseChan Noi(clk, ce, reset, ADDR[1:0], DIN, ApuMW3, ClkL, ClkE, Enabled[3], LenCtr_In, NoiSample, NoiNonZero); 2264DmcChan Dmc(clk, ce, reset, odd_or_even, ADDR[2:0], DIN, ApuMW4, DmcSample, DmaReq, DmaAck, DmaAddr, DmaData, DmcIrq, IsDmcActive); 2265 2266// Reading this register clears the frame interrupt flag (but not the DMC interrupt flag). 2267// If an interrupt flag was set at the same moment of the read, it will read back as 1 but it will not be cleared. 2268reg FrameInterrupt, DisableFrameInterrupt; 2269 2270 2271//mode 0: 4-step effective rate (approx) 2272//--------------------------------------- 2273// - - - f 60 Hz 2274// - l - l 120 Hz 2275// e e e e 240 Hz 2276 2277 2278//mode 1: 5-step effective rate (approx) 2279//--------------------------------------- 2280// - - - - - (interrupt flag never set) 2281// l - l - - 96 Hz 2282// e e e e - 192 Hz 2283 2284 2285always @(posedge clk) if (reset) begin 2286 FrameSeqMode <= 0; 2287 DisableFrameInterrupt <= 0; 2288 FrameInterrupt <= 0; 2289 Enabled <= 0; 2290 InternalClock <= 0; 2291 Wrote4017 <= 0; 2292 ClkE <= 0; 2293 ClkL <= 0; 2294 Cycles <= 4; // This needs to be 5 for proper power up behavior 2295 IrqCtr <= 0; 2296end else if (ce) begin 2297 FrameInterrupt <= IrqCtr[1] ? 1 : (ADDR == 5'h15 && MR || ApuMW5 && ADDR[1:0] == 3 && DIN[6]) ? 0 : FrameInterrupt; 2298 InternalClock <= !InternalClock; 2299 IrqCtr <= {IrqCtr[0], 1'b0}; 2300 Cycles <= Cycles + 1; 2301 ClkE <= 0; 2302 ClkL <= 0; 2303 if (Cycles == 7457) begin 2304 ClkE <= 1; 2305 end else if (Cycles == 14913) begin 2306 ClkE <= 1; 2307 ClkL <= 1; 2308 ClkE <= 1; 2309 ClkL <= 1; 2310 end else if (Cycles == 22371) begin 2311 ClkE <= 1; 2312 end else if (Cycles == 29829) begin 2313 if (!FrameSeqMode) begin 2314 ClkE <= 1; 2315 ClkL <= 1; 2316 Cycles <= 0; 2317 IrqCtr <= 3; 2318 FrameInterrupt <= 1; 2319 end 2320 end else if (Cycles == 37281) begin 2321 ClkE <= 1; 2322 ClkL <= 1; 2323 Cycles <= 0; 2324 end 2325 2326 // Handle one cycle delayed write to 4017. 2327 Wrote4017 <= 0; 2328 if (Wrote4017) begin 2329 if (FrameSeqMode) begin 2330 ClkE <= 1; 2331 ClkL <= 1; 2332 end 2333 Cycles <= 0; 2334 end 2335 2336// if (ClkE||ClkL) $write("%d: Clocking %s%s\n", Cycles, ClkE?"E":" ", ClkL?"L":" "); 2337 2338 // Handle writes to control registers 2339 if (ApuMW5) begin 2340 case (ADDR[1:0]) 2341 1: begin // Register $4015 2342 Enabled <= DIN[3:0]; 2343// $write("$4015 = %X\n", DIN); 2344 end 2345 3: begin // Register $4017 2346 FrameSeqMode <= DIN[7]; // 1 = 5 frames cycle, 0 = 4 frames cycle 2347 DisableFrameInterrupt <= DIN[6]; 2348 2349 // If the internal clock is even, things happen 2350 // right away. 2351 if (!InternalClock) begin 2352 if (DIN[7]) begin 2353 ClkE <= 1; 2354 ClkL <= 1; 2355 end 2356 Cycles <= 0; 2357 end 2358 2359 // Otherwise they get delayed one clock 2360 Wrote4017 <= InternalClock; 2361 end 2362 endcase 2363 end 2364 2365 2366end 2367 2368ApuLookupTable lookup(clk, 2369 (audio_channels[0] ? {4'b0, Sq1Sample} : 8'b0) + 2370 (audio_channels[1] ? {4'b0, Sq2Sample} : 8'b0), 2371 (audio_channels[2] ? {4'b0, TriSample} + {3'b0, TriSample, 1'b0} : 8'b0) + 2372 (audio_channels[3] ? {3'b0, NoiSample, 1'b0} : 8'b0) + 2373 (audio_channels[4] ? {1'b0, DmcSample} : 8'b0), 2374 Sample); 2375 2376wire frame_irq = FrameInterrupt && !DisableFrameInterrupt; 2377 2378// Generate bus output 2379assign DOUT = {DmcIrq, frame_irq, 1'b0, 2380 IsDmcActive, 2381 NoiNonZero, 2382 TriNonZero, 2383 Sq2NonZero, 2384 Sq1NonZero}; 2385 2386assign IRQ = frame_irq || DmcIrq; 2387 2388endmodule 2389// Copyright (c) 2012-2013 Ludvig Strigeus 2390// This program is GPL Licensed. See COPYING for the full license. 2391module MUXCY(output O, input CI, input DI, input S); 2392 assign O = S ? CI : DI; 2393endmodule 2394module MUXCY_L(output LO, input CI, input DI, input S); 2395 assign LO = S ? CI : DI; 2396endmodule 2397module MUXCY_D(output LO, output O, input CI, input DI, input S); 2398 assign LO = S ? CI : DI; 2399 assign O = LO; 2400endmodule 2401module XORCY(output O, input CI, input LI); 2402 assign O = CI ^ LI; 2403endmodule 2404module XOR2_nes(output O, input I0, input I1); 2405 assign O = I0 ^ I1; 2406endmodule// Simple, platform-agnostic single-ported RAM 2407 2408module generic_ram(clock, reset, address, wren, write_data, read_data); 2409 2410parameter integer WIDTH = 8; 2411parameter integer WORDS = 2048; 2412localparam ADDR_BITS = $clog2(WORDS-1); 2413 2414input clock; 2415input reset; 2416input [ADDR_BITS-1:0] address; 2417input wren; 2418input [WIDTH-1:0] write_data; 2419output reg [WIDTH-1:0] read_data; 2420 2421reg [WIDTH-1:0] mem[0:WORDS-1]; 2422 2423reg [ADDR_BITS-1:0] a_prereg; 2424reg [WIDTH-1:0] d_prereg; 2425reg wren_prereg; 2426 2427always @(posedge clock) begin 2428 if (reset == 1'b1) begin 2429 wren_prereg <= 0; 2430 a_prereg <= 0; 2431 d_prereg <= 0; 2432 end else begin 2433 wren_prereg <= wren; 2434 a_prereg <= address; 2435 d_prereg <= write_data; 2436 end 2437 2438 2439 read_data <= mem[a_prereg]; 2440 if (wren_prereg) mem[a_prereg] <= d_prereg; 2441end 2442 2443endmodule// SPI flash memory interface, taken from the icosoc project 2444 2445module icosoc_flashmem ( 2446 input clk, reset, 2447 2448 input valid, 2449 output reg ready, 2450 input [23:0] addr, 2451 output reg [31:0] rdata, 2452 2453 output reg spi_cs, 2454 output reg spi_sclk, 2455 output reg spi_mosi, 2456 input spi_miso 2457); 2458 reg [7:0] buffer; 2459 reg [3:0] xfer_cnt; 2460 reg [3:0] state; 2461 2462 always @(posedge clk) begin 2463 ready <= 0; 2464 if (reset || !valid || ready) begin 2465 spi_cs <= 1; 2466 spi_sclk <= 1; 2467 xfer_cnt <= 0; 2468 state <= 0; 2469 end else begin 2470 spi_cs <= 0; 2471 if (xfer_cnt) begin 2472 if (spi_sclk) begin 2473 spi_sclk <= 0; 2474 spi_mosi <= buffer[7]; 2475 end else begin 2476 spi_sclk <= 1; 2477 buffer <= {buffer, spi_miso}; 2478 xfer_cnt <= xfer_cnt - 1; 2479 end 2480 end else 2481 case (state) 2482 0: begin 2483 buffer <= 'h03; 2484 xfer_cnt <= 8; 2485 state <= 1; 2486 end 2487 1: begin 2488 buffer <= addr[23:16]; 2489 xfer_cnt <= 8; 2490 state <= 2; 2491 end 2492 2: begin 2493 buffer <= addr[15:8]; 2494 xfer_cnt <= 8; 2495 state <= 3; 2496 end 2497 3: begin 2498 buffer <= addr[7:0]; 2499 xfer_cnt <= 8; 2500 state <= 4; 2501 end 2502 4: begin 2503 xfer_cnt <= 8; 2504 state <= 5; 2505 end 2506 5: begin 2507 rdata[7:0] <= buffer; 2508 xfer_cnt <= 8; 2509 state <= 6; 2510 end 2511 6: begin 2512 rdata[15:8] <= buffer; 2513 xfer_cnt <= 8; 2514 state <= 7; 2515 end 2516 7: begin 2517 rdata[23:16] <= buffer; 2518 xfer_cnt <= 8; 2519 state <= 8; 2520 end 2521 8: begin 2522 rdata[31:24] <= buffer; 2523 ready <= 1; 2524 end 2525 endcase 2526 end 2527 end 2528endmodule 2529module MicroCodeTableInner(input clk, input ce, input reset, input [7:0] IR, input [2:0] State, output reg [8:0] M); 2530 reg [8:0] L[0:2047]; 2531 initial begin 2532L[0] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2533L[1] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2534L[2] = 9'b00_10_10100; // ['PCH->[SP--]', 'PCL->[SP--],', 'PCH->[SP--](KEEPAC)', 'PCL->[SP--](KEEPAC)'] 2535L[3] = 9'b00_10_10100; // ['PCH->[SP--]', 'PCL->[SP--],', 'PCH->[SP--](KEEPAC)', 'PCL->[SP--](KEEPAC)'] 2536L[4] = 9'b00_10_10101; // P->[SP--] 2537L[5] = 9'b00_11_00011; // [VECT]->T 2538L[6] = 9'b10_11_10011; // [VECT]:T->PC 2539L[7] = 9'bxx_xx_xxxxx; // [] 2540L[8] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2541L[9] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2542L[10] = 9'b00_01_00111; // [AX]->?,AL+X->AL 2543L[11] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2544L[12] = 9'b00_01_01011; // [AX]->AH,T->AL 2545L[13] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2546L[14] = 9'bxx_xx_xxxxx; // [] 2547L[15] = 9'bxx_xx_xxxxx; // [] 2548L[16] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2549L[17] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 2550L[18] = 9'bxx_xx_xxxxx; // [] 2551L[19] = 9'bxx_xx_xxxxx; // [] 2552L[20] = 9'bxx_xx_xxxxx; // [] 2553L[21] = 9'bxx_xx_xxxxx; // [] 2554L[22] = 9'bxx_xx_xxxxx; // [] 2555L[23] = 9'bxx_xx_xxxxx; // [] 2556L[24] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2557L[25] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2558L[26] = 9'b00_01_00111; // [AX]->?,AL+X->AL 2559L[27] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2560L[28] = 9'b00_01_01011; // [AX]->AH,T->AL 2561L[29] = 9'b00_01_00011; // [AX]->T 2562L[30] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2563L[31] = 9'b10_01_00101; // T->[AX] 2564L[32] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2565L[33] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2566L[34] = 9'bxx_xx_xxxxx; // [] 2567L[35] = 9'bxx_xx_xxxxx; // [] 2568L[36] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 2569L[37] = 9'bxx_xx_xxxxx; // [] 2570L[38] = 9'bxx_xx_xxxxx; // [] 2571L[39] = 9'bxx_xx_xxxxx; // [] 2572L[40] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2573L[41] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2574L[42] = 9'bxx_xx_xxxxx; // [] 2575L[43] = 9'bxx_xx_xxxxx; // [] 2576L[44] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2577L[45] = 9'bxx_xx_xxxxx; // [] 2578L[46] = 9'bxx_xx_xxxxx; // [] 2579L[47] = 9'bxx_xx_xxxxx; // [] 2580L[48] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2581L[49] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2582L[50] = 9'bxx_xx_xxxxx; // [] 2583L[51] = 9'bxx_xx_xxxxx; // [] 2584L[52] = 9'b00_01_00011; // [AX]->T 2585L[53] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2586L[54] = 9'b10_01_00101; // T->[AX] 2587L[55] = 9'bxx_xx_xxxxx; // [] 2588L[56] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2589L[57] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2590L[58] = 9'bxx_xx_xxxxx; // [] 2591L[59] = 9'bxx_xx_xxxxx; // [] 2592L[60] = 9'b00_01_00011; // [AX]->T 2593L[61] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2594L[62] = 9'b10_01_00101; // T->[AX] 2595L[63] = 9'bxx_xx_xxxxx; // [] 2596L[64] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2597L[65] = 9'b00_00_00011; // [PC]-> 2598L[66] = 9'b10_10_01111; // P->[SP--] 2599L[67] = 9'bxx_xx_xxxxx; // [] 2600L[68] = 9'bxx_xx_xxxxx; // [] 2601L[69] = 9'bxx_xx_xxxxx; // [] 2602L[70] = 9'bxx_xx_xxxxx; // [] 2603L[71] = 9'bxx_xx_xxxxx; // [] 2604L[72] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2605L[73] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 2606L[74] = 9'bxx_xx_xxxxx; // [] 2607L[75] = 9'bxx_xx_xxxxx; // [] 2608L[76] = 9'bxx_xx_xxxxx; // [] 2609L[77] = 9'bxx_xx_xxxxx; // [] 2610L[78] = 9'bxx_xx_xxxxx; // [] 2611L[79] = 9'bxx_xx_xxxxx; // [] 2612L[80] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2613L[81] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 2614L[82] = 9'bxx_xx_xxxxx; // [] 2615L[83] = 9'bxx_xx_xxxxx; // [] 2616L[84] = 9'bxx_xx_xxxxx; // [] 2617L[85] = 9'bxx_xx_xxxxx; // [] 2618L[86] = 9'bxx_xx_xxxxx; // [] 2619L[87] = 9'bxx_xx_xxxxx; // [] 2620L[88] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2621L[89] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 2622L[90] = 9'bxx_xx_xxxxx; // [] 2623L[91] = 9'bxx_xx_xxxxx; // [] 2624L[92] = 9'bxx_xx_xxxxx; // [] 2625L[93] = 9'bxx_xx_xxxxx; // [] 2626L[94] = 9'bxx_xx_xxxxx; // [] 2627L[95] = 9'bxx_xx_xxxxx; // [] 2628L[96] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2629L[97] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2630L[98] = 9'b11_00_00001; // [PC++]->AH 2631L[99] = 9'bxx_xx_xxxxx; // [] 2632L[100] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 2633L[101] = 9'bxx_xx_xxxxx; // [] 2634L[102] = 9'bxx_xx_xxxxx; // [] 2635L[103] = 9'bxx_xx_xxxxx; // [] 2636L[104] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2637L[105] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2638L[106] = 9'b11_00_00001; // [PC++]->AH 2639L[107] = 9'bxx_xx_xxxxx; // [] 2640L[108] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2641L[109] = 9'bxx_xx_xxxxx; // [] 2642L[110] = 9'bxx_xx_xxxxx; // [] 2643L[111] = 9'bxx_xx_xxxxx; // [] 2644L[112] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2645L[113] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2646L[114] = 9'b11_00_00001; // [PC++]->AH 2647L[115] = 9'bxx_xx_xxxxx; // [] 2648L[116] = 9'b00_01_00011; // [AX]->T 2649L[117] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2650L[118] = 9'b10_01_00101; // T->[AX] 2651L[119] = 9'bxx_xx_xxxxx; // [] 2652L[120] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2653L[121] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2654L[122] = 9'b11_00_00001; // [PC++]->AH 2655L[123] = 9'bxx_xx_xxxxx; // [] 2656L[124] = 9'b00_01_00011; // [AX]->T 2657L[125] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2658L[126] = 9'b10_01_00101; // T->[AX] 2659L[127] = 9'bxx_xx_xxxxx; // [] 2660L[128] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2661L[129] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 2662L[130] = 9'b11_00_10001; // PC+T->PC 2663L[131] = 9'bxx_xx_xxxxx; // [] 2664L[132] = 9'b10_00_00011; // ['NO-OP', ''] 2665L[133] = 9'bxx_xx_xxxxx; // [] 2666L[134] = 9'bxx_xx_xxxxx; // [] 2667L[135] = 9'bxx_xx_xxxxx; // [] 2668L[136] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2669L[137] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2670L[138] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2671L[139] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 2672L[140] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2673L[141] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2674L[142] = 9'bxx_xx_xxxxx; // [] 2675L[143] = 9'bxx_xx_xxxxx; // [] 2676L[144] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2677L[145] = 9'b10_00_00011; // ['NO-OP', ''] 2678L[146] = 9'bxx_xx_xxxxx; // [] 2679L[147] = 9'bxx_xx_xxxxx; // [] 2680L[148] = 9'bxx_xx_xxxxx; // [] 2681L[149] = 9'bxx_xx_xxxxx; // [] 2682L[150] = 9'bxx_xx_xxxxx; // [] 2683L[151] = 9'bxx_xx_xxxxx; // [] 2684L[152] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2685L[153] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2686L[154] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2687L[155] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 2688L[156] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2689L[157] = 9'b00_01_00011; // [AX]->T 2690L[158] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2691L[159] = 9'b10_01_00101; // T->[AX] 2692L[160] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2693L[161] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2694L[162] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2695L[163] = 9'bxx_xx_xxxxx; // [] 2696L[164] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 2697L[165] = 9'bxx_xx_xxxxx; // [] 2698L[166] = 9'bxx_xx_xxxxx; // [] 2699L[167] = 9'bxx_xx_xxxxx; // [] 2700L[168] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2701L[169] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2702L[170] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2703L[171] = 9'bxx_xx_xxxxx; // [] 2704L[172] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2705L[173] = 9'bxx_xx_xxxxx; // [] 2706L[174] = 9'bxx_xx_xxxxx; // [] 2707L[175] = 9'bxx_xx_xxxxx; // [] 2708L[176] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2709L[177] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2710L[178] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2711L[179] = 9'bxx_xx_xxxxx; // [] 2712L[180] = 9'b00_01_00011; // [AX]->T 2713L[181] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2714L[182] = 9'b10_01_00101; // T->[AX] 2715L[183] = 9'bxx_xx_xxxxx; // [] 2716L[184] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2717L[185] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2718L[186] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2719L[187] = 9'bxx_xx_xxxxx; // [] 2720L[188] = 9'b00_01_00011; // [AX]->T 2721L[189] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2722L[190] = 9'b10_01_00101; // T->[AX] 2723L[191] = 9'bxx_xx_xxxxx; // [] 2724L[192] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2725L[193] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 2726L[194] = 9'bxx_xx_xxxxx; // [] 2727L[195] = 9'bxx_xx_xxxxx; // [] 2728L[196] = 9'bxx_xx_xxxxx; // [] 2729L[197] = 9'bxx_xx_xxxxx; // [] 2730L[198] = 9'bxx_xx_xxxxx; // [] 2731L[199] = 9'bxx_xx_xxxxx; // [] 2732L[200] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2733L[201] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2734L[202] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2735L[203] = 9'bxx_xx_xxxxx; // [] 2736L[204] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2737L[205] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2738L[206] = 9'bxx_xx_xxxxx; // [] 2739L[207] = 9'bxx_xx_xxxxx; // [] 2740L[208] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2741L[209] = 9'b10_00_00011; // ['NO-OP', ''] 2742L[210] = 9'bxx_xx_xxxxx; // [] 2743L[211] = 9'bxx_xx_xxxxx; // [] 2744L[212] = 9'bxx_xx_xxxxx; // [] 2745L[213] = 9'bxx_xx_xxxxx; // [] 2746L[214] = 9'bxx_xx_xxxxx; // [] 2747L[215] = 9'bxx_xx_xxxxx; // [] 2748L[216] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2749L[217] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2750L[218] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2751L[219] = 9'bxx_xx_xxxxx; // [] 2752L[220] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2753L[221] = 9'b00_01_00011; // [AX]->T 2754L[222] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2755L[223] = 9'b10_01_00101; // T->[AX] 2756L[224] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2757L[225] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2758L[226] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2759L[227] = 9'bxx_xx_xxxxx; // [] 2760L[228] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2761L[229] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 2762L[230] = 9'bxx_xx_xxxxx; // [] 2763L[231] = 9'bxx_xx_xxxxx; // [] 2764L[232] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2765L[233] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2766L[234] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2767L[235] = 9'bxx_xx_xxxxx; // [] 2768L[236] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2769L[237] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2770L[238] = 9'bxx_xx_xxxxx; // [] 2771L[239] = 9'bxx_xx_xxxxx; // [] 2772L[240] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2773L[241] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2774L[242] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2775L[243] = 9'bxx_xx_xxxxx; // [] 2776L[244] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2777L[245] = 9'b00_01_00011; // [AX]->T 2778L[246] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2779L[247] = 9'b10_01_00101; // T->[AX] 2780L[248] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2781L[249] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2782L[250] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2783L[251] = 9'bxx_xx_xxxxx; // [] 2784L[252] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2785L[253] = 9'b00_01_00011; // [AX]->T 2786L[254] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2787L[255] = 9'b10_01_00101; // T->[AX] 2788L[256] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2789L[257] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2790L[258] = 9'b00_10_10100; // ['PCH->[SP--]', 'PCL->[SP--],', 'PCH->[SP--](KEEPAC)', 'PCL->[SP--](KEEPAC)'] 2791L[259] = 9'b00_10_10100; // ['PCH->[SP--]', 'PCL->[SP--],', 'PCH->[SP--](KEEPAC)', 'PCL->[SP--](KEEPAC)'] 2792L[260] = 9'b00_10_00111; // KEEP_AC 2793L[261] = 9'b10_00_10011; // [PC]:T->PC 2794L[262] = 9'bxx_xx_xxxxx; // [] 2795L[263] = 9'bxx_xx_xxxxx; // [] 2796L[264] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2797L[265] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2798L[266] = 9'b00_01_00111; // [AX]->?,AL+X->AL 2799L[267] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2800L[268] = 9'b00_01_01011; // [AX]->AH,T->AL 2801L[269] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2802L[270] = 9'bxx_xx_xxxxx; // [] 2803L[271] = 9'bxx_xx_xxxxx; // [] 2804L[272] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2805L[273] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 2806L[274] = 9'bxx_xx_xxxxx; // [] 2807L[275] = 9'bxx_xx_xxxxx; // [] 2808L[276] = 9'bxx_xx_xxxxx; // [] 2809L[277] = 9'bxx_xx_xxxxx; // [] 2810L[278] = 9'bxx_xx_xxxxx; // [] 2811L[279] = 9'bxx_xx_xxxxx; // [] 2812L[280] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2813L[281] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2814L[282] = 9'b00_01_00111; // [AX]->?,AL+X->AL 2815L[283] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2816L[284] = 9'b00_01_01011; // [AX]->AH,T->AL 2817L[285] = 9'b00_01_00011; // [AX]->T 2818L[286] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2819L[287] = 9'b10_01_00101; // T->[AX] 2820L[288] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2821L[289] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2822L[290] = 9'bxx_xx_xxxxx; // [] 2823L[291] = 9'bxx_xx_xxxxx; // [] 2824L[292] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2825L[293] = 9'bxx_xx_xxxxx; // [] 2826L[294] = 9'bxx_xx_xxxxx; // [] 2827L[295] = 9'bxx_xx_xxxxx; // [] 2828L[296] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2829L[297] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2830L[298] = 9'bxx_xx_xxxxx; // [] 2831L[299] = 9'bxx_xx_xxxxx; // [] 2832L[300] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2833L[301] = 9'bxx_xx_xxxxx; // [] 2834L[302] = 9'bxx_xx_xxxxx; // [] 2835L[303] = 9'bxx_xx_xxxxx; // [] 2836L[304] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2837L[305] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2838L[306] = 9'bxx_xx_xxxxx; // [] 2839L[307] = 9'bxx_xx_xxxxx; // [] 2840L[308] = 9'b00_01_00011; // [AX]->T 2841L[309] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2842L[310] = 9'b10_01_00101; // T->[AX] 2843L[311] = 9'bxx_xx_xxxxx; // [] 2844L[312] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2845L[313] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 2846L[314] = 9'bxx_xx_xxxxx; // [] 2847L[315] = 9'bxx_xx_xxxxx; // [] 2848L[316] = 9'b00_01_00011; // [AX]->T 2849L[317] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2850L[318] = 9'b10_01_00101; // T->[AX] 2851L[319] = 9'bxx_xx_xxxxx; // [] 2852L[320] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2853L[321] = 9'b00_00_00011; // [PC]-> 2854L[322] = 9'b00_10_10000; // ['SP++', 'SP+1->SP', '[SP]->T,SP+1->SP'] 2855L[323] = 9'b10_10_00010; // ['ALU([SP])->A', '[SP]->P'] 2856L[324] = 9'bxx_xx_xxxxx; // [] 2857L[325] = 9'bxx_xx_xxxxx; // [] 2858L[326] = 9'bxx_xx_xxxxx; // [] 2859L[327] = 9'bxx_xx_xxxxx; // [] 2860L[328] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2861L[329] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 2862L[330] = 9'bxx_xx_xxxxx; // [] 2863L[331] = 9'bxx_xx_xxxxx; // [] 2864L[332] = 9'bxx_xx_xxxxx; // [] 2865L[333] = 9'bxx_xx_xxxxx; // [] 2866L[334] = 9'bxx_xx_xxxxx; // [] 2867L[335] = 9'bxx_xx_xxxxx; // [] 2868L[336] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2869L[337] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 2870L[338] = 9'bxx_xx_xxxxx; // [] 2871L[339] = 9'bxx_xx_xxxxx; // [] 2872L[340] = 9'bxx_xx_xxxxx; // [] 2873L[341] = 9'bxx_xx_xxxxx; // [] 2874L[342] = 9'bxx_xx_xxxxx; // [] 2875L[343] = 9'bxx_xx_xxxxx; // [] 2876L[344] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2877L[345] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 2878L[346] = 9'bxx_xx_xxxxx; // [] 2879L[347] = 9'bxx_xx_xxxxx; // [] 2880L[348] = 9'bxx_xx_xxxxx; // [] 2881L[349] = 9'bxx_xx_xxxxx; // [] 2882L[350] = 9'bxx_xx_xxxxx; // [] 2883L[351] = 9'bxx_xx_xxxxx; // [] 2884L[352] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2885L[353] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2886L[354] = 9'b11_00_00001; // [PC++]->AH 2887L[355] = 9'bxx_xx_xxxxx; // [] 2888L[356] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2889L[357] = 9'bxx_xx_xxxxx; // [] 2890L[358] = 9'bxx_xx_xxxxx; // [] 2891L[359] = 9'bxx_xx_xxxxx; // [] 2892L[360] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2893L[361] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2894L[362] = 9'b11_00_00001; // [PC++]->AH 2895L[363] = 9'bxx_xx_xxxxx; // [] 2896L[364] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2897L[365] = 9'bxx_xx_xxxxx; // [] 2898L[366] = 9'bxx_xx_xxxxx; // [] 2899L[367] = 9'bxx_xx_xxxxx; // [] 2900L[368] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2901L[369] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2902L[370] = 9'b11_00_00001; // [PC++]->AH 2903L[371] = 9'bxx_xx_xxxxx; // [] 2904L[372] = 9'b00_01_00011; // [AX]->T 2905L[373] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2906L[374] = 9'b10_01_00101; // T->[AX] 2907L[375] = 9'bxx_xx_xxxxx; // [] 2908L[376] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2909L[377] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2910L[378] = 9'b11_00_00001; // [PC++]->AH 2911L[379] = 9'bxx_xx_xxxxx; // [] 2912L[380] = 9'b00_01_00011; // [AX]->T 2913L[381] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2914L[382] = 9'b10_01_00101; // T->[AX] 2915L[383] = 9'bxx_xx_xxxxx; // [] 2916L[384] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2917L[385] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 2918L[386] = 9'b11_00_10001; // PC+T->PC 2919L[387] = 9'bxx_xx_xxxxx; // [] 2920L[388] = 9'b10_00_00011; // ['NO-OP', ''] 2921L[389] = 9'bxx_xx_xxxxx; // [] 2922L[390] = 9'bxx_xx_xxxxx; // [] 2923L[391] = 9'bxx_xx_xxxxx; // [] 2924L[392] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2925L[393] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2926L[394] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2927L[395] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 2928L[396] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2929L[397] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2930L[398] = 9'bxx_xx_xxxxx; // [] 2931L[399] = 9'bxx_xx_xxxxx; // [] 2932L[400] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2933L[401] = 9'b10_00_00011; // ['NO-OP', ''] 2934L[402] = 9'bxx_xx_xxxxx; // [] 2935L[403] = 9'bxx_xx_xxxxx; // [] 2936L[404] = 9'bxx_xx_xxxxx; // [] 2937L[405] = 9'bxx_xx_xxxxx; // [] 2938L[406] = 9'bxx_xx_xxxxx; // [] 2939L[407] = 9'bxx_xx_xxxxx; // [] 2940L[408] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2941L[409] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2942L[410] = 9'b00_01_01010; // [AX]->T,AL+1->AL 2943L[411] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 2944L[412] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2945L[413] = 9'b00_01_00011; // [AX]->T 2946L[414] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2947L[415] = 9'b10_01_00101; // T->[AX] 2948L[416] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2949L[417] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2950L[418] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2951L[419] = 9'bxx_xx_xxxxx; // [] 2952L[420] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 2953L[421] = 9'bxx_xx_xxxxx; // [] 2954L[422] = 9'bxx_xx_xxxxx; // [] 2955L[423] = 9'bxx_xx_xxxxx; // [] 2956L[424] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2957L[425] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2958L[426] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2959L[427] = 9'bxx_xx_xxxxx; // [] 2960L[428] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2961L[429] = 9'bxx_xx_xxxxx; // [] 2962L[430] = 9'bxx_xx_xxxxx; // [] 2963L[431] = 9'bxx_xx_xxxxx; // [] 2964L[432] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2965L[433] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2966L[434] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2967L[435] = 9'bxx_xx_xxxxx; // [] 2968L[436] = 9'b00_01_00011; // [AX]->T 2969L[437] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2970L[438] = 9'b10_01_00101; // T->[AX] 2971L[439] = 9'bxx_xx_xxxxx; // [] 2972L[440] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2973L[441] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2974L[442] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 2975L[443] = 9'bxx_xx_xxxxx; // [] 2976L[444] = 9'b00_01_00011; // [AX]->T 2977L[445] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 2978L[446] = 9'b10_01_00101; // T->[AX] 2979L[447] = 9'bxx_xx_xxxxx; // [] 2980L[448] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2981L[449] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 2982L[450] = 9'bxx_xx_xxxxx; // [] 2983L[451] = 9'bxx_xx_xxxxx; // [] 2984L[452] = 9'bxx_xx_xxxxx; // [] 2985L[453] = 9'bxx_xx_xxxxx; // [] 2986L[454] = 9'bxx_xx_xxxxx; // [] 2987L[455] = 9'bxx_xx_xxxxx; // [] 2988L[456] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2989L[457] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2990L[458] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 2991L[459] = 9'bxx_xx_xxxxx; // [] 2992L[460] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 2993L[461] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 2994L[462] = 9'bxx_xx_xxxxx; // [] 2995L[463] = 9'bxx_xx_xxxxx; // [] 2996L[464] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 2997L[465] = 9'b10_00_00011; // ['NO-OP', ''] 2998L[466] = 9'bxx_xx_xxxxx; // [] 2999L[467] = 9'bxx_xx_xxxxx; // [] 3000L[468] = 9'bxx_xx_xxxxx; // [] 3001L[469] = 9'bxx_xx_xxxxx; // [] 3002L[470] = 9'bxx_xx_xxxxx; // [] 3003L[471] = 9'bxx_xx_xxxxx; // [] 3004L[472] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3005L[473] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3006L[474] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3007L[475] = 9'bxx_xx_xxxxx; // [] 3008L[476] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3009L[477] = 9'b00_01_00011; // [AX]->T 3010L[478] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3011L[479] = 9'b10_01_00101; // T->[AX] 3012L[480] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3013L[481] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3014L[482] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3015L[483] = 9'bxx_xx_xxxxx; // [] 3016L[484] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3017L[485] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3018L[486] = 9'bxx_xx_xxxxx; // [] 3019L[487] = 9'bxx_xx_xxxxx; // [] 3020L[488] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3021L[489] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3022L[490] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3023L[491] = 9'bxx_xx_xxxxx; // [] 3024L[492] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3025L[493] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3026L[494] = 9'bxx_xx_xxxxx; // [] 3027L[495] = 9'bxx_xx_xxxxx; // [] 3028L[496] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3029L[497] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3030L[498] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3031L[499] = 9'bxx_xx_xxxxx; // [] 3032L[500] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3033L[501] = 9'b00_01_00011; // [AX]->T 3034L[502] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3035L[503] = 9'b10_01_00101; // T->[AX] 3036L[504] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3037L[505] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3038L[506] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3039L[507] = 9'bxx_xx_xxxxx; // [] 3040L[508] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3041L[509] = 9'b00_01_00011; // [AX]->T 3042L[510] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3043L[511] = 9'b10_01_00101; // T->[AX] 3044L[512] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3045L[513] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3046L[514] = 9'b00_10_10000; // ['SP++', 'SP+1->SP', '[SP]->T,SP+1->SP'] 3047L[515] = 9'b00_10_10110; // [SP]->P,SP+1->SP 3048L[516] = 9'b00_10_10000; // ['SP++', 'SP+1->SP', '[SP]->T,SP+1->SP'] 3049L[517] = 9'b10_10_10011; // [SP]:T->PC 3050L[518] = 9'bxx_xx_xxxxx; // [] 3051L[519] = 9'bxx_xx_xxxxx; // [] 3052L[520] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3053L[521] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3054L[522] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3055L[523] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3056L[524] = 9'b00_01_01011; // [AX]->AH,T->AL 3057L[525] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3058L[526] = 9'bxx_xx_xxxxx; // [] 3059L[527] = 9'bxx_xx_xxxxx; // [] 3060L[528] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3061L[529] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3062L[530] = 9'bxx_xx_xxxxx; // [] 3063L[531] = 9'bxx_xx_xxxxx; // [] 3064L[532] = 9'bxx_xx_xxxxx; // [] 3065L[533] = 9'bxx_xx_xxxxx; // [] 3066L[534] = 9'bxx_xx_xxxxx; // [] 3067L[535] = 9'bxx_xx_xxxxx; // [] 3068L[536] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3069L[537] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3070L[538] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3071L[539] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3072L[540] = 9'b00_01_01011; // [AX]->AH,T->AL 3073L[541] = 9'b00_01_00011; // [AX]->T 3074L[542] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3075L[543] = 9'b10_01_00101; // T->[AX] 3076L[544] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3077L[545] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3078L[546] = 9'bxx_xx_xxxxx; // [] 3079L[547] = 9'bxx_xx_xxxxx; // [] 3080L[548] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3081L[549] = 9'bxx_xx_xxxxx; // [] 3082L[550] = 9'bxx_xx_xxxxx; // [] 3083L[551] = 9'bxx_xx_xxxxx; // [] 3084L[552] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3085L[553] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3086L[554] = 9'bxx_xx_xxxxx; // [] 3087L[555] = 9'bxx_xx_xxxxx; // [] 3088L[556] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3089L[557] = 9'bxx_xx_xxxxx; // [] 3090L[558] = 9'bxx_xx_xxxxx; // [] 3091L[559] = 9'bxx_xx_xxxxx; // [] 3092L[560] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3093L[561] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3094L[562] = 9'bxx_xx_xxxxx; // [] 3095L[563] = 9'bxx_xx_xxxxx; // [] 3096L[564] = 9'b00_01_00011; // [AX]->T 3097L[565] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3098L[566] = 9'b10_01_00101; // T->[AX] 3099L[567] = 9'bxx_xx_xxxxx; // [] 3100L[568] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3101L[569] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3102L[570] = 9'bxx_xx_xxxxx; // [] 3103L[571] = 9'bxx_xx_xxxxx; // [] 3104L[572] = 9'b00_01_00011; // [AX]->T 3105L[573] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3106L[574] = 9'b10_01_00101; // T->[AX] 3107L[575] = 9'bxx_xx_xxxxx; // [] 3108L[576] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3109L[577] = 9'b00_00_00011; // [PC]-> 3110L[578] = 9'b10_10_01110; // ALU(A)->[SP--] 3111L[579] = 9'bxx_xx_xxxxx; // [] 3112L[580] = 9'bxx_xx_xxxxx; // [] 3113L[581] = 9'bxx_xx_xxxxx; // [] 3114L[582] = 9'bxx_xx_xxxxx; // [] 3115L[583] = 9'bxx_xx_xxxxx; // [] 3116L[584] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3117L[585] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 3118L[586] = 9'bxx_xx_xxxxx; // [] 3119L[587] = 9'bxx_xx_xxxxx; // [] 3120L[588] = 9'bxx_xx_xxxxx; // [] 3121L[589] = 9'bxx_xx_xxxxx; // [] 3122L[590] = 9'bxx_xx_xxxxx; // [] 3123L[591] = 9'bxx_xx_xxxxx; // [] 3124L[592] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3125L[593] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3126L[594] = 9'bxx_xx_xxxxx; // [] 3127L[595] = 9'bxx_xx_xxxxx; // [] 3128L[596] = 9'bxx_xx_xxxxx; // [] 3129L[597] = 9'bxx_xx_xxxxx; // [] 3130L[598] = 9'bxx_xx_xxxxx; // [] 3131L[599] = 9'bxx_xx_xxxxx; // [] 3132L[600] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3133L[601] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3134L[602] = 9'bxx_xx_xxxxx; // [] 3135L[603] = 9'bxx_xx_xxxxx; // [] 3136L[604] = 9'bxx_xx_xxxxx; // [] 3137L[605] = 9'bxx_xx_xxxxx; // [] 3138L[606] = 9'bxx_xx_xxxxx; // [] 3139L[607] = 9'bxx_xx_xxxxx; // [] 3140L[608] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3141L[609] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3142L[610] = 9'bxx_xx_xxxxx; // [] 3143L[611] = 9'bxx_xx_xxxxx; // [] 3144L[612] = 9'b10_00_10011; // [PC]:T->PC 3145L[613] = 9'bxx_xx_xxxxx; // [] 3146L[614] = 9'bxx_xx_xxxxx; // [] 3147L[615] = 9'bxx_xx_xxxxx; // [] 3148L[616] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3149L[617] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3150L[618] = 9'b11_00_00001; // [PC++]->AH 3151L[619] = 9'bxx_xx_xxxxx; // [] 3152L[620] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3153L[621] = 9'bxx_xx_xxxxx; // [] 3154L[622] = 9'bxx_xx_xxxxx; // [] 3155L[623] = 9'bxx_xx_xxxxx; // [] 3156L[624] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3157L[625] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3158L[626] = 9'b11_00_00001; // [PC++]->AH 3159L[627] = 9'bxx_xx_xxxxx; // [] 3160L[628] = 9'b00_01_00011; // [AX]->T 3161L[629] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3162L[630] = 9'b10_01_00101; // T->[AX] 3163L[631] = 9'bxx_xx_xxxxx; // [] 3164L[632] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3165L[633] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3166L[634] = 9'b11_00_00001; // [PC++]->AH 3167L[635] = 9'bxx_xx_xxxxx; // [] 3168L[636] = 9'b00_01_00011; // [AX]->T 3169L[637] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3170L[638] = 9'b10_01_00101; // T->[AX] 3171L[639] = 9'bxx_xx_xxxxx; // [] 3172L[640] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3173L[641] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3174L[642] = 9'b11_00_10001; // PC+T->PC 3175L[643] = 9'bxx_xx_xxxxx; // [] 3176L[644] = 9'b10_00_00011; // ['NO-OP', ''] 3177L[645] = 9'bxx_xx_xxxxx; // [] 3178L[646] = 9'bxx_xx_xxxxx; // [] 3179L[647] = 9'bxx_xx_xxxxx; // [] 3180L[648] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3181L[649] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3182L[650] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3183L[651] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 3184L[652] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3185L[653] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3186L[654] = 9'bxx_xx_xxxxx; // [] 3187L[655] = 9'bxx_xx_xxxxx; // [] 3188L[656] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3189L[657] = 9'b10_00_00011; // ['NO-OP', ''] 3190L[658] = 9'bxx_xx_xxxxx; // [] 3191L[659] = 9'bxx_xx_xxxxx; // [] 3192L[660] = 9'bxx_xx_xxxxx; // [] 3193L[661] = 9'bxx_xx_xxxxx; // [] 3194L[662] = 9'bxx_xx_xxxxx; // [] 3195L[663] = 9'bxx_xx_xxxxx; // [] 3196L[664] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3197L[665] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3198L[666] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3199L[667] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 3200L[668] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3201L[669] = 9'b00_01_00011; // [AX]->T 3202L[670] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3203L[671] = 9'b10_01_00101; // T->[AX] 3204L[672] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3205L[673] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3206L[674] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3207L[675] = 9'bxx_xx_xxxxx; // [] 3208L[676] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3209L[677] = 9'bxx_xx_xxxxx; // [] 3210L[678] = 9'bxx_xx_xxxxx; // [] 3211L[679] = 9'bxx_xx_xxxxx; // [] 3212L[680] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3213L[681] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3214L[682] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3215L[683] = 9'bxx_xx_xxxxx; // [] 3216L[684] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3217L[685] = 9'bxx_xx_xxxxx; // [] 3218L[686] = 9'bxx_xx_xxxxx; // [] 3219L[687] = 9'bxx_xx_xxxxx; // [] 3220L[688] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3221L[689] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3222L[690] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3223L[691] = 9'bxx_xx_xxxxx; // [] 3224L[692] = 9'b00_01_00011; // [AX]->T 3225L[693] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3226L[694] = 9'b10_01_00101; // T->[AX] 3227L[695] = 9'bxx_xx_xxxxx; // [] 3228L[696] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3229L[697] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3230L[698] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3231L[699] = 9'bxx_xx_xxxxx; // [] 3232L[700] = 9'b00_01_00011; // [AX]->T 3233L[701] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3234L[702] = 9'b10_01_00101; // T->[AX] 3235L[703] = 9'bxx_xx_xxxxx; // [] 3236L[704] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3237L[705] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3238L[706] = 9'bxx_xx_xxxxx; // [] 3239L[707] = 9'bxx_xx_xxxxx; // [] 3240L[708] = 9'bxx_xx_xxxxx; // [] 3241L[709] = 9'bxx_xx_xxxxx; // [] 3242L[710] = 9'bxx_xx_xxxxx; // [] 3243L[711] = 9'bxx_xx_xxxxx; // [] 3244L[712] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3245L[713] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3246L[714] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3247L[715] = 9'bxx_xx_xxxxx; // [] 3248L[716] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3249L[717] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3250L[718] = 9'bxx_xx_xxxxx; // [] 3251L[719] = 9'bxx_xx_xxxxx; // [] 3252L[720] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3253L[721] = 9'b10_00_00011; // ['NO-OP', ''] 3254L[722] = 9'bxx_xx_xxxxx; // [] 3255L[723] = 9'bxx_xx_xxxxx; // [] 3256L[724] = 9'bxx_xx_xxxxx; // [] 3257L[725] = 9'bxx_xx_xxxxx; // [] 3258L[726] = 9'bxx_xx_xxxxx; // [] 3259L[727] = 9'bxx_xx_xxxxx; // [] 3260L[728] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3261L[729] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3262L[730] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3263L[731] = 9'bxx_xx_xxxxx; // [] 3264L[732] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3265L[733] = 9'b00_01_00011; // [AX]->T 3266L[734] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3267L[735] = 9'b10_01_00101; // T->[AX] 3268L[736] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3269L[737] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3270L[738] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3271L[739] = 9'bxx_xx_xxxxx; // [] 3272L[740] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3273L[741] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3274L[742] = 9'bxx_xx_xxxxx; // [] 3275L[743] = 9'bxx_xx_xxxxx; // [] 3276L[744] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3277L[745] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3278L[746] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3279L[747] = 9'bxx_xx_xxxxx; // [] 3280L[748] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3281L[749] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3282L[750] = 9'bxx_xx_xxxxx; // [] 3283L[751] = 9'bxx_xx_xxxxx; // [] 3284L[752] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3285L[753] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3286L[754] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3287L[755] = 9'bxx_xx_xxxxx; // [] 3288L[756] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3289L[757] = 9'b00_01_00011; // [AX]->T 3290L[758] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3291L[759] = 9'b10_01_00101; // T->[AX] 3292L[760] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3293L[761] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3294L[762] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3295L[763] = 9'bxx_xx_xxxxx; // [] 3296L[764] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3297L[765] = 9'b00_01_00011; // [AX]->T 3298L[766] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3299L[767] = 9'b10_01_00101; // T->[AX] 3300L[768] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3301L[769] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3302L[770] = 9'b11_10_10000; // SP+1->SP 3303L[771] = 9'bxx_xx_xxxxx; // [] 3304L[772] = 9'b00_10_10000; // ['SP++', 'SP+1->SP', '[SP]->T,SP+1->SP'] 3305L[773] = 9'b00_10_10011; // [SP]:T->PC 3306L[774] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3307L[775] = 9'bxx_xx_xxxxx; // [] 3308L[776] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3309L[777] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3310L[778] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3311L[779] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3312L[780] = 9'b00_01_01011; // [AX]->AH,T->AL 3313L[781] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3314L[782] = 9'bxx_xx_xxxxx; // [] 3315L[783] = 9'bxx_xx_xxxxx; // [] 3316L[784] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3317L[785] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3318L[786] = 9'bxx_xx_xxxxx; // [] 3319L[787] = 9'bxx_xx_xxxxx; // [] 3320L[788] = 9'bxx_xx_xxxxx; // [] 3321L[789] = 9'bxx_xx_xxxxx; // [] 3322L[790] = 9'bxx_xx_xxxxx; // [] 3323L[791] = 9'bxx_xx_xxxxx; // [] 3324L[792] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3325L[793] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3326L[794] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3327L[795] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3328L[796] = 9'b00_01_01011; // [AX]->AH,T->AL 3329L[797] = 9'b00_01_00011; // [AX]->T 3330L[798] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3331L[799] = 9'b10_01_00101; // T->[AX] 3332L[800] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3333L[801] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3334L[802] = 9'bxx_xx_xxxxx; // [] 3335L[803] = 9'bxx_xx_xxxxx; // [] 3336L[804] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3337L[805] = 9'bxx_xx_xxxxx; // [] 3338L[806] = 9'bxx_xx_xxxxx; // [] 3339L[807] = 9'bxx_xx_xxxxx; // [] 3340L[808] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3341L[809] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3342L[810] = 9'bxx_xx_xxxxx; // [] 3343L[811] = 9'bxx_xx_xxxxx; // [] 3344L[812] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3345L[813] = 9'bxx_xx_xxxxx; // [] 3346L[814] = 9'bxx_xx_xxxxx; // [] 3347L[815] = 9'bxx_xx_xxxxx; // [] 3348L[816] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3349L[817] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3350L[818] = 9'bxx_xx_xxxxx; // [] 3351L[819] = 9'bxx_xx_xxxxx; // [] 3352L[820] = 9'b00_01_00011; // [AX]->T 3353L[821] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3354L[822] = 9'b10_01_00101; // T->[AX] 3355L[823] = 9'bxx_xx_xxxxx; // [] 3356L[824] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3357L[825] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3358L[826] = 9'bxx_xx_xxxxx; // [] 3359L[827] = 9'bxx_xx_xxxxx; // [] 3360L[828] = 9'b00_01_00011; // [AX]->T 3361L[829] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3362L[830] = 9'b10_01_00101; // T->[AX] 3363L[831] = 9'bxx_xx_xxxxx; // [] 3364L[832] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3365L[833] = 9'b00_00_00011; // [PC]-> 3366L[834] = 9'b00_10_10000; // ['SP++', 'SP+1->SP', '[SP]->T,SP+1->SP'] 3367L[835] = 9'b10_10_00010; // ['ALU([SP])->A', '[SP]->P'] 3368L[836] = 9'bxx_xx_xxxxx; // [] 3369L[837] = 9'bxx_xx_xxxxx; // [] 3370L[838] = 9'bxx_xx_xxxxx; // [] 3371L[839] = 9'bxx_xx_xxxxx; // [] 3372L[840] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3373L[841] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 3374L[842] = 9'bxx_xx_xxxxx; // [] 3375L[843] = 9'bxx_xx_xxxxx; // [] 3376L[844] = 9'bxx_xx_xxxxx; // [] 3377L[845] = 9'bxx_xx_xxxxx; // [] 3378L[846] = 9'bxx_xx_xxxxx; // [] 3379L[847] = 9'bxx_xx_xxxxx; // [] 3380L[848] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3381L[849] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3382L[850] = 9'bxx_xx_xxxxx; // [] 3383L[851] = 9'bxx_xx_xxxxx; // [] 3384L[852] = 9'bxx_xx_xxxxx; // [] 3385L[853] = 9'bxx_xx_xxxxx; // [] 3386L[854] = 9'bxx_xx_xxxxx; // [] 3387L[855] = 9'bxx_xx_xxxxx; // [] 3388L[856] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3389L[857] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3390L[858] = 9'bxx_xx_xxxxx; // [] 3391L[859] = 9'bxx_xx_xxxxx; // [] 3392L[860] = 9'bxx_xx_xxxxx; // [] 3393L[861] = 9'bxx_xx_xxxxx; // [] 3394L[862] = 9'bxx_xx_xxxxx; // [] 3395L[863] = 9'bxx_xx_xxxxx; // [] 3396L[864] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3397L[865] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3398L[866] = 9'b00_00_00001; // [PC++]->AH 3399L[867] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3400L[868] = 9'b10_01_10011; // [AX]:T->PC 3401L[869] = 9'bxx_xx_xxxxx; // [] 3402L[870] = 9'bxx_xx_xxxxx; // [] 3403L[871] = 9'bxx_xx_xxxxx; // [] 3404L[872] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3405L[873] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3406L[874] = 9'b11_00_00001; // [PC++]->AH 3407L[875] = 9'bxx_xx_xxxxx; // [] 3408L[876] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3409L[877] = 9'bxx_xx_xxxxx; // [] 3410L[878] = 9'bxx_xx_xxxxx; // [] 3411L[879] = 9'bxx_xx_xxxxx; // [] 3412L[880] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3413L[881] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3414L[882] = 9'b11_00_00001; // [PC++]->AH 3415L[883] = 9'bxx_xx_xxxxx; // [] 3416L[884] = 9'b00_01_00011; // [AX]->T 3417L[885] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3418L[886] = 9'b10_01_00101; // T->[AX] 3419L[887] = 9'bxx_xx_xxxxx; // [] 3420L[888] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3421L[889] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3422L[890] = 9'b11_00_00001; // [PC++]->AH 3423L[891] = 9'bxx_xx_xxxxx; // [] 3424L[892] = 9'b00_01_00011; // [AX]->T 3425L[893] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3426L[894] = 9'b10_01_00101; // T->[AX] 3427L[895] = 9'bxx_xx_xxxxx; // [] 3428L[896] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3429L[897] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3430L[898] = 9'b11_00_10001; // PC+T->PC 3431L[899] = 9'bxx_xx_xxxxx; // [] 3432L[900] = 9'b10_00_00011; // ['NO-OP', ''] 3433L[901] = 9'bxx_xx_xxxxx; // [] 3434L[902] = 9'bxx_xx_xxxxx; // [] 3435L[903] = 9'bxx_xx_xxxxx; // [] 3436L[904] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3437L[905] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3438L[906] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3439L[907] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 3440L[908] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3441L[909] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3442L[910] = 9'bxx_xx_xxxxx; // [] 3443L[911] = 9'bxx_xx_xxxxx; // [] 3444L[912] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3445L[913] = 9'b10_00_00011; // ['NO-OP', ''] 3446L[914] = 9'bxx_xx_xxxxx; // [] 3447L[915] = 9'bxx_xx_xxxxx; // [] 3448L[916] = 9'bxx_xx_xxxxx; // [] 3449L[917] = 9'bxx_xx_xxxxx; // [] 3450L[918] = 9'bxx_xx_xxxxx; // [] 3451L[919] = 9'bxx_xx_xxxxx; // [] 3452L[920] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3453L[921] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3454L[922] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3455L[923] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 3456L[924] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3457L[925] = 9'b00_01_00011; // [AX]->T 3458L[926] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3459L[927] = 9'b10_01_00101; // T->[AX] 3460L[928] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3461L[929] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3462L[930] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3463L[931] = 9'bxx_xx_xxxxx; // [] 3464L[932] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3465L[933] = 9'bxx_xx_xxxxx; // [] 3466L[934] = 9'bxx_xx_xxxxx; // [] 3467L[935] = 9'bxx_xx_xxxxx; // [] 3468L[936] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3469L[937] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3470L[938] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3471L[939] = 9'bxx_xx_xxxxx; // [] 3472L[940] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3473L[941] = 9'bxx_xx_xxxxx; // [] 3474L[942] = 9'bxx_xx_xxxxx; // [] 3475L[943] = 9'bxx_xx_xxxxx; // [] 3476L[944] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3477L[945] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3478L[946] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3479L[947] = 9'bxx_xx_xxxxx; // [] 3480L[948] = 9'b00_01_00011; // [AX]->T 3481L[949] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3482L[950] = 9'b10_01_00101; // T->[AX] 3483L[951] = 9'bxx_xx_xxxxx; // [] 3484L[952] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3485L[953] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3486L[954] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3487L[955] = 9'bxx_xx_xxxxx; // [] 3488L[956] = 9'b00_01_00011; // [AX]->T 3489L[957] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3490L[958] = 9'b10_01_00101; // T->[AX] 3491L[959] = 9'bxx_xx_xxxxx; // [] 3492L[960] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3493L[961] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3494L[962] = 9'bxx_xx_xxxxx; // [] 3495L[963] = 9'bxx_xx_xxxxx; // [] 3496L[964] = 9'bxx_xx_xxxxx; // [] 3497L[965] = 9'bxx_xx_xxxxx; // [] 3498L[966] = 9'bxx_xx_xxxxx; // [] 3499L[967] = 9'bxx_xx_xxxxx; // [] 3500L[968] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3501L[969] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3502L[970] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3503L[971] = 9'bxx_xx_xxxxx; // [] 3504L[972] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3505L[973] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3506L[974] = 9'bxx_xx_xxxxx; // [] 3507L[975] = 9'bxx_xx_xxxxx; // [] 3508L[976] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3509L[977] = 9'b10_00_00011; // ['NO-OP', ''] 3510L[978] = 9'bxx_xx_xxxxx; // [] 3511L[979] = 9'bxx_xx_xxxxx; // [] 3512L[980] = 9'bxx_xx_xxxxx; // [] 3513L[981] = 9'bxx_xx_xxxxx; // [] 3514L[982] = 9'bxx_xx_xxxxx; // [] 3515L[983] = 9'bxx_xx_xxxxx; // [] 3516L[984] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3517L[985] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3518L[986] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3519L[987] = 9'bxx_xx_xxxxx; // [] 3520L[988] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3521L[989] = 9'b00_01_00011; // [AX]->T 3522L[990] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3523L[991] = 9'b10_01_00101; // T->[AX] 3524L[992] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3525L[993] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3526L[994] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3527L[995] = 9'bxx_xx_xxxxx; // [] 3528L[996] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3529L[997] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 3530L[998] = 9'bxx_xx_xxxxx; // [] 3531L[999] = 9'bxx_xx_xxxxx; // [] 3532L[1000] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3533L[1001] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3534L[1002] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3535L[1003] = 9'bxx_xx_xxxxx; // [] 3536L[1004] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3537L[1005] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3538L[1006] = 9'bxx_xx_xxxxx; // [] 3539L[1007] = 9'bxx_xx_xxxxx; // [] 3540L[1008] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3541L[1009] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3542L[1010] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3543L[1011] = 9'bxx_xx_xxxxx; // [] 3544L[1012] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3545L[1013] = 9'b00_01_00011; // [AX]->T 3546L[1014] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3547L[1015] = 9'b10_01_00101; // T->[AX] 3548L[1016] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3549L[1017] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3550L[1018] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3551L[1019] = 9'bxx_xx_xxxxx; // [] 3552L[1020] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3553L[1021] = 9'b00_01_00011; // [AX]->T 3554L[1022] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 3555L[1023] = 9'b10_01_00101; // T->[AX] 3556L[1024] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3557L[1025] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3558L[1026] = 9'bxx_xx_xxxxx; // [] 3559L[1027] = 9'bxx_xx_xxxxx; // [] 3560L[1028] = 9'bxx_xx_xxxxx; // [] 3561L[1029] = 9'bxx_xx_xxxxx; // [] 3562L[1030] = 9'bxx_xx_xxxxx; // [] 3563L[1031] = 9'bxx_xx_xxxxx; // [] 3564L[1032] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3565L[1033] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3566L[1034] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3567L[1035] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3568L[1036] = 9'b00_01_01011; // [AX]->AH,T->AL 3569L[1037] = 9'b10_01_00110; // ALU()->[AX] 3570L[1038] = 9'bxx_xx_xxxxx; // [] 3571L[1039] = 9'bxx_xx_xxxxx; // [] 3572L[1040] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3573L[1041] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3574L[1042] = 9'bxx_xx_xxxxx; // [] 3575L[1043] = 9'bxx_xx_xxxxx; // [] 3576L[1044] = 9'bxx_xx_xxxxx; // [] 3577L[1045] = 9'bxx_xx_xxxxx; // [] 3578L[1046] = 9'bxx_xx_xxxxx; // [] 3579L[1047] = 9'bxx_xx_xxxxx; // [] 3580L[1048] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3581L[1049] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3582L[1050] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3583L[1051] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3584L[1052] = 9'b00_01_01011; // [AX]->AH,T->AL 3585L[1053] = 9'b10_01_00110; // ALU()->[AX] 3586L[1054] = 9'bxx_xx_xxxxx; // [] 3587L[1055] = 9'bxx_xx_xxxxx; // [] 3588L[1056] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3589L[1057] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3590L[1058] = 9'bxx_xx_xxxxx; // [] 3591L[1059] = 9'bxx_xx_xxxxx; // [] 3592L[1060] = 9'b10_01_00110; // ALU()->[AX] 3593L[1061] = 9'bxx_xx_xxxxx; // [] 3594L[1062] = 9'bxx_xx_xxxxx; // [] 3595L[1063] = 9'bxx_xx_xxxxx; // [] 3596L[1064] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3597L[1065] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3598L[1066] = 9'bxx_xx_xxxxx; // [] 3599L[1067] = 9'bxx_xx_xxxxx; // [] 3600L[1068] = 9'b10_01_00110; // ALU()->[AX] 3601L[1069] = 9'bxx_xx_xxxxx; // [] 3602L[1070] = 9'bxx_xx_xxxxx; // [] 3603L[1071] = 9'bxx_xx_xxxxx; // [] 3604L[1072] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3605L[1073] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3606L[1074] = 9'bxx_xx_xxxxx; // [] 3607L[1075] = 9'bxx_xx_xxxxx; // [] 3608L[1076] = 9'b10_01_00110; // ALU()->[AX] 3609L[1077] = 9'bxx_xx_xxxxx; // [] 3610L[1078] = 9'bxx_xx_xxxxx; // [] 3611L[1079] = 9'bxx_xx_xxxxx; // [] 3612L[1080] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3613L[1081] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3614L[1082] = 9'bxx_xx_xxxxx; // [] 3615L[1083] = 9'bxx_xx_xxxxx; // [] 3616L[1084] = 9'b10_01_00110; // ALU()->[AX] 3617L[1085] = 9'bxx_xx_xxxxx; // [] 3618L[1086] = 9'bxx_xx_xxxxx; // [] 3619L[1087] = 9'bxx_xx_xxxxx; // [] 3620L[1088] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3621L[1089] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3622L[1090] = 9'bxx_xx_xxxxx; // [] 3623L[1091] = 9'bxx_xx_xxxxx; // [] 3624L[1092] = 9'bxx_xx_xxxxx; // [] 3625L[1093] = 9'bxx_xx_xxxxx; // [] 3626L[1094] = 9'bxx_xx_xxxxx; // [] 3627L[1095] = 9'bxx_xx_xxxxx; // [] 3628L[1096] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3629L[1097] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3630L[1098] = 9'bxx_xx_xxxxx; // [] 3631L[1099] = 9'bxx_xx_xxxxx; // [] 3632L[1100] = 9'bxx_xx_xxxxx; // [] 3633L[1101] = 9'bxx_xx_xxxxx; // [] 3634L[1102] = 9'bxx_xx_xxxxx; // [] 3635L[1103] = 9'bxx_xx_xxxxx; // [] 3636L[1104] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3637L[1105] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3638L[1106] = 9'bxx_xx_xxxxx; // [] 3639L[1107] = 9'bxx_xx_xxxxx; // [] 3640L[1108] = 9'bxx_xx_xxxxx; // [] 3641L[1109] = 9'bxx_xx_xxxxx; // [] 3642L[1110] = 9'bxx_xx_xxxxx; // [] 3643L[1111] = 9'bxx_xx_xxxxx; // [] 3644L[1112] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3645L[1113] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3646L[1114] = 9'bxx_xx_xxxxx; // [] 3647L[1115] = 9'bxx_xx_xxxxx; // [] 3648L[1116] = 9'bxx_xx_xxxxx; // [] 3649L[1117] = 9'bxx_xx_xxxxx; // [] 3650L[1118] = 9'bxx_xx_xxxxx; // [] 3651L[1119] = 9'bxx_xx_xxxxx; // [] 3652L[1120] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3653L[1121] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3654L[1122] = 9'b11_00_00001; // [PC++]->AH 3655L[1123] = 9'bxx_xx_xxxxx; // [] 3656L[1124] = 9'b10_01_00110; // ALU()->[AX] 3657L[1125] = 9'bxx_xx_xxxxx; // [] 3658L[1126] = 9'bxx_xx_xxxxx; // [] 3659L[1127] = 9'bxx_xx_xxxxx; // [] 3660L[1128] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3661L[1129] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3662L[1130] = 9'b11_00_00001; // [PC++]->AH 3663L[1131] = 9'bxx_xx_xxxxx; // [] 3664L[1132] = 9'b10_01_00110; // ALU()->[AX] 3665L[1133] = 9'bxx_xx_xxxxx; // [] 3666L[1134] = 9'bxx_xx_xxxxx; // [] 3667L[1135] = 9'bxx_xx_xxxxx; // [] 3668L[1136] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3669L[1137] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3670L[1138] = 9'b11_00_00001; // [PC++]->AH 3671L[1139] = 9'bxx_xx_xxxxx; // [] 3672L[1140] = 9'b10_01_00110; // ALU()->[AX] 3673L[1141] = 9'bxx_xx_xxxxx; // [] 3674L[1142] = 9'bxx_xx_xxxxx; // [] 3675L[1143] = 9'bxx_xx_xxxxx; // [] 3676L[1144] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3677L[1145] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3678L[1146] = 9'b11_00_00001; // [PC++]->AH 3679L[1147] = 9'bxx_xx_xxxxx; // [] 3680L[1148] = 9'b10_01_00110; // ALU()->[AX] 3681L[1149] = 9'bxx_xx_xxxxx; // [] 3682L[1150] = 9'bxx_xx_xxxxx; // [] 3683L[1151] = 9'bxx_xx_xxxxx; // [] 3684L[1152] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3685L[1153] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3686L[1154] = 9'b11_00_10001; // PC+T->PC 3687L[1155] = 9'bxx_xx_xxxxx; // [] 3688L[1156] = 9'b10_00_00011; // ['NO-OP', ''] 3689L[1157] = 9'bxx_xx_xxxxx; // [] 3690L[1158] = 9'bxx_xx_xxxxx; // [] 3691L[1159] = 9'bxx_xx_xxxxx; // [] 3692L[1160] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3693L[1161] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3694L[1162] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3695L[1163] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 3696L[1164] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3697L[1165] = 9'b10_01_00110; // ALU()->[AX] 3698L[1166] = 9'bxx_xx_xxxxx; // [] 3699L[1167] = 9'bxx_xx_xxxxx; // [] 3700L[1168] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3701L[1169] = 9'b10_00_00011; // ['NO-OP', ''] 3702L[1170] = 9'bxx_xx_xxxxx; // [] 3703L[1171] = 9'bxx_xx_xxxxx; // [] 3704L[1172] = 9'bxx_xx_xxxxx; // [] 3705L[1173] = 9'bxx_xx_xxxxx; // [] 3706L[1174] = 9'bxx_xx_xxxxx; // [] 3707L[1175] = 9'bxx_xx_xxxxx; // [] 3708L[1176] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3709L[1177] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3710L[1178] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3711L[1179] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 3712L[1180] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3713L[1181] = 9'b10_01_00110; // ALU()->[AX] 3714L[1182] = 9'bxx_xx_xxxxx; // [] 3715L[1183] = 9'bxx_xx_xxxxx; // [] 3716L[1184] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3717L[1185] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3718L[1186] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3719L[1187] = 9'bxx_xx_xxxxx; // [] 3720L[1188] = 9'b10_01_00110; // ALU()->[AX] 3721L[1189] = 9'bxx_xx_xxxxx; // [] 3722L[1190] = 9'bxx_xx_xxxxx; // [] 3723L[1191] = 9'bxx_xx_xxxxx; // [] 3724L[1192] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3725L[1193] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3726L[1194] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3727L[1195] = 9'bxx_xx_xxxxx; // [] 3728L[1196] = 9'b10_01_00110; // ALU()->[AX] 3729L[1197] = 9'bxx_xx_xxxxx; // [] 3730L[1198] = 9'bxx_xx_xxxxx; // [] 3731L[1199] = 9'bxx_xx_xxxxx; // [] 3732L[1200] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3733L[1201] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3734L[1202] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3735L[1203] = 9'bxx_xx_xxxxx; // [] 3736L[1204] = 9'b10_01_00110; // ALU()->[AX] 3737L[1205] = 9'bxx_xx_xxxxx; // [] 3738L[1206] = 9'bxx_xx_xxxxx; // [] 3739L[1207] = 9'bxx_xx_xxxxx; // [] 3740L[1208] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3741L[1209] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3742L[1210] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3743L[1211] = 9'bxx_xx_xxxxx; // [] 3744L[1212] = 9'b10_01_00110; // ALU()->[AX] 3745L[1213] = 9'bxx_xx_xxxxx; // [] 3746L[1214] = 9'bxx_xx_xxxxx; // [] 3747L[1215] = 9'bxx_xx_xxxxx; // [] 3748L[1216] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3749L[1217] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3750L[1218] = 9'bxx_xx_xxxxx; // [] 3751L[1219] = 9'bxx_xx_xxxxx; // [] 3752L[1220] = 9'bxx_xx_xxxxx; // [] 3753L[1221] = 9'bxx_xx_xxxxx; // [] 3754L[1222] = 9'bxx_xx_xxxxx; // [] 3755L[1223] = 9'bxx_xx_xxxxx; // [] 3756L[1224] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3757L[1225] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3758L[1226] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3759L[1227] = 9'bxx_xx_xxxxx; // [] 3760L[1228] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3761L[1229] = 9'b10_01_00110; // ALU()->[AX] 3762L[1230] = 9'bxx_xx_xxxxx; // [] 3763L[1231] = 9'bxx_xx_xxxxx; // [] 3764L[1232] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3765L[1233] = 9'b10_00_10010; // X->S 3766L[1234] = 9'bxx_xx_xxxxx; // [] 3767L[1235] = 9'bxx_xx_xxxxx; // [] 3768L[1236] = 9'bxx_xx_xxxxx; // [] 3769L[1237] = 9'bxx_xx_xxxxx; // [] 3770L[1238] = 9'bxx_xx_xxxxx; // [] 3771L[1239] = 9'bxx_xx_xxxxx; // [] 3772L[1240] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3773L[1241] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3774L[1242] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3775L[1243] = 9'bxx_xx_xxxxx; // [] 3776L[1244] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3777L[1245] = 9'b10_01_00110; // ALU()->[AX] 3778L[1246] = 9'bxx_xx_xxxxx; // [] 3779L[1247] = 9'bxx_xx_xxxxx; // [] 3780L[1248] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3781L[1249] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3782L[1250] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3783L[1251] = 9'bxx_xx_xxxxx; // [] 3784L[1252] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3785L[1253] = 9'b10_01_00110; // ALU()->[AX] 3786L[1254] = 9'bxx_xx_xxxxx; // [] 3787L[1255] = 9'bxx_xx_xxxxx; // [] 3788L[1256] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3789L[1257] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3790L[1258] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3791L[1259] = 9'bxx_xx_xxxxx; // [] 3792L[1260] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3793L[1261] = 9'b10_01_00110; // ALU()->[AX] 3794L[1262] = 9'bxx_xx_xxxxx; // [] 3795L[1263] = 9'bxx_xx_xxxxx; // [] 3796L[1264] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3797L[1265] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3798L[1266] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3799L[1267] = 9'bxx_xx_xxxxx; // [] 3800L[1268] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3801L[1269] = 9'b10_01_00110; // ALU()->[AX] 3802L[1270] = 9'bxx_xx_xxxxx; // [] 3803L[1271] = 9'bxx_xx_xxxxx; // [] 3804L[1272] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3805L[1273] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3806L[1274] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 3807L[1275] = 9'bxx_xx_xxxxx; // [] 3808L[1276] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3809L[1277] = 9'b10_01_00110; // ALU()->[AX] 3810L[1278] = 9'bxx_xx_xxxxx; // [] 3811L[1279] = 9'bxx_xx_xxxxx; // [] 3812L[1280] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3813L[1281] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 3814L[1282] = 9'bxx_xx_xxxxx; // [] 3815L[1283] = 9'bxx_xx_xxxxx; // [] 3816L[1284] = 9'bxx_xx_xxxxx; // [] 3817L[1285] = 9'bxx_xx_xxxxx; // [] 3818L[1286] = 9'bxx_xx_xxxxx; // [] 3819L[1287] = 9'bxx_xx_xxxxx; // [] 3820L[1288] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3821L[1289] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3822L[1290] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3823L[1291] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3824L[1292] = 9'b00_01_01011; // [AX]->AH,T->AL 3825L[1293] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3826L[1294] = 9'bxx_xx_xxxxx; // [] 3827L[1295] = 9'bxx_xx_xxxxx; // [] 3828L[1296] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3829L[1297] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 3830L[1298] = 9'bxx_xx_xxxxx; // [] 3831L[1299] = 9'bxx_xx_xxxxx; // [] 3832L[1300] = 9'bxx_xx_xxxxx; // [] 3833L[1301] = 9'bxx_xx_xxxxx; // [] 3834L[1302] = 9'bxx_xx_xxxxx; // [] 3835L[1303] = 9'bxx_xx_xxxxx; // [] 3836L[1304] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3837L[1305] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3838L[1306] = 9'b00_01_00111; // [AX]->?,AL+X->AL 3839L[1307] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3840L[1308] = 9'b00_01_01011; // [AX]->AH,T->AL 3841L[1309] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3842L[1310] = 9'bxx_xx_xxxxx; // [] 3843L[1311] = 9'bxx_xx_xxxxx; // [] 3844L[1312] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3845L[1313] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3846L[1314] = 9'bxx_xx_xxxxx; // [] 3847L[1315] = 9'bxx_xx_xxxxx; // [] 3848L[1316] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3849L[1317] = 9'bxx_xx_xxxxx; // [] 3850L[1318] = 9'bxx_xx_xxxxx; // [] 3851L[1319] = 9'bxx_xx_xxxxx; // [] 3852L[1320] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3853L[1321] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3854L[1322] = 9'bxx_xx_xxxxx; // [] 3855L[1323] = 9'bxx_xx_xxxxx; // [] 3856L[1324] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3857L[1325] = 9'bxx_xx_xxxxx; // [] 3858L[1326] = 9'bxx_xx_xxxxx; // [] 3859L[1327] = 9'bxx_xx_xxxxx; // [] 3860L[1328] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3861L[1329] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3862L[1330] = 9'bxx_xx_xxxxx; // [] 3863L[1331] = 9'bxx_xx_xxxxx; // [] 3864L[1332] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3865L[1333] = 9'bxx_xx_xxxxx; // [] 3866L[1334] = 9'bxx_xx_xxxxx; // [] 3867L[1335] = 9'bxx_xx_xxxxx; // [] 3868L[1336] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3869L[1337] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 3870L[1338] = 9'bxx_xx_xxxxx; // [] 3871L[1339] = 9'bxx_xx_xxxxx; // [] 3872L[1340] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3873L[1341] = 9'bxx_xx_xxxxx; // [] 3874L[1342] = 9'bxx_xx_xxxxx; // [] 3875L[1343] = 9'bxx_xx_xxxxx; // [] 3876L[1344] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3877L[1345] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3878L[1346] = 9'bxx_xx_xxxxx; // [] 3879L[1347] = 9'bxx_xx_xxxxx; // [] 3880L[1348] = 9'bxx_xx_xxxxx; // [] 3881L[1349] = 9'bxx_xx_xxxxx; // [] 3882L[1350] = 9'bxx_xx_xxxxx; // [] 3883L[1351] = 9'bxx_xx_xxxxx; // [] 3884L[1352] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3885L[1353] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 3886L[1354] = 9'bxx_xx_xxxxx; // [] 3887L[1355] = 9'bxx_xx_xxxxx; // [] 3888L[1356] = 9'bxx_xx_xxxxx; // [] 3889L[1357] = 9'bxx_xx_xxxxx; // [] 3890L[1358] = 9'bxx_xx_xxxxx; // [] 3891L[1359] = 9'bxx_xx_xxxxx; // [] 3892L[1360] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3893L[1361] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 3894L[1362] = 9'bxx_xx_xxxxx; // [] 3895L[1363] = 9'bxx_xx_xxxxx; // [] 3896L[1364] = 9'bxx_xx_xxxxx; // [] 3897L[1365] = 9'bxx_xx_xxxxx; // [] 3898L[1366] = 9'bxx_xx_xxxxx; // [] 3899L[1367] = 9'bxx_xx_xxxxx; // [] 3900L[1368] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3901L[1369] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3902L[1370] = 9'bxx_xx_xxxxx; // [] 3903L[1371] = 9'bxx_xx_xxxxx; // [] 3904L[1372] = 9'bxx_xx_xxxxx; // [] 3905L[1373] = 9'bxx_xx_xxxxx; // [] 3906L[1374] = 9'bxx_xx_xxxxx; // [] 3907L[1375] = 9'bxx_xx_xxxxx; // [] 3908L[1376] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3909L[1377] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3910L[1378] = 9'b11_00_00001; // [PC++]->AH 3911L[1379] = 9'bxx_xx_xxxxx; // [] 3912L[1380] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3913L[1381] = 9'bxx_xx_xxxxx; // [] 3914L[1382] = 9'bxx_xx_xxxxx; // [] 3915L[1383] = 9'bxx_xx_xxxxx; // [] 3916L[1384] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3917L[1385] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3918L[1386] = 9'b11_00_00001; // [PC++]->AH 3919L[1387] = 9'bxx_xx_xxxxx; // [] 3920L[1388] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3921L[1389] = 9'bxx_xx_xxxxx; // [] 3922L[1390] = 9'bxx_xx_xxxxx; // [] 3923L[1391] = 9'bxx_xx_xxxxx; // [] 3924L[1392] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3925L[1393] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3926L[1394] = 9'b11_00_00001; // [PC++]->AH 3927L[1395] = 9'bxx_xx_xxxxx; // [] 3928L[1396] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3929L[1397] = 9'bxx_xx_xxxxx; // [] 3930L[1398] = 9'bxx_xx_xxxxx; // [] 3931L[1399] = 9'bxx_xx_xxxxx; // [] 3932L[1400] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3933L[1401] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3934L[1402] = 9'b11_00_00001; // [PC++]->AH 3935L[1403] = 9'bxx_xx_xxxxx; // [] 3936L[1404] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3937L[1405] = 9'bxx_xx_xxxxx; // [] 3938L[1406] = 9'bxx_xx_xxxxx; // [] 3939L[1407] = 9'bxx_xx_xxxxx; // [] 3940L[1408] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3941L[1409] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 3942L[1410] = 9'b11_00_10001; // PC+T->PC 3943L[1411] = 9'bxx_xx_xxxxx; // [] 3944L[1412] = 9'b10_00_00011; // ['NO-OP', ''] 3945L[1413] = 9'bxx_xx_xxxxx; // [] 3946L[1414] = 9'bxx_xx_xxxxx; // [] 3947L[1415] = 9'bxx_xx_xxxxx; // [] 3948L[1416] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3949L[1417] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3950L[1418] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3951L[1419] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 3952L[1420] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3953L[1421] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3954L[1422] = 9'bxx_xx_xxxxx; // [] 3955L[1423] = 9'bxx_xx_xxxxx; // [] 3956L[1424] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3957L[1425] = 9'b10_00_00011; // ['NO-OP', ''] 3958L[1426] = 9'bxx_xx_xxxxx; // [] 3959L[1427] = 9'bxx_xx_xxxxx; // [] 3960L[1428] = 9'bxx_xx_xxxxx; // [] 3961L[1429] = 9'bxx_xx_xxxxx; // [] 3962L[1430] = 9'bxx_xx_xxxxx; // [] 3963L[1431] = 9'bxx_xx_xxxxx; // [] 3964L[1432] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3965L[1433] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3966L[1434] = 9'b00_01_01010; // [AX]->T,AL+1->AL 3967L[1435] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 3968L[1436] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 3969L[1437] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3970L[1438] = 9'bxx_xx_xxxxx; // [] 3971L[1439] = 9'bxx_xx_xxxxx; // [] 3972L[1440] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3973L[1441] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3974L[1442] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3975L[1443] = 9'bxx_xx_xxxxx; // [] 3976L[1444] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3977L[1445] = 9'bxx_xx_xxxxx; // [] 3978L[1446] = 9'bxx_xx_xxxxx; // [] 3979L[1447] = 9'bxx_xx_xxxxx; // [] 3980L[1448] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3981L[1449] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3982L[1450] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3983L[1451] = 9'bxx_xx_xxxxx; // [] 3984L[1452] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3985L[1453] = 9'bxx_xx_xxxxx; // [] 3986L[1454] = 9'bxx_xx_xxxxx; // [] 3987L[1455] = 9'bxx_xx_xxxxx; // [] 3988L[1456] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3989L[1457] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3990L[1458] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3991L[1459] = 9'bxx_xx_xxxxx; // [] 3992L[1460] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 3993L[1461] = 9'bxx_xx_xxxxx; // [] 3994L[1462] = 9'bxx_xx_xxxxx; // [] 3995L[1463] = 9'bxx_xx_xxxxx; // [] 3996L[1464] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3997L[1465] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 3998L[1466] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 3999L[1467] = 9'bxx_xx_xxxxx; // [] 4000L[1468] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4001L[1469] = 9'bxx_xx_xxxxx; // [] 4002L[1470] = 9'bxx_xx_xxxxx; // [] 4003L[1471] = 9'bxx_xx_xxxxx; // [] 4004L[1472] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4005L[1473] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4006L[1474] = 9'bxx_xx_xxxxx; // [] 4007L[1475] = 9'bxx_xx_xxxxx; // [] 4008L[1476] = 9'bxx_xx_xxxxx; // [] 4009L[1477] = 9'bxx_xx_xxxxx; // [] 4010L[1478] = 9'bxx_xx_xxxxx; // [] 4011L[1479] = 9'bxx_xx_xxxxx; // [] 4012L[1480] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4013L[1481] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4014L[1482] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4015L[1483] = 9'bxx_xx_xxxxx; // [] 4016L[1484] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4017L[1485] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4018L[1486] = 9'bxx_xx_xxxxx; // [] 4019L[1487] = 9'bxx_xx_xxxxx; // [] 4020L[1488] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4021L[1489] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4022L[1490] = 9'bxx_xx_xxxxx; // [] 4023L[1491] = 9'bxx_xx_xxxxx; // [] 4024L[1492] = 9'bxx_xx_xxxxx; // [] 4025L[1493] = 9'bxx_xx_xxxxx; // [] 4026L[1494] = 9'bxx_xx_xxxxx; // [] 4027L[1495] = 9'bxx_xx_xxxxx; // [] 4028L[1496] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4029L[1497] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4030L[1498] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4031L[1499] = 9'bxx_xx_xxxxx; // [] 4032L[1500] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4033L[1501] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4034L[1502] = 9'bxx_xx_xxxxx; // [] 4035L[1503] = 9'bxx_xx_xxxxx; // [] 4036L[1504] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4037L[1505] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4038L[1506] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4039L[1507] = 9'bxx_xx_xxxxx; // [] 4040L[1508] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4041L[1509] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4042L[1510] = 9'bxx_xx_xxxxx; // [] 4043L[1511] = 9'bxx_xx_xxxxx; // [] 4044L[1512] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4045L[1513] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4046L[1514] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4047L[1515] = 9'bxx_xx_xxxxx; // [] 4048L[1516] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4049L[1517] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4050L[1518] = 9'bxx_xx_xxxxx; // [] 4051L[1519] = 9'bxx_xx_xxxxx; // [] 4052L[1520] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4053L[1521] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4054L[1522] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4055L[1523] = 9'bxx_xx_xxxxx; // [] 4056L[1524] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4057L[1525] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4058L[1526] = 9'bxx_xx_xxxxx; // [] 4059L[1527] = 9'bxx_xx_xxxxx; // [] 4060L[1528] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4061L[1529] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4062L[1530] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4063L[1531] = 9'bxx_xx_xxxxx; // [] 4064L[1532] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4065L[1533] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4066L[1534] = 9'bxx_xx_xxxxx; // [] 4067L[1535] = 9'bxx_xx_xxxxx; // [] 4068L[1536] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4069L[1537] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 4070L[1538] = 9'bxx_xx_xxxxx; // [] 4071L[1539] = 9'bxx_xx_xxxxx; // [] 4072L[1540] = 9'bxx_xx_xxxxx; // [] 4073L[1541] = 9'bxx_xx_xxxxx; // [] 4074L[1542] = 9'bxx_xx_xxxxx; // [] 4075L[1543] = 9'bxx_xx_xxxxx; // [] 4076L[1544] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4077L[1545] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4078L[1546] = 9'b00_01_00111; // [AX]->?,AL+X->AL 4079L[1547] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4080L[1548] = 9'b00_01_01011; // [AX]->AH,T->AL 4081L[1549] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4082L[1550] = 9'bxx_xx_xxxxx; // [] 4083L[1551] = 9'bxx_xx_xxxxx; // [] 4084L[1552] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4085L[1553] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 4086L[1554] = 9'bxx_xx_xxxxx; // [] 4087L[1555] = 9'bxx_xx_xxxxx; // [] 4088L[1556] = 9'bxx_xx_xxxxx; // [] 4089L[1557] = 9'bxx_xx_xxxxx; // [] 4090L[1558] = 9'bxx_xx_xxxxx; // [] 4091L[1559] = 9'bxx_xx_xxxxx; // [] 4092L[1560] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4093L[1561] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4094L[1562] = 9'b00_01_00111; // [AX]->?,AL+X->AL 4095L[1563] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4096L[1564] = 9'b00_01_01011; // [AX]->AH,T->AL 4097L[1565] = 9'b00_01_00011; // [AX]->T 4098L[1566] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4099L[1567] = 9'b10_01_00101; // T->[AX] 4100L[1568] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4101L[1569] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4102L[1570] = 9'bxx_xx_xxxxx; // [] 4103L[1571] = 9'bxx_xx_xxxxx; // [] 4104L[1572] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4105L[1573] = 9'bxx_xx_xxxxx; // [] 4106L[1574] = 9'bxx_xx_xxxxx; // [] 4107L[1575] = 9'bxx_xx_xxxxx; // [] 4108L[1576] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4109L[1577] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4110L[1578] = 9'bxx_xx_xxxxx; // [] 4111L[1579] = 9'bxx_xx_xxxxx; // [] 4112L[1580] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4113L[1581] = 9'bxx_xx_xxxxx; // [] 4114L[1582] = 9'bxx_xx_xxxxx; // [] 4115L[1583] = 9'bxx_xx_xxxxx; // [] 4116L[1584] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4117L[1585] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4118L[1586] = 9'bxx_xx_xxxxx; // [] 4119L[1587] = 9'bxx_xx_xxxxx; // [] 4120L[1588] = 9'b00_01_00011; // [AX]->T 4121L[1589] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4122L[1590] = 9'b10_01_00101; // T->[AX] 4123L[1591] = 9'bxx_xx_xxxxx; // [] 4124L[1592] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4125L[1593] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4126L[1594] = 9'bxx_xx_xxxxx; // [] 4127L[1595] = 9'bxx_xx_xxxxx; // [] 4128L[1596] = 9'b00_01_00011; // [AX]->T 4129L[1597] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4130L[1598] = 9'b10_01_00101; // T->[AX] 4131L[1599] = 9'bxx_xx_xxxxx; // [] 4132L[1600] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4133L[1601] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4134L[1602] = 9'bxx_xx_xxxxx; // [] 4135L[1603] = 9'bxx_xx_xxxxx; // [] 4136L[1604] = 9'bxx_xx_xxxxx; // [] 4137L[1605] = 9'bxx_xx_xxxxx; // [] 4138L[1606] = 9'bxx_xx_xxxxx; // [] 4139L[1607] = 9'bxx_xx_xxxxx; // [] 4140L[1608] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4141L[1609] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 4142L[1610] = 9'bxx_xx_xxxxx; // [] 4143L[1611] = 9'bxx_xx_xxxxx; // [] 4144L[1612] = 9'bxx_xx_xxxxx; // [] 4145L[1613] = 9'bxx_xx_xxxxx; // [] 4146L[1614] = 9'bxx_xx_xxxxx; // [] 4147L[1615] = 9'bxx_xx_xxxxx; // [] 4148L[1616] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4149L[1617] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4150L[1618] = 9'bxx_xx_xxxxx; // [] 4151L[1619] = 9'bxx_xx_xxxxx; // [] 4152L[1620] = 9'bxx_xx_xxxxx; // [] 4153L[1621] = 9'bxx_xx_xxxxx; // [] 4154L[1622] = 9'bxx_xx_xxxxx; // [] 4155L[1623] = 9'bxx_xx_xxxxx; // [] 4156L[1624] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4157L[1625] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 4158L[1626] = 9'bxx_xx_xxxxx; // [] 4159L[1627] = 9'bxx_xx_xxxxx; // [] 4160L[1628] = 9'bxx_xx_xxxxx; // [] 4161L[1629] = 9'bxx_xx_xxxxx; // [] 4162L[1630] = 9'bxx_xx_xxxxx; // [] 4163L[1631] = 9'bxx_xx_xxxxx; // [] 4164L[1632] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4165L[1633] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4166L[1634] = 9'b11_00_00001; // [PC++]->AH 4167L[1635] = 9'bxx_xx_xxxxx; // [] 4168L[1636] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4169L[1637] = 9'bxx_xx_xxxxx; // [] 4170L[1638] = 9'bxx_xx_xxxxx; // [] 4171L[1639] = 9'bxx_xx_xxxxx; // [] 4172L[1640] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4173L[1641] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4174L[1642] = 9'b11_00_00001; // [PC++]->AH 4175L[1643] = 9'bxx_xx_xxxxx; // [] 4176L[1644] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4177L[1645] = 9'bxx_xx_xxxxx; // [] 4178L[1646] = 9'bxx_xx_xxxxx; // [] 4179L[1647] = 9'bxx_xx_xxxxx; // [] 4180L[1648] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4181L[1649] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4182L[1650] = 9'b11_00_00001; // [PC++]->AH 4183L[1651] = 9'bxx_xx_xxxxx; // [] 4184L[1652] = 9'b00_01_00011; // [AX]->T 4185L[1653] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4186L[1654] = 9'b10_01_00101; // T->[AX] 4187L[1655] = 9'bxx_xx_xxxxx; // [] 4188L[1656] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4189L[1657] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4190L[1658] = 9'b11_00_00001; // [PC++]->AH 4191L[1659] = 9'bxx_xx_xxxxx; // [] 4192L[1660] = 9'b00_01_00011; // [AX]->T 4193L[1661] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4194L[1662] = 9'b10_01_00101; // T->[AX] 4195L[1663] = 9'bxx_xx_xxxxx; // [] 4196L[1664] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4197L[1665] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 4198L[1666] = 9'b11_00_10001; // PC+T->PC 4199L[1667] = 9'bxx_xx_xxxxx; // [] 4200L[1668] = 9'b10_00_00011; // ['NO-OP', ''] 4201L[1669] = 9'bxx_xx_xxxxx; // [] 4202L[1670] = 9'bxx_xx_xxxxx; // [] 4203L[1671] = 9'bxx_xx_xxxxx; // [] 4204L[1672] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4205L[1673] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4206L[1674] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4207L[1675] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 4208L[1676] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4209L[1677] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4210L[1678] = 9'bxx_xx_xxxxx; // [] 4211L[1679] = 9'bxx_xx_xxxxx; // [] 4212L[1680] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4213L[1681] = 9'b10_00_00011; // ['NO-OP', ''] 4214L[1682] = 9'bxx_xx_xxxxx; // [] 4215L[1683] = 9'bxx_xx_xxxxx; // [] 4216L[1684] = 9'bxx_xx_xxxxx; // [] 4217L[1685] = 9'bxx_xx_xxxxx; // [] 4218L[1686] = 9'bxx_xx_xxxxx; // [] 4219L[1687] = 9'bxx_xx_xxxxx; // [] 4220L[1688] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4221L[1689] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4222L[1690] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4223L[1691] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 4224L[1692] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4225L[1693] = 9'b00_01_00011; // [AX]->T 4226L[1694] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4227L[1695] = 9'b10_01_00101; // T->[AX] 4228L[1696] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4229L[1697] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4230L[1698] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4231L[1699] = 9'bxx_xx_xxxxx; // [] 4232L[1700] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 4233L[1701] = 9'bxx_xx_xxxxx; // [] 4234L[1702] = 9'bxx_xx_xxxxx; // [] 4235L[1703] = 9'bxx_xx_xxxxx; // [] 4236L[1704] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4237L[1705] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4238L[1706] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4239L[1707] = 9'bxx_xx_xxxxx; // [] 4240L[1708] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4241L[1709] = 9'bxx_xx_xxxxx; // [] 4242L[1710] = 9'bxx_xx_xxxxx; // [] 4243L[1711] = 9'bxx_xx_xxxxx; // [] 4244L[1712] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4245L[1713] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4246L[1714] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4247L[1715] = 9'bxx_xx_xxxxx; // [] 4248L[1716] = 9'b00_01_00011; // [AX]->T 4249L[1717] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4250L[1718] = 9'b10_01_00101; // T->[AX] 4251L[1719] = 9'bxx_xx_xxxxx; // [] 4252L[1720] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4253L[1721] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4254L[1722] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4255L[1723] = 9'bxx_xx_xxxxx; // [] 4256L[1724] = 9'b00_01_00011; // [AX]->T 4257L[1725] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4258L[1726] = 9'b10_01_00101; // T->[AX] 4259L[1727] = 9'bxx_xx_xxxxx; // [] 4260L[1728] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4261L[1729] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4262L[1730] = 9'bxx_xx_xxxxx; // [] 4263L[1731] = 9'bxx_xx_xxxxx; // [] 4264L[1732] = 9'bxx_xx_xxxxx; // [] 4265L[1733] = 9'bxx_xx_xxxxx; // [] 4266L[1734] = 9'bxx_xx_xxxxx; // [] 4267L[1735] = 9'bxx_xx_xxxxx; // [] 4268L[1736] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4269L[1737] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4270L[1738] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4271L[1739] = 9'bxx_xx_xxxxx; // [] 4272L[1740] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4273L[1741] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4274L[1742] = 9'bxx_xx_xxxxx; // [] 4275L[1743] = 9'bxx_xx_xxxxx; // [] 4276L[1744] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4277L[1745] = 9'b10_00_00011; // ['NO-OP', ''] 4278L[1746] = 9'bxx_xx_xxxxx; // [] 4279L[1747] = 9'bxx_xx_xxxxx; // [] 4280L[1748] = 9'bxx_xx_xxxxx; // [] 4281L[1749] = 9'bxx_xx_xxxxx; // [] 4282L[1750] = 9'bxx_xx_xxxxx; // [] 4283L[1751] = 9'bxx_xx_xxxxx; // [] 4284L[1752] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4285L[1753] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4286L[1754] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4287L[1755] = 9'bxx_xx_xxxxx; // [] 4288L[1756] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4289L[1757] = 9'b00_01_00011; // [AX]->T 4290L[1758] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4291L[1759] = 9'b10_01_00101; // T->[AX] 4292L[1760] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4293L[1761] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4294L[1762] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4295L[1763] = 9'bxx_xx_xxxxx; // [] 4296L[1764] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4297L[1765] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 4298L[1766] = 9'bxx_xx_xxxxx; // [] 4299L[1767] = 9'bxx_xx_xxxxx; // [] 4300L[1768] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4301L[1769] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4302L[1770] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4303L[1771] = 9'bxx_xx_xxxxx; // [] 4304L[1772] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4305L[1773] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4306L[1774] = 9'bxx_xx_xxxxx; // [] 4307L[1775] = 9'bxx_xx_xxxxx; // [] 4308L[1776] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4309L[1777] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4310L[1778] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4311L[1779] = 9'bxx_xx_xxxxx; // [] 4312L[1780] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4313L[1781] = 9'b00_01_00011; // [AX]->T 4314L[1782] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4315L[1783] = 9'b10_01_00101; // T->[AX] 4316L[1784] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4317L[1785] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4318L[1786] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4319L[1787] = 9'bxx_xx_xxxxx; // [] 4320L[1788] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4321L[1789] = 9'b00_01_00011; // [AX]->T 4322L[1790] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4323L[1791] = 9'b10_01_00101; // T->[AX] 4324L[1792] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4325L[1793] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 4326L[1794] = 9'bxx_xx_xxxxx; // [] 4327L[1795] = 9'bxx_xx_xxxxx; // [] 4328L[1796] = 9'bxx_xx_xxxxx; // [] 4329L[1797] = 9'bxx_xx_xxxxx; // [] 4330L[1798] = 9'bxx_xx_xxxxx; // [] 4331L[1799] = 9'bxx_xx_xxxxx; // [] 4332L[1800] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4333L[1801] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4334L[1802] = 9'b00_01_00111; // [AX]->?,AL+X->AL 4335L[1803] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4336L[1804] = 9'b00_01_01011; // [AX]->AH,T->AL 4337L[1805] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4338L[1806] = 9'bxx_xx_xxxxx; // [] 4339L[1807] = 9'bxx_xx_xxxxx; // [] 4340L[1808] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4341L[1809] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 4342L[1810] = 9'bxx_xx_xxxxx; // [] 4343L[1811] = 9'bxx_xx_xxxxx; // [] 4344L[1812] = 9'bxx_xx_xxxxx; // [] 4345L[1813] = 9'bxx_xx_xxxxx; // [] 4346L[1814] = 9'bxx_xx_xxxxx; // [] 4347L[1815] = 9'bxx_xx_xxxxx; // [] 4348L[1816] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4349L[1817] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4350L[1818] = 9'b00_01_00111; // [AX]->?,AL+X->AL 4351L[1819] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4352L[1820] = 9'b00_01_01011; // [AX]->AH,T->AL 4353L[1821] = 9'b00_01_00011; // [AX]->T 4354L[1822] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4355L[1823] = 9'b10_01_00101; // T->[AX] 4356L[1824] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4357L[1825] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4358L[1826] = 9'bxx_xx_xxxxx; // [] 4359L[1827] = 9'bxx_xx_xxxxx; // [] 4360L[1828] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4361L[1829] = 9'bxx_xx_xxxxx; // [] 4362L[1830] = 9'bxx_xx_xxxxx; // [] 4363L[1831] = 9'bxx_xx_xxxxx; // [] 4364L[1832] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4365L[1833] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4366L[1834] = 9'bxx_xx_xxxxx; // [] 4367L[1835] = 9'bxx_xx_xxxxx; // [] 4368L[1836] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4369L[1837] = 9'bxx_xx_xxxxx; // [] 4370L[1838] = 9'bxx_xx_xxxxx; // [] 4371L[1839] = 9'bxx_xx_xxxxx; // [] 4372L[1840] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4373L[1841] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4374L[1842] = 9'bxx_xx_xxxxx; // [] 4375L[1843] = 9'bxx_xx_xxxxx; // [] 4376L[1844] = 9'b00_01_00011; // [AX]->T 4377L[1845] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4378L[1846] = 9'b10_01_00101; // T->[AX] 4379L[1847] = 9'bxx_xx_xxxxx; // [] 4380L[1848] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4381L[1849] = 9'b11_00_00000; // ['[PC++]->AL', '[PC++]->T'] 4382L[1850] = 9'bxx_xx_xxxxx; // [] 4383L[1851] = 9'bxx_xx_xxxxx; // [] 4384L[1852] = 9'b00_01_00011; // [AX]->T 4385L[1853] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4386L[1854] = 9'b10_01_00101; // T->[AX] 4387L[1855] = 9'bxx_xx_xxxxx; // [] 4388L[1856] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4389L[1857] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4390L[1858] = 9'bxx_xx_xxxxx; // [] 4391L[1859] = 9'bxx_xx_xxxxx; // [] 4392L[1860] = 9'bxx_xx_xxxxx; // [] 4393L[1861] = 9'bxx_xx_xxxxx; // [] 4394L[1862] = 9'bxx_xx_xxxxx; // [] 4395L[1863] = 9'bxx_xx_xxxxx; // [] 4396L[1864] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4397L[1865] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 4398L[1866] = 9'bxx_xx_xxxxx; // [] 4399L[1867] = 9'bxx_xx_xxxxx; // [] 4400L[1868] = 9'bxx_xx_xxxxx; // [] 4401L[1869] = 9'bxx_xx_xxxxx; // [] 4402L[1870] = 9'bxx_xx_xxxxx; // [] 4403L[1871] = 9'bxx_xx_xxxxx; // [] 4404L[1872] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4405L[1873] = 9'b10_00_00011; // ['NO-OP', ''] 4406L[1874] = 9'bxx_xx_xxxxx; // [] 4407L[1875] = 9'bxx_xx_xxxxx; // [] 4408L[1876] = 9'bxx_xx_xxxxx; // [] 4409L[1877] = 9'bxx_xx_xxxxx; // [] 4410L[1878] = 9'bxx_xx_xxxxx; // [] 4411L[1879] = 9'bxx_xx_xxxxx; // [] 4412L[1880] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4413L[1881] = 9'b10_00_01101; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 4414L[1882] = 9'bxx_xx_xxxxx; // [] 4415L[1883] = 9'bxx_xx_xxxxx; // [] 4416L[1884] = 9'bxx_xx_xxxxx; // [] 4417L[1885] = 9'bxx_xx_xxxxx; // [] 4418L[1886] = 9'bxx_xx_xxxxx; // [] 4419L[1887] = 9'bxx_xx_xxxxx; // [] 4420L[1888] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4421L[1889] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4422L[1890] = 9'b11_00_00001; // [PC++]->AH 4423L[1891] = 9'bxx_xx_xxxxx; // [] 4424L[1892] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4425L[1893] = 9'bxx_xx_xxxxx; // [] 4426L[1894] = 9'bxx_xx_xxxxx; // [] 4427L[1895] = 9'bxx_xx_xxxxx; // [] 4428L[1896] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4429L[1897] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4430L[1898] = 9'b11_00_00001; // [PC++]->AH 4431L[1899] = 9'bxx_xx_xxxxx; // [] 4432L[1900] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4433L[1901] = 9'bxx_xx_xxxxx; // [] 4434L[1902] = 9'bxx_xx_xxxxx; // [] 4435L[1903] = 9'bxx_xx_xxxxx; // [] 4436L[1904] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4437L[1905] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4438L[1906] = 9'b11_00_00001; // [PC++]->AH 4439L[1907] = 9'bxx_xx_xxxxx; // [] 4440L[1908] = 9'b00_01_00011; // [AX]->T 4441L[1909] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4442L[1910] = 9'b10_01_00101; // T->[AX] 4443L[1911] = 9'bxx_xx_xxxxx; // [] 4444L[1912] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4445L[1913] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4446L[1914] = 9'b11_00_00001; // [PC++]->AH 4447L[1915] = 9'bxx_xx_xxxxx; // [] 4448L[1916] = 9'b00_01_00011; // [AX]->T 4449L[1917] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4450L[1918] = 9'b10_01_00101; // T->[AX] 4451L[1919] = 9'bxx_xx_xxxxx; // [] 4452L[1920] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4453L[1921] = 9'b10_00_00000; // ['[PC++]->?', 'PC+1->PC', ''] 4454L[1922] = 9'b11_00_10001; // PC+T->PC 4455L[1923] = 9'bxx_xx_xxxxx; // [] 4456L[1924] = 9'b10_00_00011; // ['NO-OP', ''] 4457L[1925] = 9'bxx_xx_xxxxx; // [] 4458L[1926] = 9'bxx_xx_xxxxx; // [] 4459L[1927] = 9'bxx_xx_xxxxx; // [] 4460L[1928] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4461L[1929] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4462L[1930] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4463L[1931] = 9'b01_01_01100; // [AX]->AH,T+Y->AL 4464L[1932] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4465L[1933] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4466L[1934] = 9'bxx_xx_xxxxx; // [] 4467L[1935] = 9'bxx_xx_xxxxx; // [] 4468L[1936] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4469L[1937] = 9'b10_00_00011; // ['NO-OP', ''] 4470L[1938] = 9'bxx_xx_xxxxx; // [] 4471L[1939] = 9'bxx_xx_xxxxx; // [] 4472L[1940] = 9'bxx_xx_xxxxx; // [] 4473L[1941] = 9'bxx_xx_xxxxx; // [] 4474L[1942] = 9'bxx_xx_xxxxx; // [] 4475L[1943] = 9'bxx_xx_xxxxx; // [] 4476L[1944] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4477L[1945] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4478L[1946] = 9'b00_01_01010; // [AX]->T,AL+1->AL 4479L[1947] = 9'b00_01_01100; // [AX]->AH,T+Y->AL 4480L[1948] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4481L[1949] = 9'b00_01_00011; // [AX]->T 4482L[1950] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4483L[1951] = 9'b10_01_00101; // T->[AX] 4484L[1952] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4485L[1953] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4486L[1954] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4487L[1955] = 9'bxx_xx_xxxxx; // [] 4488L[1956] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 4489L[1957] = 9'bxx_xx_xxxxx; // [] 4490L[1958] = 9'bxx_xx_xxxxx; // [] 4491L[1959] = 9'bxx_xx_xxxxx; // [] 4492L[1960] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4493L[1961] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4494L[1962] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4495L[1963] = 9'bxx_xx_xxxxx; // [] 4496L[1964] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4497L[1965] = 9'bxx_xx_xxxxx; // [] 4498L[1966] = 9'bxx_xx_xxxxx; // [] 4499L[1967] = 9'bxx_xx_xxxxx; // [] 4500L[1968] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4501L[1969] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4502L[1970] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4503L[1971] = 9'bxx_xx_xxxxx; // [] 4504L[1972] = 9'b00_01_00011; // [AX]->T 4505L[1973] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4506L[1974] = 9'b10_01_00101; // T->[AX] 4507L[1975] = 9'bxx_xx_xxxxx; // [] 4508L[1976] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4509L[1977] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4510L[1978] = 9'b11_01_00111; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL'] 4511L[1979] = 9'bxx_xx_xxxxx; // [] 4512L[1980] = 9'b00_01_00011; // [AX]->T 4513L[1981] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4514L[1982] = 9'b10_01_00101; // T->[AX] 4515L[1983] = 9'bxx_xx_xxxxx; // [] 4516L[1984] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4517L[1985] = 9'b10_00_00010; // ['[PC]->,ALU()->A', 'Setappropriateflags', 'ALU()->X,Y', 'ALU()->A'] 4518L[1986] = 9'bxx_xx_xxxxx; // [] 4519L[1987] = 9'bxx_xx_xxxxx; // [] 4520L[1988] = 9'bxx_xx_xxxxx; // [] 4521L[1989] = 9'bxx_xx_xxxxx; // [] 4522L[1990] = 9'bxx_xx_xxxxx; // [] 4523L[1991] = 9'bxx_xx_xxxxx; // [] 4524L[1992] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4525L[1993] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4526L[1994] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4527L[1995] = 9'bxx_xx_xxxxx; // [] 4528L[1996] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4529L[1997] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4530L[1998] = 9'bxx_xx_xxxxx; // [] 4531L[1999] = 9'bxx_xx_xxxxx; // [] 4532L[2000] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4533L[2001] = 9'b10_00_00011; // ['NO-OP', ''] 4534L[2002] = 9'bxx_xx_xxxxx; // [] 4535L[2003] = 9'bxx_xx_xxxxx; // [] 4536L[2004] = 9'bxx_xx_xxxxx; // [] 4537L[2005] = 9'bxx_xx_xxxxx; // [] 4538L[2006] = 9'bxx_xx_xxxxx; // [] 4539L[2007] = 9'bxx_xx_xxxxx; // [] 4540L[2008] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4541L[2009] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4542L[2010] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4543L[2011] = 9'bxx_xx_xxxxx; // [] 4544L[2012] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4545L[2013] = 9'b00_01_00011; // [AX]->T 4546L[2014] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4547L[2015] = 9'b10_01_00101; // T->[AX] 4548L[2016] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4549L[2017] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4550L[2018] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4551L[2019] = 9'bxx_xx_xxxxx; // [] 4552L[2020] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4553L[2021] = 9'b10_01_00011; // ['ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->'] 4554L[2022] = 9'bxx_xx_xxxxx; // [] 4555L[2023] = 9'bxx_xx_xxxxx; // [] 4556L[2024] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4557L[2025] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4558L[2026] = 9'b01_00_01000; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4559L[2027] = 9'bxx_xx_xxxxx; // [] 4560L[2028] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4561L[2029] = 9'b10_01_00010; // ['ALU([AX])->A', 'ALU([AX])->?'] 4562L[2030] = 9'bxx_xx_xxxxx; // [] 4563L[2031] = 9'bxx_xx_xxxxx; // [] 4564L[2032] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4565L[2033] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4566L[2034] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4567L[2035] = 9'bxx_xx_xxxxx; // [] 4568L[2036] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4569L[2037] = 9'b00_01_00011; // [AX]->T 4570L[2038] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4571L[2039] = 9'b10_01_00101; // T->[AX] 4572L[2040] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4573L[2041] = 9'b00_00_00000; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T'] 4574L[2042] = 9'b11_00_01000; // ['[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+Y->AL'] 4575L[2043] = 9'bxx_xx_xxxxx; // [] 4576L[2044] = 9'b00_01_01001; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4577L[2045] = 9'b00_01_00011; // [AX]->T 4578L[2046] = 9'b00_01_00100; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4579L[2047] = 9'b10_01_00101; // T->[AX] 4580 end 4581 always @(posedge clk) if (reset) begin 4582 M <= 0; // Stupid XILINX inferral only allows 0 as reset value. 4583 end else if (ce) begin 4584 M <= L[{IR, State}]; 4585 end 4586endmodule 4587 4588module MicroCodeTable(input clk, input ce, input reset, input [7:0] IR, input [2:0] State, output [37:0] Mout); 4589 wire [8:0] M; 4590 MicroCodeTableInner inner(clk, ce, reset, IR, State, M); 4591 reg [14:0] A[0:31]; 4592 reg [18:0] B[0:255]; 4593 initial begin 4594A[0] = 15'b_10__0_10101_0xx_01_00; // ['[PC++]', '[PC++]->AL', '[PC++]->?', '[PC++]->T', 'PC+1->PC', ''] 4595A[1] = 15'b_xx__0_0xx11_0xx_01_00; // [PC++]->AH 4596A[2] = 15'b_xx__1_00000_0xx_00_00; // ['ALU([AX])->A', 'ALU([AX])->?', '[PC]->,ALU()->A', 'Setappropriateflags', 'ALU([SP])->A', '[SP]->P', 'ALU()->X,Y', 'ALU()->A'] 4597A[3] = 15'b_10__0_00000_0xx_00_00; // ['[AX]->T', 'ALU([AX])->?', 'ALU([AX])->A', 'ALU([AX])->', '[PC]->', 'NO-OP', '[VECT]->T', ''] 4598A[4] = 15'b_11__1_00000_100_00_00; // ['T->[AX],ALU(T)->T', 'T->[AX],ALU(T)->T:A'] 4599A[5] = 15'b_xx__0_xxxxx_100_00_00; // T->[AX] 4600A[6] = 15'b_xx__0_00000_101_00_00; // ALU()->[AX] 4601A[7] = 15'b_0x__0_10000_0xx_00_00; // ['[AX]->?,AL+X->AL', '[AX]->?,AL+X/Y->AL', 'KEEP_AC'] 4602A[8] = 15'b_xx__0_10011_0xx_01_00; // ['[PC++]->AH,AL+X/Y->AL', '[PC++]->AH,AL+X->AL', '[PC++]->AH,AL+Y->AL'] 4603A[9] = 15'b_10__0_0xx10_0xx_00_00; // ['[AX]->?,AH+FIX->AH', '[AX]->T,AH+FIX->AH'] 4604A[10] = 15'b_10__0_11000_0xx_00_00; // [AX]->T,AL+1->AL 4605A[11] = 15'b_xx__0_11111_0xx_00_00; // [AX]->AH,T->AL 4606A[12] = 15'b_xx__0_10011_0xx_00_00; // [AX]->AH,T+Y->AL 4607A[13] = 15'b_xx__1_xxxxx_0xx_01_00; // ['ALU([PC++])->A', 'ALU([PC++])->?', 'ALU([PC++])->Reg'] 4608A[14] = 15'b_xx__0_xxxxx_101_00_11; // ALU(A)->[SP--] 4609A[15] = 15'b_xx__0_xxxxx_110_00_11; // P->[SP--] 4610A[16] = 15'b_10__0_xxxxx_0xx_00_10; // ['SP++', 'SP+1->SP', '[SP]->T,SP+1->SP'] 4611A[17] = 15'b_xx__0_xxxxx_0xx_11_00; // PC+T->PC 4612A[18] = 15'b_xx__0_xxxxx_0xx_00_01; // X->S 4613A[19] = 15'b_xx__0_xxxxx_0xx_10_00; // ['[PC]:T->PC', '[AX]:T->PC', '[VECT]:T->PC', '[SP]:T->PC'] 4614A[20] = 15'b_0x__0_xxxxx_111_00_11; // ['PCH->[SP--]', 'PCL->[SP--],', 'PCH->[SP--](KEEPAC)', 'PCL->[SP--](KEEPAC)'] 4615A[21] = 15'b_xx__1_xxxxx_110_00_11; // P->[SP--] 4616A[22] = 15'b_xx__1_xxxxx_0xx_00_10; // [SP]->P,SP+1->SP 4617A[23] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4618A[24] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4619A[25] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4620A[26] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4621A[27] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4622A[28] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4623A[29] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4624A[30] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4625A[31] = 15'b_xx__x_xxxxx_xxx_xx_xx; // [] 4626B[0] = 19'bxxxxxxxxxx0_000_00_010; 4627B[32] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4628B[64] = 19'bxxxxxxxxxx0_000_00_100; 4629B[96] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4630B[128] = 19'b011010x10x0_xxx_00_xxx; 4631B[160] = 19'bxx0010x10x0_100_00_001; 4632B[192] = 19'b010010x1100_000_00_001; 4633B[224] = 19'b100010x1100_000_00_001; 4634B[1] = 19'b000010x0001_010_00_001; 4635B[33] = 19'b000010x0011_010_00_001; 4636B[65] = 19'b000010x0101_010_00_001; 4637B[97] = 19'b000010x0111_010_00_001; 4638B[129] = 19'b001010x10x1_xxx_00_xxx; 4639B[161] = 19'bxx0010x10x1_010_00_001; 4640B[193] = 19'b000010x1101_000_00_001; 4641B[225] = 19'b000010x1111_010_00_001; 4642B[2] = 19'bxx0100010x0_000_00_001; 4643B[34] = 19'bxx0100110x0_000_00_001; 4644B[66] = 19'bxx0101010x0_000_00_001; 4645B[98] = 19'bxx0101110x0_000_00_001; 4646B[130] = 19'b101010x10x0_xxx_00_xxx; 4647B[162] = 19'bxx0010x10x0_001_00_001; 4648B[194] = 19'bxx0111010x0_000_00_001; 4649B[226] = 19'bxx0111110x0_000_00_001; 4650B[3] = 19'b00010000001_010_00_001; 4651B[35] = 19'b00010010011_010_00_001; 4652B[67] = 19'b00010100101_010_00_001; 4653B[99] = 19'b00010110111_010_00_001; 4654B[131] = 19'b111010x10x1_xxx_00_xxx; 4655B[163] = 19'bxx0010x10x1_011_00_001; 4656B[195] = 19'b00011101101_000_00_001; 4657B[227] = 19'b00011111111_010_00_001; 4658B[4] = 19'b000010x0000_xxx_00_xxx; 4659B[36] = 19'b000010x0010_000_00_001; 4660B[68] = 19'b000010x0100_xxx_00_xxx; 4661B[100] = 19'b000010x0110_xxx_00_xxx; 4662B[132] = 19'b011010x10x0_xxx_00_xxx; 4663B[164] = 19'bxx0010x10x0_100_00_001; 4664B[196] = 19'b010010x1100_000_00_001; 4665B[228] = 19'b100010x1100_000_00_001; 4666B[5] = 19'b000010x0001_010_00_001; 4667B[37] = 19'b000010x0011_010_00_001; 4668B[69] = 19'b000010x0101_010_00_001; 4669B[101] = 19'b000010x0111_010_00_001; 4670B[133] = 19'b001010x10x1_xxx_00_xxx; 4671B[165] = 19'bxx0010x10x1_010_00_001; 4672B[197] = 19'b000010x1101_000_00_001; 4673B[229] = 19'b000010x1111_010_00_001; 4674B[6] = 19'bxx0100010x0_000_00_001; 4675B[38] = 19'bxx0100110x0_000_00_001; 4676B[70] = 19'bxx0101010x0_000_00_001; 4677B[102] = 19'bxx0101110x0_000_00_001; 4678B[134] = 19'b101010x10x0_xxx_00_xxx; 4679B[166] = 19'bxx0010x10x0_001_00_001; 4680B[198] = 19'bxx0111010x0_000_00_001; 4681B[230] = 19'bxx0111110x0_000_00_001; 4682B[7] = 19'b00010000001_010_00_001; 4683B[39] = 19'b00010010011_010_00_001; 4684B[71] = 19'b00010100101_010_00_001; 4685B[103] = 19'b00010110111_010_00_001; 4686B[135] = 19'b111010x10x1_xxx_00_xxx; 4687B[167] = 19'bxx0010x10x1_011_00_001; 4688B[199] = 19'b00011101101_000_00_001; 4689B[231] = 19'b00011111111_010_00_001; 4690B[8] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4691B[40] = 19'bxxxxxxxxxx0_000_00_100; 4692B[72] = 19'b001010x10x0_xxx_00_xxx; 4693B[104] = 19'bxx0010x10x0_010_00_001; 4694B[136] = 19'b011011010x0_100_00_001; 4695B[168] = 19'b001010x10x0_100_00_001; 4696B[200] = 19'b011011110x0_100_00_001; 4697B[232] = 19'b101011110x0_001_00_001; 4698B[9] = 19'b000010x0001_010_00_001; 4699B[41] = 19'b000010x0011_010_00_001; 4700B[73] = 19'b000010x0101_010_00_001; 4701B[105] = 19'b000010x0111_010_00_001; 4702B[137] = 19'b001010x10x1_xxx_00_xxx; 4703B[169] = 19'bxx0010x10x1_010_00_001; 4704B[201] = 19'b000010x1101_000_00_001; 4705B[233] = 19'b000010x1111_010_00_001; 4706B[10] = 19'b001000010x0_010_00_001; 4707B[42] = 19'b001000110x0_010_00_001; 4708B[74] = 19'b001001010x0_010_00_001; 4709B[106] = 19'b001001110x0_010_00_001; 4710B[138] = 19'b101010x10x0_010_00_001; 4711B[170] = 19'b001010x10x0_001_00_001; 4712B[202] = 19'b101011010x0_001_00_001; 4713B[234] = 19'bxx0111110x0_000_00_001; 4714B[11] = 19'b000010x0001_010_00_001; 4715B[43] = 19'b000010x0011_010_00_001; 4716B[75] = 19'b000010x0101_010_00_001; 4717B[107] = 19'b000010x0111_010_00_001; 4718B[139] = 19'b111010x10x1_xxx_00_xxx; 4719B[171] = 19'bxx0010x10x1_011_00_001; 4720B[203] = 19'b000010x1101_000_00_001; 4721B[235] = 19'b000010x1111_010_00_001; 4722B[12] = 19'b000010x0000_xxx_00_xxx; 4723B[44] = 19'b000010x0010_000_00_001; 4724B[76] = 19'bxxxxxxxxxx0_000_00_001; 4725B[108] = 19'bxxxxxxxxxx0_000_00_001; 4726B[140] = 19'b011010x10x0_xxx_00_xxx; 4727B[172] = 19'bxx0010x10x0_100_00_001; 4728B[204] = 19'b010010x1100_000_00_001; 4729B[236] = 19'b100010x1100_000_00_001; 4730B[13] = 19'b000010x0001_010_00_001; 4731B[45] = 19'b000010x0011_010_00_001; 4732B[77] = 19'b000010x0101_010_00_001; 4733B[109] = 19'b000010x0111_010_00_001; 4734B[141] = 19'b001010x10x1_xxx_00_xxx; 4735B[173] = 19'bxx0010x10x1_010_00_001; 4736B[205] = 19'b000010x1101_000_00_001; 4737B[237] = 19'b000010x1111_010_00_001; 4738B[14] = 19'bxx0100010x0_000_00_001; 4739B[46] = 19'bxx0100110x0_000_00_001; 4740B[78] = 19'bxx0101010x0_000_00_001; 4741B[110] = 19'bxx0101110x0_000_00_001; 4742B[142] = 19'b101010x10x0_xxx_00_xxx; 4743B[174] = 19'bxx0010x10x0_001_00_001; 4744B[206] = 19'bxx0111010x0_000_00_001; 4745B[238] = 19'bxx0111110x0_000_00_001; 4746B[15] = 19'b00010000001_010_00_001; 4747B[47] = 19'b00010010011_010_00_001; 4748B[79] = 19'b00010100101_010_00_001; 4749B[111] = 19'b00010110111_010_00_001; 4750B[143] = 19'b111010x10x1_xxx_00_xxx; 4751B[175] = 19'bxx0010x10x1_011_00_001; 4752B[207] = 19'b00011101101_000_00_001; 4753B[239] = 19'b00011111111_010_00_001; 4754B[16] = 19'bxxxxxxxxxx0_xxx_11_xxx; 4755B[48] = 19'bxxxxxxxxxx0_xxx_11_xxx; 4756B[80] = 19'bxxxxxxxxxx0_xxx_11_xxx; 4757B[112] = 19'bxxxxxxxxxx0_xxx_11_xxx; 4758B[144] = 19'b011010x10x0_xxx_11_xxx; 4759B[176] = 19'bxx0010x10x0_xxx_11_xxx; 4760B[208] = 19'bxxxxxxxxxx0_xxx_11_xxx; 4761B[240] = 19'bxxxxxxxxxx0_xxx_11_xxx; 4762B[17] = 19'b000010x0001_010_11_001; 4763B[49] = 19'b000010x0011_010_11_001; 4764B[81] = 19'b000010x0101_010_11_001; 4765B[113] = 19'b000010x0111_010_11_001; 4766B[145] = 19'b001010x10x1_xxx_11_xxx; 4767B[177] = 19'bxx0010x10x1_010_11_001; 4768B[209] = 19'b000010x1101_000_11_001; 4769B[241] = 19'b000010x1111_010_11_001; 4770B[18] = 19'bxx0100010x0_000_11_001; 4771B[50] = 19'bxx0100110x0_000_11_001; 4772B[82] = 19'bxx0101010x0_000_11_001; 4773B[114] = 19'bxx0101110x0_000_11_001; 4774B[146] = 19'b101010x10x0_xxx_11_xxx; 4775B[178] = 19'bxx0010x10x0_xxx_11_xxx; 4776B[210] = 19'bxx0111010x0_000_11_001; 4777B[242] = 19'bxx0111110x0_000_11_001; 4778B[19] = 19'b00010000001_010_11_001; 4779B[51] = 19'b00010010011_010_11_001; 4780B[83] = 19'b00010100101_010_11_001; 4781B[115] = 19'b00010110111_010_11_001; 4782B[147] = 19'b111010x10x1_xxx_11_xxx; 4783B[179] = 19'bxx0010x10x1_011_11_001; 4784B[211] = 19'b00011101101_000_11_001; 4785B[243] = 19'b00011111111_010_11_001; 4786B[20] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4787B[52] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4788B[84] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4789B[116] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4790B[148] = 19'b011010x10x0_xxx_00_xxx; 4791B[180] = 19'bxx0010x10x0_100_00_001; 4792B[212] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4793B[244] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4794B[21] = 19'b000010x0001_010_00_001; 4795B[53] = 19'b000010x0011_010_00_001; 4796B[85] = 19'b000010x0101_010_00_001; 4797B[117] = 19'b000010x0111_010_00_001; 4798B[149] = 19'b001010x10x1_xxx_00_xxx; 4799B[181] = 19'bxx0010x10x1_010_00_001; 4800B[213] = 19'b000010x1101_000_00_001; 4801B[245] = 19'b000010x1111_010_00_001; 4802B[22] = 19'bxx0100010x0_000_00_001; 4803B[54] = 19'bxx0100110x0_000_00_001; 4804B[86] = 19'bxx0101010x0_000_00_001; 4805B[118] = 19'bxx0101110x0_000_00_001; 4806B[150] = 19'b101010x10x0_xxx_10_xxx; 4807B[182] = 19'bxx0010x10x0_001_10_001; 4808B[214] = 19'bxx0111010x0_000_00_001; 4809B[246] = 19'bxx0111110x0_000_00_001; 4810B[23] = 19'b00010000001_010_00_001; 4811B[55] = 19'b00010010011_010_00_001; 4812B[87] = 19'b00010100101_010_00_001; 4813B[119] = 19'b00010110111_010_00_001; 4814B[151] = 19'b111010x10x1_xxx_10_xxx; 4815B[183] = 19'bxx0010x10x1_011_10_001; 4816B[215] = 19'b00011101101_000_00_001; 4817B[247] = 19'b00011111111_010_00_001; 4818B[24] = 19'bxxxxxxxxxx0_000_10_101; 4819B[56] = 19'bxxxxxxxxxx0_000_10_101; 4820B[88] = 19'bxxxxxxxxxx0_000_10_110; 4821B[120] = 19'bxxxxxxxxxx0_000_10_110; 4822B[152] = 19'b011010x10x0_010_10_001; 4823B[184] = 19'bxx1110x10x0_000_10_011; 4824B[216] = 19'bxxxxxxxxxx0_000_10_111; 4825B[248] = 19'bxxxxxxxxxx0_000_10_111; 4826B[25] = 19'b000010x0001_010_10_001; 4827B[57] = 19'b000010x0011_010_10_001; 4828B[89] = 19'b000010x0101_010_10_001; 4829B[121] = 19'b000010x0111_010_10_001; 4830B[153] = 19'b001010x10x1_xxx_10_xxx; 4831B[185] = 19'bxx0010x10x1_010_10_001; 4832B[217] = 19'b000010x1101_000_10_001; 4833B[249] = 19'b000010x1111_010_10_001; 4834B[26] = 19'bxx0100010x0_000_10_001; 4835B[58] = 19'bxx0100110x0_000_10_001; 4836B[90] = 19'bxx0101010x0_000_10_001; 4837B[122] = 19'bxx0101110x0_000_10_001; 4838B[154] = 19'b101010x10x0_xxx_10_xxx; 4839B[186] = 19'bxx1110x10x0_001_10_001; 4840B[218] = 19'bxx0111010x0_000_10_001; 4841B[250] = 19'bxx0111110x0_000_10_001; 4842B[27] = 19'b00010000001_010_10_001; 4843B[59] = 19'b00010010011_010_10_001; 4844B[91] = 19'b00010100101_010_10_001; 4845B[123] = 19'b00010110111_010_10_001; 4846B[155] = 19'b111010x10x1_xxx_10_xxx; 4847B[187] = 19'bxx0010x10x1_xxx_10_xxx; 4848B[219] = 19'b00011101101_000_10_001; 4849B[251] = 19'b00011111111_010_10_001; 4850B[28] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4851B[60] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4852B[92] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4853B[124] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4854B[156] = 19'b011010x10x0_xxx_00_xxx; 4855B[188] = 19'bxx0010x10x0_100_00_001; 4856B[220] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4857B[252] = 19'bxxxxxxxxxx0_xxx_00_xxx; 4858B[29] = 19'b000010x0001_010_00_001; 4859B[61] = 19'b000010x0011_010_00_001; 4860B[93] = 19'b000010x0101_010_00_001; 4861B[125] = 19'b000010x0111_010_00_001; 4862B[157] = 19'b001010x10x1_xxx_00_xxx; 4863B[189] = 19'bxx0010x10x1_010_00_001; 4864B[221] = 19'b000010x1101_000_00_001; 4865B[253] = 19'b000010x1111_010_00_001; 4866B[30] = 19'bxx0100010x0_000_00_001; 4867B[62] = 19'bxx0100110x0_000_00_001; 4868B[94] = 19'bxx0101010x0_000_00_001; 4869B[126] = 19'bxx0101110x0_000_00_001; 4870B[158] = 19'b101010x10x0_xxx_10_xxx; 4871B[190] = 19'bxx0010x10x0_001_10_001; 4872B[222] = 19'bxx0111010x0_000_00_001; 4873B[254] = 19'bxx0111110x0_000_00_001; 4874B[31] = 19'b00010000001_010_00_001; 4875B[63] = 19'b00010010011_010_00_001; 4876B[95] = 19'b00010100101_010_00_001; 4877B[127] = 19'b00010110111_010_00_001; 4878B[159] = 19'b111010x10x1_xxx_10_xxx; 4879B[191] = 19'bxx0010x10x1_011_10_001; 4880B[223] = 19'b00011101101_000_00_001; 4881B[255] = 19'b00011111111_010_00_001; 4882 end 4883 wire [14:0] R = A[M[4:0]]; 4884 reg [18:0] AluFlags; 4885 always @(posedge clk) if (reset) begin 4886 AluFlags <= 0; 4887 end else if (ce) begin 4888 AluFlags <= B[IR]; 4889 end 4890 4891 assign Mout = {AluFlags,// 19 4892 M[8:7], // NextState // 2 4893 R[14:13],// LoadT // 2 4894 R[12], // FlagCtrl // 1 4895 R[11:7], // AddrCtrl // 5 4896 R[6:4], // MemWrite // 3 4897 M[6:5], // AddrBus // 2 4898 R[3:2], // LoadPC // 2 4899 R[1:0] // LoadSP // 2 4900 }; 4901endmodule 4902 4903module sigma_delta_dac( 4904 output reg DACout, //Average Output feeding analog lowpass 4905 input [MSBI:0] DACin, //DAC input (excess 2**MSBI) 4906 input CLK, 4907 input CEN, 4908 input RESET 4909); 4910 4911parameter MSBI = 7; 4912 4913reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder 4914reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder 4915reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder 4916reg [MSBI+2:0] DeltaB; //B input of Delta Adder 4917 4918always @ (*) 4919 DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1); 4920 4921always @(*) 4922 DeltaAdder = DACin + DeltaB; 4923 4924always @(*) 4925 SigmaAdder = DeltaAdder + SigmaLatch; 4926 4927always @(posedge CLK) 4928 begin 4929 SigmaLatch <= SigmaAdder; 4930 DACout <= SigmaLatch[MSBI+2]; 4931 end 4932endmodule // Copyright (c) 2012-2013 Ludvig Strigeus 4933// Copyright (c) 2017 David Shah 4934// This program is GPL Licensed. See COPYING for the full license. 4935 4936`timescale 1ns / 1ps 4937 4938module top ( 4939 // clock input 4940 input clock_16, 4941 output led0, led1, 4942 4943 // VGA 4944 output vga_HS, // VGA H_SYNC 4945 output vga_VS, // VGA V_SYNC 4946 output [ 3:0] vga_R, // VGA Red[3:0] 4947 output [ 3:0] vga_G, // VGA Green[3:0] 4948 output [ 3:0] vga_B, // VGA Blue[3:0] 4949 4950 4951 // audio 4952 output audio_o, 4953 4954 // joystick 4955 output joy_strobe, joy_clock, 4956 input joy_data, 4957 4958 // flashmem 4959 output flash_sck, 4960 output flash_csn, 4961 output flash_mosi, 4962 input flash_miso, 4963 4964 input [4:0] buttons 4965 4966); 4967 wire clock; 4968 4969wire [4:0] sel_btn; 4970 4971 4972assign sel_btn = buttons; 4973 4974 4975 wire scandoubler_disable; 4976 4977 reg clock_locked; 4978 wire locked_pre; 4979 always @(posedge clock) 4980 clock_locked <= locked_pre; 4981 4982 wire [8:0] cycle; 4983 wire [8:0] scanline; 4984 wire [15:0] sample; 4985 wire [5:0] color; 4986 4987 wire load_done; 4988 wire [21:0] memory_addr; 4989 wire memory_read_cpu, memory_read_ppu; 4990 wire memory_write; 4991 wire [7:0] memory_din_cpu, memory_din_ppu; 4992 wire [7:0] memory_dout; 4993 4994 wire [31:0] mapper_flags; 4995 4996 pll pll_i ( 4997 .clock_in(clock_16), 4998 .clock_out(clock), 4999 .locked(locked_pre) 5000 ); 5001 5002 assign led0 = memory_addr[0]; 5003 assign led1 = !load_done; 5004 5005 wire sys_reset = !clock_locked; 5006 reg reload; 5007 reg [2:0] last_pressed; 5008 reg [3:0] btn_dly; 5009 always @ ( posedge clock ) begin 5010 //Detect button release and trigger reload 5011 btn_dly <= sel_btn[3:0]; 5012 if (sel_btn[3:0] == 4'b1111 && btn_dly != 4'b1111) 5013 reload <= 1'b1; 5014 else 5015 reload <= 1'b0; 5016 // Button 4 is a "shift" 5017 if(!sel_btn[0]) 5018 last_pressed <= {!sel_btn[4], 2'b00}; 5019 else if(!sel_btn[1]) 5020 last_pressed <= {!sel_btn[4], 2'b01}; 5021 else if(!sel_btn[2]) 5022 last_pressed <= {!sel_btn[4], 2'b10}; 5023 else if(!sel_btn[3]) 5024 last_pressed <= {!sel_btn[4], 2'b11}; 5025 end 5026 5027 main_mem mem ( 5028 .clock(clock), 5029 .reset(sys_reset), 5030 .reload(reload), 5031 .index({1'b0, last_pressed}), 5032 .load_done(load_done), 5033 .flags_out(mapper_flags), 5034 //NES interface 5035 .mem_addr(memory_addr), 5036 .mem_rd_cpu(memory_read_cpu), 5037 .mem_rd_ppu(memory_read_ppu), 5038 .mem_wr(memory_write), 5039 .mem_q_cpu(memory_din_cpu), 5040 .mem_q_ppu(memory_din_ppu), 5041 .mem_d(memory_dout), 5042 5043 //Flash load interface 5044 .flash_csn(flash_csn), 5045 .flash_sck(flash_sck), 5046 .flash_mosi(flash_mosi), 5047 .flash_miso(flash_miso) 5048 ); 5049 5050 wire reset_nes = !load_done || sys_reset; 5051 reg [1:0] nes_ce; 5052 wire run_nes = (nes_ce == 3); // keep running even when reset, so that the reset can actually do its job! 5053 5054 wire run_nes_g = run_nes; 5055 5056 // NES is clocked at every 4th cycle. 5057 always @(posedge clock) 5058 nes_ce <= nes_ce + 1; 5059 5060 wire [31:0] dbgadr; 5061 wire [1:0] dbgctr; 5062 5063 NES nes(clock, reset_nes, run_nes_g, 5064 mapper_flags, 5065 sample, color, 5066 joy_strobe, joy_clock, {3'b0,!joy_data}, 5067 5'b11111, // enable all channels 5068 memory_addr, 5069 memory_read_cpu, memory_din_cpu, 5070 memory_read_ppu, memory_din_ppu, 5071 memory_write, memory_dout, 5072 cycle, scanline, 5073 dbgadr, 5074 dbgctr); 5075 5076 5077video video ( 5078 .clk(clock), 5079 5080 .color(color), 5081 .count_v(scanline), 5082 .count_h(cycle), 5083 .mode(1'b0), 5084 .smoothing(1'b1), 5085 .scanlines(1'b1), 5086 .overscan(1'b1), 5087 .palette(1'b0), 5088 5089 .VGA_HS(vga_HS), 5090 .VGA_VS(vga_VS), 5091 .VGA_R(vga_R), 5092 .VGA_G(vga_G), 5093 .VGA_B(vga_B) 5094 5095); 5096 5097wire audio; 5098sigma_delta_dac sigma_delta_dac ( 5099 .DACout(audio), 5100 .DACin(sample[15:8]), 5101 .CLK(clock), 5102 .RESET(reset_nes), 5103 .CEN(run_nes) 5104); 5105assign audio_o = audio; 5106 5107endmodule 5108// Copyright (c) 2012-2013 Ludvig Strigeus 5109// This program is GPL Licensed. See COPYING for the full license. 5110 5111// No mapper chip 5112module MMC0(input clk, input ce, 5113 input [31:0] flags, 5114 input [15:0] prg_ain, output [21:0] prg_aout, 5115 input prg_read, prg_write, // Read / write signals 5116 input [7:0] prg_din, 5117 output prg_allow, // Enable access to memory for the specified operation. 5118 input [13:0] chr_ain, output [21:0] chr_aout, 5119 output chr_allow, // Allow write 5120 output vram_a10, // Value for A10 address line 5121 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 5122 assign prg_aout = {7'b00_0000_0, prg_ain[14:0]}; 5123 assign prg_allow = prg_ain[15] && !prg_write; 5124 assign chr_allow = flags[15]; 5125 assign chr_aout = {9'b10_0000_000, chr_ain[12:0]}; 5126 assign vram_ce = chr_ain[13]; 5127 assign vram_a10 = flags[14] ? chr_ain[10] : chr_ain[11]; 5128endmodule 5129 5130// MMC1 mapper chip. Maps prg or chr addresses into a linear address. 5131// If vram_ce is set, {vram_a10, chr_aout[9:0]} are used to access the NES internal VRAM instead. 5132module MMC1(input clk, input ce, input reset, 5133 input [31:0] flags, 5134 input [15:0] prg_ain, output [21:0] prg_aout, 5135 input prg_read, prg_write, // Read / write signals 5136 input [7:0] prg_din, 5137 output prg_allow, // Enable access to memory for the specified operation. 5138 input [13:0] chr_ain, output [21:0] chr_aout, 5139 output chr_allow, // Allow write 5140 output vram_a10, // Value for A10 address line 5141 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 5142 reg [4:0] shift; 5143 5144// CPPMM 5145// ||||| 5146// |||++- Mirroring (0: one-screen, lower bank; 1: one-screen, upper bank; 5147// ||| 2: vertical; 3: horizontal) 5148// |++--- PRG ROM bank mode (0, 1: switch 32 KB at $8000, ignoring low bit of bank number; 5149// | 2: fix first bank at $8000 and switch 16 KB bank at $C000; 5150// | 3: fix last bank at $C000 and switch 16 KB bank at $8000) 5151// +----- CHR ROM bank mode (0: switch 8 KB at a time; 1: switch two separate 4 KB banks) 5152 reg [4:0] control; 5153 5154// CCCCC 5155// ||||| 5156// +++++- Select 4 KB or 8 KB CHR bank at PPU $0000 (low bit ignored in 8 KB mode) 5157 reg [4:0] chr_bank_0; 5158 5159// CCCCC 5160// ||||| 5161// +++++- Select 4 KB CHR bank at PPU $1000 (ignored in 8 KB mode) 5162 reg [4:0] chr_bank_1; 5163 5164// RPPPP 5165// ||||| 5166// |++++- Select 16 KB PRG ROM bank (low bit ignored in 32 KB mode) 5167// +----- PRG RAM chip enable (0: enabled; 1: disabled; ignored on MMC1A) 5168 reg [4:0] prg_bank; 5169 5170 reg delay_ctrl; // used to prevent fast-write to the control register 5171 5172 wire [2:0] prg_size = flags[10:8]; 5173 5174 // Update shift register 5175 always @(posedge clk) if (reset) begin 5176 shift <= 5'b10000; 5177 control <= 5'b0_11_00; 5178 chr_bank_0 <= 0; 5179 chr_bank_1 <= 0; 5180 prg_bank <= 5'b00000; 5181 delay_ctrl <= 0; 5182 end else if (ce) begin 5183 if (!prg_write) 5184 delay_ctrl <= 1'b0; 5185 if (prg_write && prg_ain[15] && !delay_ctrl) begin 5186 delay_ctrl <= 1'b1; 5187 if (prg_din[7]) begin 5188 shift <= 5'b10000; 5189 control <= control | 5'b0_11_00; 5190// $write("MMC1 RESET!\n"); 5191 end else begin 5192 if (shift[0]) begin 5193// $write("MMC1 WRITE %X to %X!\n", {prg_din[0], shift[4:1]}, prg_ain); 5194 casez(prg_ain[14:13]) 5195 0: control <= {prg_din[0], shift[4:1]}; 5196 1: chr_bank_0 <= {prg_din[0], shift[4:1]}; 5197 2: chr_bank_1 <= {prg_din[0], shift[4:1]}; 5198 3: prg_bank <= {prg_din[0], shift[4:1]}; 5199 endcase 5200 shift <= 5'b10000; 5201 end else begin 5202 shift <= {prg_din[0], shift[4:1]}; 5203 end 5204 end 5205 end 5206 end 5207 5208 // The PRG bank to load. Each increment here is 16kb. So valid values are 0..15. 5209 // prg_ain[14] selects bank0 ($8000) or bank1 ($C000) 5210 reg [3:0] prgsel; 5211 always @* begin 5212 casez({control[3:2], prg_ain[14]}) 5213 3'b0?_?: prgsel = {prg_bank[3:1], prg_ain[14]}; // Swap 32Kb 5214 3'b10_0: prgsel = 4'b0000; // Swap 16Kb at $C000 with access at $8000, so select page 0 (hardcoded) 5215 3'b10_1: prgsel = prg_bank[3:0]; // Swap 16Kb at $C000 with $C000 access, so select page based on prg_bank (register 3) 5216 3'b11_0: prgsel = prg_bank[3:0]; // Swap 16Kb at $8000 with $8000 access, so select page based on prg_bank (register 3) 5217 3'b11_1: prgsel = 4'b1111; // Swap 16Kb at $8000 with $C000 access, so select last page (hardcoded) 5218 endcase 5219 end 5220 5221 // The CHR bank to load. Each increment here is 4 kb. So valid values are 0..31. 5222 reg [4:0] chrsel; 5223 always @* begin 5224 casez({control[4], chr_ain[12]}) 5225 2'b0_?: chrsel = {chr_bank_0[4:1], chr_ain[12]}; 5226 2'b1_0: chrsel = chr_bank_0; 5227 2'b1_1: chrsel = chr_bank_1; 5228 endcase 5229 end 5230 assign chr_aout = {5'b100_00, chrsel, chr_ain[11:0]}; 5231 wire [21:0] prg_aout_tmp = prg_size == 5 ? {3'b000, chrsel[4], prgsel, prg_ain[13:0]} // for large PRG ROM, CHR A16 selects the 256KB PRG bank 5232 : {4'b00_00, prgsel, prg_ain[13:0]}; 5233 5234 // The a10 VRAM address line. (Used for mirroring) 5235 reg vram_a10_t; 5236 always @* begin 5237 casez(control[1:0]) 5238 2'b00: vram_a10_t = 0; // One screen, lower bank 5239 2'b01: vram_a10_t = 1; // One screen, upper bank 5240 2'b10: vram_a10_t = chr_ain[10]; // One screen, vertical 5241 2'b11: vram_a10_t = chr_ain[11]; // One screen, horizontal 5242 endcase 5243 end 5244 assign vram_a10 = vram_a10_t; 5245 assign vram_ce = chr_ain[13]; 5246 5247 wire prg_is_ram = prg_ain >= 'h6000 && prg_ain < 'h8000; 5248 assign prg_allow = prg_ain[15] && !prg_write || prg_is_ram; 5249 wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]}; 5250 5251 assign prg_aout = prg_is_ram ? prg_ram : prg_aout_tmp; 5252 assign chr_allow = flags[15]; 5253endmodule 5254 5255// MMC2 mapper chip. PRG ROM: 128kB. Bank Size: 8kB. CHR ROM: 128kB 5256module MMC2(input clk, input ce, input reset, 5257 input [31:0] flags, 5258 input [15:0] prg_ain, output [21:0] prg_aout, 5259 input prg_read, prg_write, // Read / write signals 5260 input [7:0] prg_din, 5261 output prg_allow, // Enable access to memory for the specified operation. 5262 input chr_read, input [13:0] chr_ain, output [21:0] chr_aout, 5263 output chr_allow, // Allow write 5264 output vram_a10, // Value for A10 address line 5265 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 5266 5267// PRG ROM bank select ($A000-$AFFF) 5268// 7 bit 0 5269// ---- ---- 5270// xxxx PPPP 5271// |||| 5272// ++++- Select 8 KB PRG ROM bank for CPU $8000-$9FFF 5273 reg [3:0] prg_bank; 5274 5275// CHR ROM $FD/0000 bank select ($B000-$BFFF) 5276// 7 bit 0 5277// ---- ---- 5278// xxxC CCCC 5279// | |||| 5280// +-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF 5281// used when latch 0 = $FD 5282 reg [4:0] chr_bank_0a; 5283 5284// CHR ROM $FE/0000 bank select ($C000-$CFFF) 5285// 7 bit 0 5286// ---- ---- 5287// xxxC CCCC 5288// | |||| 5289// +-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF 5290// used when latch 0 = $FE 5291 reg [4:0] chr_bank_0b; 5292 5293// CHR ROM $FD/1000 bank select ($D000-$DFFF) 5294// 7 bit 0 5295// ---- ---- 5296// xxxC CCCC 5297// | |||| 5298// +-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF 5299// used when latch 1 = $FD 5300 reg [4:0] chr_bank_1a; 5301 5302// CHR ROM $FE/1000 bank select ($E000-$EFFF) 5303// 7 bit 0 5304// ---- ---- 5305// xxxC CCCC 5306// | |||| 5307// +-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF 5308// used when latch 1 = $FE 5309 reg [4:0] chr_bank_1b; 5310 5311// Mirroring ($F000-$FFFF) 5312// 7 bit 0 5313// ---- ---- 5314// xxxx xxxM 5315// | 5316// +- Select nametable mirroring (0: vertical; 1: horizontal) 5317 reg mirroring; 5318 5319 reg latch_0, latch_1; 5320 5321 // Update registers 5322 always @(posedge clk) if (ce) begin 5323 if (prg_write && prg_ain[15]) begin 5324 case(prg_ain[14:12]) 5325 2: prg_bank <= prg_din[3:0]; // $A000 5326 3: chr_bank_0a <= prg_din[4:0]; // $B000 5327 4: chr_bank_0b <= prg_din[4:0]; // $C000 5328 5: chr_bank_1a <= prg_din[4:0]; // $D000 5329 6: chr_bank_1b <= prg_din[4:0]; // $E000 5330 7: mirroring <= prg_din[0]; // $F000 5331 endcase 5332 end 5333 end 5334 5335// PPU reads $0FD8: latch 0 is set to $FD for subsequent reads 5336// PPU reads $0FE8: latch 0 is set to $FE for subsequent reads 5337// PPU reads $1FD8 through $1FDF: latch 1 is set to $FD for subsequent reads 5338// PPU reads $1FE8 through $1FEF: latch 1 is set to $FE for subsequent reads 5339 always @(posedge clk) if (ce && chr_read) begin 5340 latch_0 <= (chr_ain & 14'h3fff) == 14'h0fd8 ? 0 : (chr_ain & 14'h3fff) == 14'h0fe8 ? 1 : latch_0; 5341 latch_1 <= (chr_ain & 14'h3ff8) == 14'h1fd8 ? 0 : (chr_ain & 14'h3ff8) == 14'h1fe8 ? 1 : latch_1; 5342 end 5343 5344 // The PRG bank to load. Each increment here is 8kb. So valid values are 0..15. 5345 reg [3:0] prgsel; 5346 always @* begin 5347 casez(prg_ain[14:13]) 5348 2'b00: prgsel = prg_bank; 5349 default: prgsel = {2'b11, prg_ain[14:13]}; 5350 endcase 5351 end 5352 assign prg_aout = {5'b00_000, prgsel, prg_ain[12:0]}; 5353 5354 // The CHR bank to load. Each increment here is 4kb. So valid values are 0..31. 5355 reg [4:0] chrsel; 5356 always @* begin 5357 casez({chr_ain[12], latch_0, latch_1}) 5358 3'b00?: chrsel = chr_bank_0a; 5359 3'b01?: chrsel = chr_bank_0b; 5360 3'b1?0: chrsel = chr_bank_1a; 5361 3'b1?1: chrsel = chr_bank_1b; 5362 endcase 5363 end 5364 assign chr_aout = {5'b100_00, chrsel, chr_ain[11:0]}; 5365 5366 // The a10 VRAM address line. (Used for mirroring) 5367 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 5368 assign vram_ce = chr_ain[13]; 5369 5370 assign prg_allow = prg_ain[15] && !prg_write; 5371 assign chr_allow = flags[15]; 5372endmodule 5373 5374// This mapper also handles mapper 47,118,119 and 206. 5375module MMC3(input clk, input ce, input reset, 5376 input [31:0] flags, 5377 input [15:0] prg_ain, output [21:0] prg_aout, 5378 input prg_read, prg_write, // Read / write signals 5379 input [7:0] prg_din, 5380 output prg_allow, // Enable access to memory for the specified operation. 5381 input [13:0] chr_ain, output [21:0] chr_aout, 5382 output chr_allow, // Allow write 5383 output vram_a10, // Value for A10 address line 5384 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 5385 output reg irq); 5386 reg [2:0] bank_select; // Register to write to next 5387 reg prg_rom_bank_mode; // Mode for PRG banking 5388 reg chr_a12_invert; // Mode for CHR banking 5389 reg mirroring; // 0 = vertical, 1 = horizontal 5390 reg irq_enable, irq_reload; // IRQ enabled, and IRQ reload requested 5391 reg [7:0] irq_latch, counter; // IRQ latch value and current counter 5392 reg ram_enable, ram_protect; // RAM protection bits 5393 reg [6:0] chr_bank_0, chr_bank_1; // Selected CHR banks 5394 reg [7:0] chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5; 5395 reg [5:0] prg_bank_0, prg_bank_1; // Selected PRG banks 5396 wire prg_is_ram; 5397 5398 // The alternative behavior has slightly different IRQ counter semantics. 5399 wire mmc3_alt_behavior = 0; 5400 5401 wire TQROM = (flags[7:0] == 119); // TQROM maps 8kB CHR RAM 5402 wire TxSROM = (flags[7:0] == 118); // Connects CHR A17 to CIRAM A10 5403 wire mapper47 = (flags[7:0] == 47); // Mapper 47 is a multicart that has 128k for each game. It has no RAM. 5404 wire DxROM = (flags[7:0] == 206); 5405 5406 wire four_screen_mirroring = flags[16] | DxROM; 5407 reg mapper47_multicart; 5408 wire [7:0] new_counter = (counter == 0 || irq_reload) ? irq_latch : counter - 1; 5409 reg [3:0] a12_ctr; 5410 5411 always @(posedge clk) if (reset) begin 5412 irq <= 0; 5413 bank_select <= 0; 5414 prg_rom_bank_mode <= 0; 5415 chr_a12_invert <= 0; 5416 mirroring <= flags[14]; 5417 {irq_enable, irq_reload} <= 0; 5418 {irq_latch, counter} <= 0; 5419 {ram_enable, ram_protect} <= 0; 5420 {chr_bank_0, chr_bank_1} <= 0; 5421 {chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5} <= 0; 5422 {prg_bank_0, prg_bank_1} <= 0; 5423 a12_ctr <= 0; 5424 end else if (ce) begin 5425 if (prg_write && prg_ain[15]) begin 5426 case({prg_ain[14], prg_ain[13], prg_ain[0]}) 5427 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, bank_select} <= {prg_din[7], prg_din[6], prg_din[2:0]}; // Bank select ($8000-$9FFE, even) 5428 3'b00_1: begin // Bank data ($8001-$9FFF, odd) 5429 case (bank_select) 5430 0: chr_bank_0 <= prg_din[7:1]; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); 5431 1: chr_bank_1 <= prg_din[7:1]; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); 5432 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); 5433 3: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); 5434 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); 5435 5: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); 5436 6: prg_bank_0 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); 5437 7: prg_bank_1 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF 5438 endcase 5439 end 5440 3'b01_0: mirroring <= prg_din[0]; // Mirroring ($A000-$BFFE, even) 5441 3'b01_1: {ram_enable, ram_protect} <= prg_din[7:6]; // PRG RAM protect ($A001-$BFFF, odd) 5442 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) 5443 3'b10_1: irq_reload <= 1; // IRQ reload ($C001-$DFFF, odd) 5444 3'b11_0: begin irq_enable <= 0; irq <= 0; end // IRQ disable ($E000-$FFFE, even) 5445 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) 5446 endcase 5447 end 5448 5449 // For Mapper 47 5450 // $6000-7FFF: [.... ...B] Block select 5451 if (prg_write && prg_is_ram) 5452 mapper47_multicart <= prg_din[0]; 5453 5454 // Trigger IRQ counter on rising edge of chr_ain[12] 5455 // All MMC3A's and non-Sharp MMC3B's will generate only a single IRQ when $C000 is $00. 5456 // This is because this version of the MMC3 generates IRQs when the scanline counter is decremented to 0. 5457 // In addition, writing to $C001 with $C000 still at $00 will result in another single IRQ being generated. 5458 // In the community, this is known as the "alternate" or "old" behavior. 5459 // All MMC3C's and Sharp MMC3B's will generate an IRQ on each scanline while $C000 is $00. 5460 // This is because this version of the MMC3 generates IRQs when the scanline counter is equal to 0. 5461 // In the community, this is known as the "normal" or "new" behavior. 5462 if (chr_ain[12] && a12_ctr == 0) begin 5463 counter <= new_counter; 5464 if ( (!mmc3_alt_behavior || counter != 0 || irq_reload) && new_counter == 0 && irq_enable) begin 5465// $write("MMC3 SCANLINE IRQ!\n"); 5466 irq <= 1; 5467 end 5468 irq_reload <= 0; 5469 end 5470 a12_ctr <= chr_ain[12] ? 4'b1111 : (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; 5471 end 5472 5473 // The PRG bank to load. Each increment here is 8kb. So valid values are 0..63. 5474 reg [5:0] prgsel; 5475 always @* begin 5476 casez({prg_ain[14:13], prg_rom_bank_mode}) 5477 3'b00_0: prgsel = prg_bank_0; // $8000 mode 0 5478 3'b00_1: prgsel = 6'b111110; // $8000 fixed to second last bank 5479 3'b01_?: prgsel = prg_bank_1; // $A000 mode 0,1 5480 3'b10_0: prgsel = 6'b111110; // $C000 fixed to second last bank 5481 3'b10_1: prgsel = prg_bank_0; // $C000 mode 1 5482 3'b11_?: prgsel = 6'b111111; // $E000 fixed to last bank 5483 endcase 5484 // mapper47 is limited to 128k PRG, the top bits are controlled by mapper47_multicart instead. 5485 if (mapper47) prgsel[5:4] = {1'b0, mapper47_multicart}; 5486 end 5487 5488 // The CHR bank to load. Each increment here is 1kb. So valid values are 0..255. 5489 reg [7:0] chrsel; 5490 always @* begin 5491 casez({chr_ain[12] ^ chr_a12_invert, chr_ain[11], chr_ain[10]}) 5492 3'b00?: chrsel = {chr_bank_0, chr_ain[10]}; 5493 3'b01?: chrsel = {chr_bank_1, chr_ain[10]}; 5494 3'b100: chrsel = chr_bank_2; 5495 3'b101: chrsel = chr_bank_3; 5496 3'b110: chrsel = chr_bank_4; 5497 3'b111: chrsel = chr_bank_5; 5498 endcase 5499 // mapper47 is limited to 128k CHR, the top bit is controlled by mapper47_multicart instead. 5500 if (mapper47) chrsel[7] = mapper47_multicart; 5501 end 5502 5503 wire [21:0] prg_aout_tmp = {3'b00_0, prgsel, prg_ain[12:0]}; 5504 5505 assign {chr_allow, chr_aout} = 5506 (TQROM && chrsel[6]) ? {1'b1, 9'b11_1111_111, chrsel[2:0], chr_ain[9:0]} : // TQROM 8kb CHR-RAM 5507 (four_screen_mirroring && chr_ain[13]) ? {1'b1, 9'b11_1111_111, chr_ain[13], chr_ain[11:0]} : // DxROM 8kb CHR-RAM 5508 {flags[15], 4'b10_00, chrsel, chr_ain[9:0]}; // Standard MMC3 5509 5510 assign prg_is_ram = prg_ain >= 'h6000 && prg_ain < 'h8000 && ram_enable && !(ram_protect && prg_write); 5511 assign prg_allow = prg_ain[15] && !prg_write || prg_is_ram && !mapper47; 5512 wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]}; 5513 assign prg_aout = prg_is_ram && !mapper47 && !DxROM ? prg_ram : prg_aout_tmp; 5514 assign vram_a10 = !TxSROM ? (mirroring ? chr_ain[11] : chr_ain[10]) : // TxSROM do not support mirroring 5515 chrsel[7]; 5516 assign vram_ce = chr_ain[13] && !four_screen_mirroring; 5517endmodule 5518 5519// MMC4 mapper chip. PRG ROM: 256kB. Bank Size: 16kB. CHR ROM: 128kB 5520module MMC4(input clk, input ce, input reset, 5521 input [31:0] flags, 5522 input [15:0] prg_ain, output [21:0] prg_aout, 5523 input prg_read, prg_write, // Read / write signals 5524 input [7:0] prg_din, 5525 output prg_allow, // Enable access to memory for the specified operation. 5526 input chr_read, input [13:0] chr_ain, output [21:0] chr_aout, 5527 output chr_allow, // Allow write 5528 output vram_a10, // Value for A10 address line 5529 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 5530 5531// PRG ROM bank select ($A000-$AFFF) 5532// 7 bit 0 5533// ---- ---- 5534// xxxx PPPP 5535// |||| 5536// ++++- Select 16 KB PRG ROM bank for CPU $8000-$BFFF 5537 reg [3:0] prg_bank; 5538 5539// CHR ROM $FD/0000 bank select ($B000-$BFFF) 5540// 7 bit 0 5541// ---- ---- 5542// xxxC CCCC 5543// | |||| 5544// +-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF 5545// used when latch 0 = $FD 5546 reg [4:0] chr_bank_0a; 5547 5548// CHR ROM $FE/0000 bank select ($C000-$CFFF) 5549// 7 bit 0 5550// ---- ---- 5551// xxxC CCCC 5552// | |||| 5553// +-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF 5554// used when latch 0 = $FE 5555 reg [4:0] chr_bank_0b; 5556 5557// CHR ROM $FD/1000 bank select ($D000-$DFFF) 5558// 7 bit 0 5559// ---- ---- 5560// xxxC CCCC 5561// | |||| 5562// +-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF 5563// used when latch 1 = $FD 5564 reg [4:0] chr_bank_1a; 5565 5566// CHR ROM $FE/1000 bank select ($E000-$EFFF) 5567// 7 bit 0 5568// ---- ---- 5569// xxxC CCCC 5570// | |||| 5571// +-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF 5572// used when latch 1 = $FE 5573 reg [4:0] chr_bank_1b; 5574 5575// Mirroring ($F000-$FFFF) 5576// 7 bit 0 5577// ---- ---- 5578// xxxx xxxM 5579// | 5580// +- Select nametable mirroring (0: vertical; 1: horizontal) 5581 reg mirroring; 5582 5583 reg latch_0, latch_1; 5584 5585 // Update registers 5586 always @(posedge clk) if (ce) begin 5587 if (reset) 5588 prg_bank <= 4'b1110; 5589 else if (prg_write && prg_ain[15]) begin 5590 case(prg_ain[14:12]) 5591 2: prg_bank <= prg_din[3:0]; // $A000 5592 3: chr_bank_0a <= prg_din[4:0]; // $B000 5593 4: chr_bank_0b <= prg_din[4:0]; // $C000 5594 5: chr_bank_1a <= prg_din[4:0]; // $D000 5595 6: chr_bank_1b <= prg_din[4:0]; // $E000 5596 7: mirroring <= prg_din[0]; // $F000 5597 endcase 5598 end 5599 end 5600 5601// PPU reads $0FD8 through $0FDF: latch 0 is set to $FD for subsequent reads 5602// PPU reads $0FE8 through $0FEF: latch 0 is set to $FE for subsequent reads 5603// PPU reads $1FD8 through $1FDF: latch 1 is set to $FD for subsequent reads 5604// PPU reads $1FE8 through $1FEF: latch 1 is set to $FE for subsequent reads 5605 always @(posedge clk) if (ce && chr_read) begin 5606 latch_0 <= (chr_ain & 14'h3ff8) == 14'h0fd8 ? 0 : (chr_ain & 14'h3ff8) == 14'h0fe8 ? 1 : latch_0; 5607 latch_1 <= (chr_ain & 14'h3ff8) == 14'h1fd8 ? 0 : (chr_ain & 14'h3ff8) == 14'h1fe8 ? 1 : latch_1; 5608 end 5609 5610 // The PRG bank to load. Each increment here is 16kb. So valid values are 0..15. 5611 reg [3:0] prgsel; 5612 always @* begin 5613 casez(prg_ain[14]) 5614 1'b0: prgsel = prg_bank; 5615 default: prgsel = 4'b1111; 5616 endcase 5617 end 5618 wire [21:0] prg_aout_tmp = {4'b00_00, prgsel, prg_ain[13:0]}; 5619 5620 // The CHR bank to load. Each increment here is 4kb. So valid values are 0..31. 5621 reg [4:0] chrsel; 5622 always @* begin 5623 casez({chr_ain[12], latch_0, latch_1}) 5624 3'b00?: chrsel = chr_bank_0a; 5625 3'b01?: chrsel = chr_bank_0b; 5626 3'b1?0: chrsel = chr_bank_1a; 5627 3'b1?1: chrsel = chr_bank_1b; 5628 endcase 5629 end 5630 assign chr_aout = {5'b100_00, chrsel, chr_ain[11:0]}; 5631 5632 // The a10 VRAM address line. (Used for mirroring) 5633 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 5634 assign vram_ce = chr_ain[13]; 5635 5636 assign chr_allow = flags[15]; 5637 5638 wire prg_is_ram = prg_ain >= 'h6000 && prg_ain < 'h8000; 5639 assign prg_allow = prg_ain[15] && !prg_write || 5640 prg_is_ram; 5641 wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]}; 5642 assign prg_aout = prg_is_ram ? prg_ram : prg_aout_tmp; 5643 5644endmodule 5645 5646module MMC5(input clk, input ce, input reset, 5647 input [31:0] flags, 5648 input [19:0] ppuflags, 5649 input [15:0] prg_ain, output [21:0] prg_aout, 5650 input prg_read, prg_write, // Read / write signals 5651 input [7:0] prg_din, output reg [7:0] prg_dout, 5652 output prg_allow, // Enable access to memory for the specified operation. 5653 input [13:0] chr_ain, output reg [21:0] chr_aout, 5654 output reg [7:0] chr_dout, output has_chr_dout, 5655 output chr_allow, // Allow write 5656 output vram_a10, // Value for A10 address line 5657 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 5658 output irq); 5659 reg [1:0] prg_mode, chr_mode; 5660 reg prg_protect_1, prg_protect_2; 5661 reg [1:0] extended_ram_mode; 5662 reg [7:0] mirroring; 5663 reg [7:0] fill_tile; 5664 reg [1:0] fill_attr; 5665 reg [2:0] prg_ram_bank; 5666 reg [7:0] prg_bank_0, prg_bank_1, prg_bank_2; 5667 reg [6:0] prg_bank_3; 5668 reg [9:0] chr_bank_0, chr_bank_1, chr_bank_2, chr_bank_3, 5669 chr_bank_4, chr_bank_5, chr_bank_6, chr_bank_7, 5670 chr_bank_8, chr_bank_9, chr_bank_a, chr_bank_b; 5671 reg [1:0] upper_chr_bank_bits; 5672 reg chr_last; // Which CHR set was written to last? 5673 5674 reg [4:0] vsplit_startstop; 5675 reg vsplit_enable, vsplit_side; 5676 reg [7:0] vsplit_scroll, vsplit_bank; 5677 5678 reg [7:0] irq_scanline; 5679 reg irq_enable; 5680 reg irq_pending; 5681 5682 reg [7:0] multiplier_1; 5683 reg [7:0] multiplier_2; 5684 wire [15:0] multiply_result = multiplier_1 * multiplier_2; 5685 5686 reg [7:0] expansion_ram[0:1023]; // Block RAM, otherwise we need to time multiplex.. 5687 reg [7:0] last_read_ram; 5688 5689 // unpack ppu flags 5690 wire ppu_in_frame = ppuflags[0]; 5691 wire ppu_sprite16 = ppuflags[1]; 5692 wire [8:0] ppu_cycle = ppuflags[10:2]; 5693 wire [8:0] ppu_scanline = ppuflags[19:11]; 5694 5695 // Handle IO register writes 5696 always @(posedge clk) begin 5697 if (ce) begin 5698 if (prg_write && prg_ain[15:10] == 6'b010100) begin // $5000-$53FF 5699 if (prg_ain <= 16'h5113) 5700 $write("%X <= %X (%d)\n", prg_ain, prg_din, ppu_scanline); 5701 casez(prg_ain[9:0]) 5702 10'h100: prg_mode <= prg_din[1:0]; 5703 10'h101: chr_mode <= prg_din[1:0]; 5704 10'h102: prg_protect_1 <= (prg_din[1:0] == 2'b10); 5705 10'h103: prg_protect_2 <= (prg_din[1:0] == 2'b01); 5706 10'h104: extended_ram_mode <= prg_din[1:0]; 5707 10'h105: mirroring <= prg_din; 5708 10'h106: fill_tile <= prg_din; 5709 10'h107: fill_attr <= prg_din[1:0]; 5710 10'h113: prg_ram_bank <= prg_din[2:0]; 5711 10'h114: prg_bank_0 <= prg_din; 5712 10'h115: prg_bank_1 <= prg_din; 5713 10'h116: prg_bank_2 <= prg_din; 5714 10'h117: prg_bank_3 <= prg_din[6:0]; 5715 10'h120: chr_bank_0 <= {upper_chr_bank_bits, prg_din}; 5716 10'h121: chr_bank_1 <= {upper_chr_bank_bits, prg_din}; 5717 10'h122: chr_bank_2 <= {upper_chr_bank_bits, prg_din}; 5718 10'h123: chr_bank_3 <= {upper_chr_bank_bits, prg_din}; 5719 10'h124: chr_bank_4 <= {upper_chr_bank_bits, prg_din}; 5720 10'h125: chr_bank_5 <= {upper_chr_bank_bits, prg_din}; 5721 10'h126: chr_bank_6 <= {upper_chr_bank_bits, prg_din}; 5722 10'h127: chr_bank_7 <= {upper_chr_bank_bits, prg_din}; 5723 10'h128: chr_bank_8 <= {upper_chr_bank_bits, prg_din}; 5724 10'h129: chr_bank_9 <= {upper_chr_bank_bits, prg_din}; 5725 10'h12a: chr_bank_a <= {upper_chr_bank_bits, prg_din}; 5726 10'h12b: chr_bank_b <= {upper_chr_bank_bits, prg_din}; 5727 10'h130: upper_chr_bank_bits <= prg_din[1:0]; 5728 10'h200: {vsplit_enable, vsplit_side, vsplit_startstop} = {prg_din[7:6], prg_din[4:0]}; 5729 10'h201: vsplit_scroll <= prg_din; 5730 10'h202: vsplit_bank <= prg_din; 5731 10'h203: irq_scanline <= prg_din; 5732 10'h204: irq_enable <= prg_din[7]; 5733 10'h205: multiplier_1 <= prg_din; 5734 10'h206: multiplier_2 <= prg_din; 5735 default: begin end 5736 endcase 5737 5738 // Remember which set of CHR was written to last. 5739 if (prg_ain[9:0] >= 10'h120 && prg_ain[9:0] < 10'h130) 5740 chr_last <= prg_ain[3]; 5741 end 5742 5743 // Mode 0/1 - Not readable (returns open bus), can only be written while the PPU is rendering (otherwise, 0 is written) 5744 // Mode 2 - Readable and writable 5745 // Mode 3 - Read-only 5746 if (prg_write && prg_ain[15:10] == 6'b010111) begin // $5C00-$5FFF 5747 if (extended_ram_mode != 3) 5748 expansion_ram[prg_ain[9:0]] <= (extended_ram_mode[1] || ppu_in_frame) ? prg_din : 0; 5749 end 5750 end 5751 if (reset) begin 5752 prg_bank_3 <= 7'h7F; 5753 prg_mode <= 3; 5754 end 5755 end 5756 5757 // Read from MMC5 5758 always @* begin 5759 prg_dout = 8'hFF; // By default open bus. 5760 if (prg_ain[15:10] == 6'b010111 && extended_ram_mode[1]) begin 5761 prg_dout = last_read_ram; 5762 end else if (prg_ain == 16'h5204) begin 5763 prg_dout = {irq_pending, ppu_in_frame, 6'b111111}; 5764 end else if (prg_ain == 16'h5205) begin 5765 prg_dout = multiply_result[7:0]; 5766 end else if (prg_ain == 16'h5206) begin 5767 prg_dout = multiply_result[15:8]; 5768 end 5769 end 5770 5771 // Determine IRQ handling 5772 reg last_scanline, irq_trig; 5773 always @(posedge clk) if (ce) begin 5774 if (prg_read && prg_ain == 16'h5204) 5775 irq_pending <= 0; 5776 irq_trig <= (irq_scanline != 0 && irq_scanline < 240 && ppu_scanline == {1'b0, irq_scanline}); 5777 last_scanline <= ppu_scanline[0]; 5778 if (ppu_scanline[0] != last_scanline && irq_trig) 5779 irq_pending <= 1; 5780 end 5781 assign irq = irq_pending && irq_enable; 5782 5783 // Determine if vertical split is active. 5784 reg [5:0] cur_tile; // Current tile the PPU is fetching 5785 reg [5:0] new_cur_tile; // New value for |cur_tile| 5786 reg [7:0] vscroll; // Current y scroll for the split region 5787 reg last_in_split_area, in_split_area; 5788 5789 // Compute if we're in the split area right now by counting PPU tiles. 5790 always @* begin 5791 new_cur_tile = (ppu_cycle[8:3] == 40) ? 0 : (cur_tile + 6'b1); 5792 in_split_area = last_in_split_area; 5793 if (ppu_cycle[2:0] == 0 && ppu_cycle < 336) begin 5794 if (new_cur_tile == 0) 5795 in_split_area = !vsplit_side; 5796 else if (new_cur_tile == {1'b0, vsplit_startstop}) 5797 in_split_area = vsplit_side; 5798 else if (new_cur_tile == 34) 5799 in_split_area = 0; 5800 end 5801 end 5802 always @(posedge clk) if (ce) begin 5803 last_in_split_area <= in_split_area; 5804 if (ppu_cycle[2:0] == 0 && ppu_cycle < 336) 5805 cur_tile <= new_cur_tile; 5806 end 5807 // Keep track of scroll 5808 always @(posedge clk) if (ce) begin 5809 if (ppu_cycle == 319) 5810 vscroll <= ppu_scanline[8] ? vsplit_scroll : 5811 (vscroll == 239) ? 8'b0 : vscroll + 8'b1; 5812 end 5813 5814 // Mirroring bits 5815 // %00 = NES internal NTA 5816 // %01 = NES internal NTB 5817 // %10 = use ExRAM as NT 5818 // %11 = Fill Mode 5819 wire [1:0] mirrbits = (chr_ain[11:10] == 0) ? mirroring[1:0] : 5820 (chr_ain[11:10] == 1) ? mirroring[3:2] : 5821 (chr_ain[11:10] == 2) ? mirroring[5:4] : 5822 mirroring[7:6]; 5823 5824 // Compute the new overriden nametable/attr address the split will read from instead 5825 // when the VSplit is active. 5826 // Cycle 0, 1 = nametable 5827 // Cycle 2, 3 = attribute 5828 // Named it loopy so I can copypaste from PPU code :) 5829 wire [9:0] loopy = {vscroll[7:3], cur_tile[4:0]}; 5830 wire [9:0] split_addr = (ppu_cycle[1] == 0) ? loopy : // name table 5831 {4'b1111, loopy[9:7], loopy[4:2]}; // attribute table 5832 // Selects 2 out of the attr bits read from exram. 5833 wire [1:0] split_attr = (!loopy[1] && !loopy[6]) ? last_read_ram[1:0] : 5834 ( loopy[1] && !loopy[6]) ? last_read_ram[3:2] : 5835 (!loopy[1] && loopy[6]) ? last_read_ram[5:4] : 5836 last_read_ram[7:6]; 5837 // If splitting is active or not 5838 wire insplit = in_split_area && vsplit_enable; 5839 5840 // Currently reading the attribute byte? 5841 wire exattr_read = (extended_ram_mode == 1) && ppu_cycle[1]; 5842 5843 // If the current chr read should be redirected from |chr_dout| instead. 5844 assign has_chr_dout = chr_ain[13] && (mirrbits[1] || insplit || exattr_read); 5845 wire [1:0] override_attr = insplit ? split_attr : (extended_ram_mode == 1) ? last_read_ram[7:6] : fill_attr; 5846 always @* begin 5847 if (ppu_cycle[1] == 0) begin 5848 // Name table fetch 5849 if (insplit || mirrbits[0] == 0) chr_dout = (extended_ram_mode[1] ? 8'b0 : last_read_ram); 5850 else begin 5851 $write("Inserting filltile!\n"); 5852 chr_dout = fill_tile; 5853 end 5854 end else begin 5855 // Attribute table fetch 5856 if (!insplit && !exattr_read && mirrbits[0] == 0) chr_dout = (extended_ram_mode[1] ? 8'b0 : last_read_ram); 5857 else chr_dout = {override_attr, override_attr, override_attr, override_attr}; 5858 end 5859 end 5860 5861 // Handle reading from the expansion ram. 5862 // 0 - Use as extra nametable (possibly for split mode) 5863 // 1 - Use as extended attribute data OR an extra nametable 5864 // 2 - Use as ordinary RAM 5865 // 3 - Use as ordinary RAM, write protected 5866 wire [9:0] exram_read_addr = extended_ram_mode[1] ? prg_ain[9:0] : 5867 insplit ? split_addr : 5868 chr_ain[9:0]; 5869 always @(posedge clk) 5870 last_read_ram <= expansion_ram[exram_read_addr]; 5871 5872 // Compute PRG address to read from. 5873 reg [7:0] prgsel; 5874 always @* begin 5875 casez({prg_mode, prg_ain[15:13]}) 5876 5'b??_0??: prgsel = {5'b1xxxx, prg_ram_bank}; // $6000-$7FFF all modes 5877 5'b00_1??: prgsel = {1'b1, prg_bank_3[6:2], prg_ain[14:13]}; // $8000-$FFFF mode 0, 32kB (prg_bank_3, skip 2 bits) 5878 5879 5'b01_10?: prgsel = { prg_bank_1[7:1], prg_ain[13]}; // $8000-$BFFF mode 1, 16kB (prg_bank_1, skip 1 bit) 5880 5'b01_11?: prgsel = {1'b1, prg_bank_3[6:1], prg_ain[13]}; // $C000-$FFFF mode 1, 16kB (prg_bank_3, skip 1 bit) 5881 5882 5'b10_10?: prgsel = { prg_bank_1[7:1], prg_ain[13]}; // $8000-$BFFF mode 2, 16kB (prg_bank_1, skip 1 bit) 5883 5'b10_110: prgsel = { prg_bank_2}; // $C000-$DFFF mode 2, 8kB (prg_bank_2) 5884 5'b10_111: prgsel = {1'b1, prg_bank_3}; // $E000-$FFFF mode 2, 8kB (prg_bank_3) 5885 5886 5'b11_100: prgsel = { prg_bank_0}; // $8000-$9FFF mode 3, 8kB (prg_bank_0) 5887 5'b11_101: prgsel = { prg_bank_1}; // $A000-$BFFF mode 3, 8kB (prg_bank_1) 5888 5'b11_110: prgsel = { prg_bank_2}; // $C000-$DFFF mode 3, 8kB (prg_bank_2) 5889 5'b11_111: prgsel = {1'b1, prg_bank_3}; // $E000-$FFFF mode 3, 8kB (prg_bank_3) 5890 endcase 5891 prgsel[7] = !prgsel[7]; // 0 means RAM, doh. 5892 5893 // Limit to 64k RAM. 5894 if (prgsel[7]) 5895 prgsel[6:3] = 0; 5896 end 5897 assign prg_aout = {1'b0, prgsel, prg_ain[12:0]}; // 8kB banks 5898 5899 // Registers $5120-$5127 apply to sprite graphics and $5128-$512B for background graphics, but ONLY when 8x16 sprites are enabled. 5900 // Otherwise, the last set of registers written to (either $5120-$5127 or $5128-$512B) will be used for all graphics. 5901 // 0 if using $5120-$5127, 1 if using $5128-$512F 5902 wire is_bg_fetch = !(ppu_cycle[8] && !ppu_cycle[6]); 5903 wire chrset = ppu_sprite16 ? is_bg_fetch : chr_last; 5904 reg [9:0] chrsel; 5905 always @* begin 5906 casez({chr_mode, chr_ain[12:10], chrset}) 5907 6'b00_???_0: chrsel = {chr_bank_7[6:0], chr_ain[12:10]}; // $0000-$1FFF mode 0, 8 kB 5908 6'b00_???_1: chrsel = {chr_bank_b[6:0], chr_ain[12:10]}; // $0000-$1FFF mode 0, 8 kB 5909 5910 6'b01_0??_0: chrsel = {chr_bank_3[7:0], chr_ain[11:10]}; // $0000-$0FFF mode 1, 4 kB 5911 6'b01_1??_0: chrsel = {chr_bank_7[7:0], chr_ain[11:10]}; // $1000-$1FFF mode 1, 4 kB 5912 6'b01_???_1: chrsel = {chr_bank_b[7:0], chr_ain[11:10]}; // $0000-$0FFF mode 1, 4 kB 5913 5914 6'b10_00?_0: chrsel = {chr_bank_1[8:0], chr_ain[10]}; // $0000-$07FF mode 2, 2 kB 5915 6'b10_01?_0: chrsel = {chr_bank_3[8:0], chr_ain[10]}; // $0800-$0FFF mode 2, 2 kB 5916 6'b10_10?_0: chrsel = {chr_bank_5[8:0], chr_ain[10]}; // $1000-$17FF mode 2, 2 kB 5917 6'b10_11?_0: chrsel = {chr_bank_7[8:0], chr_ain[10]}; // $1800-$1FFF mode 2, 2 kB 5918 6'b10_?0?_1: chrsel = {chr_bank_9[8:0], chr_ain[10]}; // $0000-$07FF mode 2, 2 kB 5919 6'b10_?1?_1: chrsel = {chr_bank_b[8:0], chr_ain[10]}; // $0800-$0FFF mode 2, 2 kB 5920 5921 6'b11_000_0: chrsel = chr_bank_0; // $0000-$03FF mode 3, 1 kB 5922 6'b11_001_0: chrsel = chr_bank_1; // $0400-$07FF mode 3, 1 kB 5923 6'b11_010_0: chrsel = chr_bank_2; // $0800-$0BFF mode 3, 1 kB 5924 6'b11_011_0: chrsel = chr_bank_3; // $0C00-$0FFF mode 3, 1 kB 5925 6'b11_100_0: chrsel = chr_bank_4; // $1000-$13FF mode 3, 1 kB 5926 6'b11_101_0: chrsel = chr_bank_5; // $1400-$17FF mode 3, 1 kB 5927 6'b11_110_0: chrsel = chr_bank_6; // $1800-$1BFF mode 3, 1 kB 5928 6'b11_111_0: chrsel = chr_bank_7; // $1C00-$1FFF mode 3, 1 kB 5929 6'b11_?00_1: chrsel = chr_bank_8; // $0000-$03FF mode 3, 1 kB 5930 6'b11_?01_1: chrsel = chr_bank_9; // $0400-$07FF mode 3, 1 kB 5931 6'b11_?10_1: chrsel = chr_bank_a; // $0800-$0BFF mode 3, 1 kB 5932 6'b11_?11_1: chrsel = chr_bank_b; // $0C00-$0FFF mode 3, 1 kB 5933 endcase 5934 5935 chr_aout = {2'b10, chrsel, chr_ain[9:0]}; // 1kB banks 5936 5937 // Override |chr_aout| if we're in a vertical split. 5938 if (insplit) begin 5939 $write("In vertical split!\n"); 5940 chr_aout = {2'b10, vsplit_bank, chr_ain[11:3], vscroll[2:0]}; 5941 end else if (extended_ram_mode == 1 && is_bg_fetch) begin 5942 $write("In exram thingy!\n"); 5943 // Extended attribute mode. Replace the page with the page from exram. 5944 chr_aout = {2'b10, upper_chr_bank_bits, last_read_ram[5:0], chr_ain[11:0]}; 5945 end 5946 5947 end 5948 5949 // The a10 VRAM address line. (Used for mirroring) 5950 assign vram_a10 = mirrbits[0]; 5951 assign vram_ce = chr_ain[13] && !mirrbits[1]; 5952 5953 // Writing to RAM is enabled only when the protect bits say so. 5954 wire prg_ram_we = prg_protect_1 && prg_protect_2; 5955 assign prg_allow = (prg_ain >= 16'h6000) && (!prg_write || prgsel[7] && prg_ram_we); 5956 5957 // MMC5 boards typically have no CHR RAM. 5958 assign chr_allow = flags[15]; 5959endmodule 5960 5961// iNES mapper 64 and 158 - Tengen's version of MMC3 5962module Rambo1(input clk, input ce, input reset, 5963 input [31:0] flags, 5964 input [15:0] prg_ain, output [21:0] prg_aout, 5965 input prg_read, prg_write, // Read / write signals 5966 input [7:0] prg_din, 5967 output prg_allow, // Enable access to memory for the specified operation. 5968 input [13:0] chr_ain, output [21:0] chr_aout, 5969 output chr_allow, // Allow write 5970 output vram_a10, // Value for A10 address line 5971 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 5972 output reg irq); 5973 reg [3:0] bank_select; // Register to write to next 5974 reg prg_rom_bank_mode; // Mode for PRG banking 5975 reg chr_K; // Mode for CHR banking 5976 reg chr_a12_invert; // Mode for CHR banking 5977 reg mirroring; // 0 = vertical, 1 = horizontal 5978 reg irq_enable, irq_reload; // IRQ enabled, and IRQ reload requested 5979 reg [7:0] irq_latch, counter; // IRQ latch value and current counter 5980 reg want_irq; 5981 reg [7:0] chr_bank_0, chr_bank_1; // Selected CHR banks 5982 reg [7:0] chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5; 5983 reg [7:0] chr_bank_8, chr_bank_9; 5984 reg [5:0] prg_bank_0, prg_bank_1, prg_bank_2; // Selected PRG banks 5985 reg irq_cycle_mode; 5986 reg [1:0] cycle_counter; 5987 5988 // Mapper has vram_a10 wired to CHR A17 5989 wire mapper64 = (flags[7:0] == 64); 5990 5991 reg is_interrupt; // Not a reg! 5992 5993 // This code detects rising edges on a12. 5994 reg old_a12_edge; 5995 reg [1:0] a12_ctr; 5996 wire a12_edge = (chr_ain[12] && a12_ctr == 0) || old_a12_edge; 5997 always @(posedge clk) begin 5998 old_a12_edge <= a12_edge && !ce; 5999 a12_ctr <= chr_ain[12] ? 2'b11 : (a12_ctr != 0 && ce) ? a12_ctr - 2'b01 : a12_ctr; 6000 end 6001 6002 always @(posedge clk) if (reset) begin 6003 bank_select <= 0; 6004 prg_rom_bank_mode <= 0; 6005 chr_K <= 0; 6006 chr_a12_invert <= 0; 6007 mirroring <= 0; 6008 {irq_enable, irq_reload} <= 0; 6009 {irq_latch, counter} <= 0; 6010 want_irq <= 0; 6011 {chr_bank_0, chr_bank_1} <= 0; 6012 {chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5} <= 0; 6013 {chr_bank_8, chr_bank_9} <= 0; 6014 {prg_bank_0, prg_bank_1, prg_bank_2} <= 6'b111111; 6015 irq_cycle_mode <= 0; 6016 cycle_counter <= 0; 6017 irq <= 0; 6018 end else if (ce) begin 6019 cycle_counter <= cycle_counter + 1; 6020 6021 if (prg_write && prg_ain[15]) begin 6022 case({prg_ain[14:13], prg_ain[0]}) 6023 // Bank select ($8000-$9FFE, even) 6024 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, chr_K, bank_select} <= {prg_din[7:5], prg_din[3:0]}; 6025 // Bank data ($8001-$9FFF, odd) 6026 3'b00_1: 6027 case (bank_select) 6028 0: chr_bank_0 <= prg_din; // Select 2 (K=0) or 1 (K=1) KB CHR bank at PPU $0000 (or $1000); 6029 1: chr_bank_1 <= prg_din; // Select 2 (K=0) or 1 (K=1) KB CHR bank at PPU $0800 (or $1800); 6030 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); 6031 3: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); 6032 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); 6033 5: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); 6034 6: prg_bank_0 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); 6035 7: prg_bank_1 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF 6036 8: chr_bank_8 <= prg_din; // If K=1, Select 1 KB CHR bank at PPU $0400 (or $1400); 6037 9: chr_bank_9 <= prg_din; // If K=1, Select 1 KB CHR bank at PPU $0C00 (or $1C00) 6038 15: prg_bank_2 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $C000-$DFFF (or $8000-$9FFF); 6039 endcase 6040 3'b01_0: mirroring <= prg_din[0]; // Mirroring ($A000-$BFFE, even) 6041 3'b01_1: begin end 6042 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) 6043 3'b10_1: begin 6044 {irq_reload, irq_cycle_mode} <= {1'b1, prg_din[0]}; // IRQ reload ($C001-$DFFF, odd) 6045 cycle_counter <= 0; 6046 end 6047 3'b11_0: {irq_enable, irq} <= 2'b0; // IRQ disable ($E000-$FFFE, even) 6048 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) 6049 endcase 6050 end 6051 is_interrupt = irq_cycle_mode ? (cycle_counter == 3) : a12_edge; 6052 if (is_interrupt) begin 6053 if (irq_reload || counter == 0) begin 6054 counter <= irq_latch; 6055 want_irq <= irq_reload; 6056 end else begin 6057 counter <= counter - 1; 6058 want_irq <= 1; 6059 end 6060 if (counter == 0 && want_irq && !irq_reload && irq_enable) 6061 irq <= 1; 6062 irq_reload <= 0; 6063 end 6064 6065 end 6066 // The PRG bank to load. Each increment here is 8kb. So valid values are 0..63. 6067 reg [5:0] prgsel; 6068 always @* begin 6069 casez({prg_ain[14:13], prg_rom_bank_mode}) 6070 3'b00_0: prgsel = prg_bank_0; // $8000 is R:6 6071 3'b01_0: prgsel = prg_bank_1; // $A000 is R:7 6072 3'b10_0: prgsel = prg_bank_2; // $C000 is R:F 6073 3'b11_0: prgsel = 6'b111111; // $E000 fixed to last bank 6074 3'b00_1: prgsel = prg_bank_2; // $8000 is R:F 6075 3'b01_1: prgsel = prg_bank_0; // $A000 is R:6 6076 3'b10_1: prgsel = prg_bank_1; // $C000 is R:7 6077 3'b11_1: prgsel = 6'b111111; // $E000 fixed to last bank 6078 endcase 6079 end 6080 // The CHR bank to load. Each increment here is 1kb. So valid values are 0..255. 6081 reg [7:0] chrsel; 6082 always @* begin 6083 casez({chr_ain[12] ^ chr_a12_invert, chr_ain[11], chr_ain[10], chr_K}) 6084 4'b00?_0: chrsel = {chr_bank_0[7:1], chr_ain[10]}; 6085 4'b01?_0: chrsel = {chr_bank_1[7:1], chr_ain[10]}; 6086 4'b000_1: chrsel = chr_bank_0; 6087 4'b001_1: chrsel = chr_bank_8; 6088 4'b010_1: chrsel = chr_bank_1; 6089 4'b011_1: chrsel = chr_bank_9; 6090 4'b100_?: chrsel = chr_bank_2; 6091 4'b101_?: chrsel = chr_bank_3; 6092 4'b110_?: chrsel = chr_bank_4; 6093 4'b111_?: chrsel = chr_bank_5; 6094 endcase 6095 end 6096 assign prg_aout = {3'b00_0, prgsel, prg_ain[12:0]}; 6097 assign {chr_allow, chr_aout} = {flags[15], 4'b10_00, chrsel, chr_ain[9:0]}; 6098 assign prg_allow = prg_ain[15] && !prg_write; 6099 assign vram_a10 = mapper64 ? chrsel[7] : // Mapper 64 controls mirroring by switching the top bits of the CHR address 6100 mirroring ? chr_ain[11] : chr_ain[10]; 6101 assign vram_ce = chr_ain[13]; 6102endmodule 6103 6104 6105// #13 - CPROM - Used by Videomation 6106module Mapper13(input clk, input ce, input reset, 6107 input [31:0] flags, 6108 input [15:0] prg_ain, output [21:0] prg_aout, 6109 input prg_read, prg_write, // Read / write signals 6110 input [7:0] prg_din, 6111 output prg_allow, // Enable access to memory for the specified operation. 6112 input [13:0] chr_ain, output [21:0] chr_aout, 6113 output chr_allow, // Allow write 6114 output vram_a10, // Value for A10 address line 6115 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6116 reg [1:0] chr_bank; 6117 always @(posedge clk) if (reset) begin 6118 chr_bank <= 0; 6119 end else if (ce) begin 6120 if (prg_ain[15] && prg_write) 6121 chr_bank <= prg_din[1:0]; 6122 end 6123 assign prg_aout = {7'b00_0000_0, prg_ain[14:0]}; 6124 assign prg_allow = prg_ain[15] && !prg_write; 6125 assign chr_allow = flags[15]; 6126 assign chr_aout = {8'b01_0000_00, chr_ain[12] ? chr_bank : 2'b00, chr_ain[11:0]}; 6127 assign vram_ce = chr_ain[13]; 6128 assign vram_a10 = flags[14] ? chr_ain[10] : chr_ain[11]; 6129endmodule 6130 6131// #15 - 100-in-1 Contra Function 16 6132module Mapper15(input clk, input ce, input reset, 6133 input [31:0] flags, 6134 input [15:0] prg_ain, output [21:0] prg_aout, 6135 input prg_read, prg_write, // Read / write signals 6136 input [7:0] prg_din, 6137 output prg_allow, // Enable access to memory for the specified operation. 6138 input [13:0] chr_ain, output [21:0] chr_aout, 6139 output chr_allow, // Allow write 6140 output vram_a10, // Value for A10 address line 6141 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6142// 15 bit 8 7 bit 0 Address bus 6143// ---- ---- ---- ---- 6144// 1xxx xxxx xxxx xxSS 6145// | || 6146// | ++- Select PRG ROM bank mode 6147// | 0: 32K; 1: 128K (UNROM style); 2: 8K; 3: 16K 6148// +------------------- Always 1 6149// 7 bit 0 Data bus 6150// ---- ---- 6151// bMBB BBBB 6152// |||| |||| 6153// ||++-++++- Select 16 KB PRG ROM bank 6154// |+-------- Select nametable mirroring mode (0=vertical; 1=horizontal) 6155// +--------- Select 8 KB half of 16 KB PRG ROM bank 6156// (should be 0 except in bank mode 0) 6157 reg [1:0] prg_rom_bank_mode; 6158 reg prg_rom_bank_lowbit; 6159 reg mirroring; 6160 reg [5:0] prg_rom_bank; 6161 always @(posedge clk) if (reset) begin 6162 prg_rom_bank_mode <= 0; 6163 prg_rom_bank_lowbit <= 0; 6164 mirroring <= 0; 6165 prg_rom_bank <= 0; 6166 end else if (ce) begin 6167 if (prg_ain[15] && prg_write) 6168 {prg_rom_bank_mode, prg_rom_bank_lowbit, mirroring, prg_rom_bank} <= {prg_ain[1:0], prg_din[7:0]}; 6169 end 6170 reg [6:0] prg_bank; 6171 always begin 6172 casez({prg_rom_bank_mode, prg_ain[14]}) 6173 // Bank mode 0 ( 32K ) / CPU $8000-$BFFF: Bank B / CPU $C000-$FFFF: Bank (B OR 1) 6174 3'b00_0: prg_bank = {prg_rom_bank, prg_ain[13]}; 6175 3'b00_1: prg_bank = {prg_rom_bank | 6'b1, prg_ain[13]}; 6176 // Bank mode 1 ( 128K ) / CPU $8000-$BFFF: Switchable 16 KB bank B / CPU $C000-$FFFF: Fixed to last bank in the cart 6177 3'b01_0: prg_bank = {prg_rom_bank, prg_ain[13]}; 6178 3'b01_1: prg_bank = {6'b111111, prg_ain[13]}; 6179 // Bank mode 2 ( 8K ) / CPU $8000-$9FFF: Sub-bank b of 16 KB PRG ROM bank B / CPU $A000-$FFFF: Mirrors of $8000-$9FFF 6180 3'b10_?: prg_bank = {prg_rom_bank, prg_rom_bank_lowbit}; 6181 // Bank mode 3 ( 16K ) / CPU $8000-$BFFF: 16 KB bank B / CPU $C000-$FFFF: Mirror of $8000-$BFFF 6182 3'b11_?: prg_bank = {prg_rom_bank, prg_ain[13]}; 6183 endcase 6184 end 6185 assign prg_aout = {2'b00, prg_bank, prg_ain[12:0]}; 6186 assign prg_allow = prg_ain[15] && !prg_write; 6187 assign chr_allow = flags[15]; // CHR RAM? 6188 assign chr_aout = {9'b10_0000_000, chr_ain[12:0]}; 6189 assign vram_ce = chr_ain[13]; 6190 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 6191endmodule 6192 6193// Mapper 16, Bandai 6194module Mapper16(input clk, input ce, input reset, 6195 input [31:0] flags, 6196 input [15:0] prg_ain, output [21:0] prg_aout, 6197 input prg_read, prg_write, // Read / write signals 6198 input [7:0] prg_din, output [7:0] prg_dout, 6199 output prg_allow, // Enable access to memory for the specified operation. 6200 input [13:0] chr_ain, output [21:0] chr_aout, 6201 output chr_allow, // Allow write 6202 output reg vram_a10, // Value for A10 address line 6203 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 6204 output reg irq); 6205 6206 reg [3:0] prg_bank; 6207 reg [7:0] chr_bank_0, chr_bank_1, chr_bank_2, chr_bank_3, 6208 chr_bank_4, chr_bank_5, chr_bank_6, chr_bank_7; 6209 reg [3:0] prg_sel; 6210 reg [1:0] mirroring; 6211 reg irq_enable; 6212 reg [15:0] irq_counter; 6213 6214 always @(posedge clk) if (reset) begin 6215 prg_bank <= 4'hF; 6216 chr_bank_0 <= 0; 6217 chr_bank_1 <= 0; 6218 chr_bank_2 <= 0; 6219 chr_bank_3 <= 0; 6220 chr_bank_4 <= 0; 6221 chr_bank_5 <= 0; 6222 chr_bank_6 <= 0; 6223 chr_bank_7 <= 0; 6224 mirroring <= 0; 6225 irq_counter <= 0; 6226 end else if (ce) begin 6227 if (prg_write) 6228 if(prg_ain >= 'h6000) // Cover all from $6000 to $FFFF to maximize compatibility 6229 case(prg_ain & 'hf) // Registers are mapped every 16 bytes 6230 'h0: chr_bank_0 <= prg_din[7:0]; 6231 'h1: chr_bank_1 <= prg_din[7:0]; 6232 'h2: chr_bank_2 <= prg_din[7:0]; 6233 'h3: chr_bank_3 <= prg_din[7:0]; 6234 'h4: chr_bank_4 <= prg_din[7:0]; 6235 'h5: chr_bank_5 <= prg_din[7:0]; 6236 'h6: chr_bank_6 <= prg_din[7:0]; 6237 'h7: chr_bank_7 <= prg_din[7:0]; 6238 'h8: prg_bank <= prg_din[3:0]; 6239 'h9: mirroring <= prg_din[1:0]; 6240 'ha: irq_enable <= prg_din[0]; 6241 'hb: irq_counter[7:0] <= prg_din[7:0]; 6242 'hc: irq_counter[15:8] <= prg_din[7:0]; 6243// 'hd: RAM enable or EEPROM control 6244 endcase 6245 6246 if (irq_enable) 6247 irq_counter <= irq_counter - 16'd1; 6248 else begin 6249 irq <= 1'b0; // IRQ ACK 6250 end 6251 6252 if (irq_counter == 16'h0000) 6253 irq <= 1'b1; // IRQ 6254 6255 end 6256 6257 always begin 6258 // mirroring 6259 casez(mirroring[1:0]) 6260 2'b00: vram_a10 = {chr_ain[10]}; // vertical 6261 2'b01: vram_a10 = {chr_ain[11]}; // horizontal 6262 2'b1?: vram_a10 = {mirroring[0]}; // single screen lower 6263 endcase 6264 end 6265 6266 reg [3:0] prgsel; 6267 always begin 6268 case(prg_ain[15:14]) 6269 2'b10: prgsel = prg_bank; // $8000 is swapable 6270 2'b11: prgsel = 4'hF; // $C000 is hardwired to last bank 6271 endcase 6272 end 6273 6274 reg [7:0] chrsel; 6275 always begin 6276 casez(chr_ain[12:10]) 6277 0: chrsel = chr_bank_0; 6278 1: chrsel = chr_bank_1; 6279 2: chrsel = chr_bank_2; 6280 3: chrsel = chr_bank_3; 6281 4: chrsel = chr_bank_4; 6282 5: chrsel = chr_bank_5; 6283 6: chrsel = chr_bank_6; 6284 7: chrsel = chr_bank_7; 6285 endcase 6286 end 6287 assign chr_aout = {4'b10_00, chrsel, chr_ain[9:0]}; // 1kB banks 6288 wire [21:0] prg_aout_tmp = {4'b00_00, prgsel, prg_ain[13:0]}; // 16kB banks 6289 6290 wire prg_is_ram = (prg_ain >= 'h6000) && (prg_ain < 'h8000); 6291 wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]}; 6292 assign prg_aout = prg_is_ram ? prg_ram : prg_aout_tmp; 6293 assign prg_dout = prg_is_ram ? 8'h00 : 8'hFF; // EEPROM stub 6294 6295 assign prg_allow = prg_ain[15] && !prg_write || 6296 prg_is_ram; 6297 assign chr_allow = flags[15]; 6298 assign vram_ce = chr_ain[13]; 6299endmodule 6300 6301// Tepples/Multi-discrete mapper 6302// This mapper can emulate other mappers, such as mapper #0, mapper #2 6303module Mapper28(input clk, input ce, input reset, 6304 input [31:0] flags, 6305 input [15:0] prg_ain, output [21:0] prg_aout, 6306 input prg_read, prg_write, // Read / write signals 6307 input [7:0] prg_din, 6308 output prg_allow, // Enable access to memory for the specified operation. 6309 input [13:0] chr_ain, output [21:0] chr_aout, 6310 output chr_allow, // Allow write 6311 output reg vram_a10, // Value for A10 address line 6312 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6313 reg [6:0] a53prg; // output PRG ROM (A14-A20 on ROM) 6314 reg [1:0] a53chr; // output CHR RAM (A13-A14 on RAM) 6315 6316 reg [3:0] inner; // "inner" bank at 01h 6317 reg [5:0] mode; // mode register at 80h 6318 reg [5:0] outer; // "outer" bank at 81h 6319 reg [1:0] selreg; // selector register 6320 6321 // Allow writes to 0x5000 only when launching through the proper mapper ID. 6322 wire [7:0] mapper = flags[7:0]; 6323 wire allow_select = (mapper == 8'd28); 6324 6325 always @(posedge clk) if (reset) begin 6326 mode[5:2] <= 0; // NROM mode, 32K mode 6327 outer[5:0] <= 6'h3f; // last bank 6328 inner <= 0; 6329 selreg <= 1; 6330 6331 // Set value for mirroring 6332 if (mapper == 2 || mapper == 0 || mapper == 3) 6333 mode[1:0] <= flags[14] ? 2'b10 : 2'b11; 6334 6335 // UNROM #2 - Current bank in $8000-$BFFF and fixed top half of outer bank in $C000-$FFFF 6336 if (mapper == 2) begin 6337 mode[5:2] <= 4'b1111; // 256K banks, UNROM mode 6338 end 6339 6340 // CNROM #3 - Fixed PRG bank, switchable CHR bank. 6341 if (mapper == 3) 6342 selreg <= 0; 6343 6344 // AxROM #7 - Switch 32kb rom bank + switchable nametables 6345 if (mapper == 7) begin 6346 mode[1:0] <= 2'b00; // Switchable VRAM page. 6347 mode[5:2] <= 4'b1100; // 256K banks, (B)NROM mode 6348 outer[5:0] <= 6'h00; 6349 end 6350 end else if (ce) begin 6351 if ((prg_ain[15:12] == 4'h5) & prg_write && allow_select) 6352 selreg <= {prg_din[7], prg_din[0]}; // select register 6353 if (prg_ain[15] & prg_write) begin 6354 case (selreg) 6355 2'h0: {mode[0], a53chr} <= {(mode[1] ? mode[0] : prg_din[4]), prg_din[1:0]}; // CHR RAM bank 6356 2'h1: {mode[0], inner} <= {(mode[1] ? mode[0] : prg_din[4]), prg_din[3:0]}; // "inner" bank 6357 2'h2: {mode} <= {prg_din[5:0]}; // mode register 6358 2'h3: {outer} <= {prg_din[5:0]}; // "outer" bank 6359 endcase 6360 end 6361 end 6362 6363 always begin 6364 // mirroring mode 6365 casez(mode[1:0]) 6366 2'b0? : vram_a10 = {mode[0]}; // 1 screen lower 6367 2'b10 : vram_a10 = {chr_ain[10]}; // vertical 6368 2'b11 : vram_a10 = {chr_ain[11]}; // horizontal 6369 endcase 6370 6371 // PRG ROM bank size select 6372 casez({mode[5:2], prg_ain[14]}) 6373 5'b00_0?_? : a53prg = {outer[5:0], prg_ain[14]}; // 32K banks, (B)NROM mode 6374 5'b01_0?_? : a53prg = {outer[5:1], inner[0], prg_ain[14]}; // 64K banks, (B)NROM mode 6375 5'b10_0?_? : a53prg = {outer[5:2], inner[1:0], prg_ain[14]}; // 128K banks, (B)NROM mode 6376 5'b11_0?_? : a53prg = {outer[5:3], inner[2:0], prg_ain[14]}; // 256K banks, (B)NROM mode 6377 6378 5'b00_10_1, 6379 5'b00_11_0 : a53prg = {outer[5:0], inner[0]}; // 32K banks, UNROM mode 6380 5'b01_10_1, 6381 5'b01_11_0 : a53prg = {outer[5:1], inner[1:0]}; // 64K banks, UNROM mode 6382 5'b10_10_1, 6383 5'b10_11_0 : a53prg = {outer[5:2], inner[2:0]}; // 128K banks, UNROM mode 6384 5'b11_10_1, 6385 5'b11_11_0 : a53prg = {outer[5:3], inner[3:0]}; // 256K banks, UNROM mode 6386 6387 default : a53prg = {outer[5:0], prg_ain[14]}; // 16K fixed bank 6388 endcase 6389 end 6390 6391 assign vram_ce = chr_ain[13]; 6392 assign prg_aout = {1'b0, (a53prg & 7'b0011111), prg_ain[13:0]}; 6393 assign prg_allow = prg_ain[15] && !prg_write; 6394 assign chr_allow = flags[15]; 6395 assign chr_aout = {7'b10_0000_0, a53chr, chr_ain[12:0]}; 6396endmodule 6397 6398// Mapper 42, used for hacked FDS games converted to cartridge form 6399module Mapper42(input clk, input ce, input reset, 6400 input [31:0] flags, 6401 input [15:0] prg_ain, output [21:0] prg_aout, 6402 input prg_read, prg_write, // Read / write signals 6403 input [7:0] prg_din, 6404 output prg_allow, // Enable access to memory for the specified operation. 6405 input [13:0] chr_ain, output [21:0] chr_aout, 6406 output chr_allow, // Allow write 6407 output vram_a10, // Value for A10 address line 6408 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 6409 output reg irq); 6410 6411 reg [3:0] prg_bank; 6412 reg [3:0] chr_bank; 6413 reg [3:0] prg_sel; 6414 reg mirroring; 6415 reg irq_enable; 6416 reg [14:0] irq_counter; 6417 6418 always @(posedge clk) if (reset) begin 6419 prg_bank <= 0; 6420 chr_bank <= 0; 6421 mirroring <= flags[14]; 6422 irq_counter <= 0; 6423 end else if (ce) begin 6424 if (prg_write) 6425 case(prg_ain & 16'he003) 6426 16'h8000: chr_bank <= prg_din[3:0]; 6427 16'he000: prg_bank <= prg_din[3:0]; 6428 16'he001: mirroring <= prg_din[3]; 6429 16'he002: irq_enable <= prg_din[1]; 6430 endcase 6431 6432 if (irq_enable) 6433 irq_counter <= irq_counter + 15'd1; 6434 else begin 6435 irq <= 1'b0; // ACK 6436 irq_counter <= 0; 6437 end 6438 6439 if (irq_counter == 15'h6000) 6440 irq <= 1'b1; 6441 6442 end 6443 6444 always @* begin 6445/* PRG bank selection 6446 6000-7FFF: Selectable 6447 8000-9FFF: bank #0Ch 6448 A000-BFFF: bank #0Dh 6449 C000-DFFF: bank #0Eh 6450 E000-FFFF: bank #0Fh 6451*/ 6452 case(prg_ain[15:13]) 6453 3'b011: prg_sel = prg_bank; // $6000-$7FFF 6454 3'b100: prg_sel = 4'hC; 6455 3'b101: prg_sel = 4'hD; 6456 3'b110: prg_sel = 4'hE; 6457 3'b111: prg_sel = 4'hF; 6458 endcase 6459 end 6460 assign prg_aout = {5'b0, prg_sel, prg_ain[12:0]}; // 8kB banks 6461 assign chr_aout = {5'b10_000, chr_bank, chr_ain[12:0]}; // 8kB banks 6462 6463 assign prg_allow = (prg_ain >= 16'h6000) && !prg_write; 6464 assign chr_allow = flags[15]; 6465 assign vram_ce = chr_ain[13]; 6466 assign vram_a10 = mirroring ? chr_ain[10] : chr_ain[11]; 6467endmodule 6468 6469// 11 - Color Dreams 6470// 66 - GxROM 6471module Mapper66(input clk, input ce, input reset, 6472 input [31:0] flags, 6473 input [15:0] prg_ain, output [21:0] prg_aout, 6474 input prg_read, prg_write, // Read / write signals 6475 input [7:0] prg_din, 6476 output prg_allow, // Enable access to memory for the specified operation. 6477 input [13:0] chr_ain, output [21:0] chr_aout, 6478 output chr_allow, // Allow write 6479 output vram_a10, // Value for A10 address line 6480 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6481 reg [1:0] prg_bank; 6482 reg [3:0] chr_bank; 6483 wire GXROM = (flags[7:0] == 66); 6484 always @(posedge clk) if (reset) begin 6485 prg_bank <= 0; 6486 chr_bank <= 0; 6487 end else if (ce) begin 6488 if (prg_ain[15] & prg_write) begin 6489 if (GXROM) 6490 {prg_bank, chr_bank} <= {prg_din[5:4], 2'b0, prg_din[1:0]}; 6491 else // Color Dreams 6492 {chr_bank, prg_bank} <= {prg_din[7:4], prg_din[1:0]}; 6493 end 6494 end 6495 assign prg_aout = {5'b00_000, prg_bank, prg_ain[14:0]}; 6496 assign prg_allow = prg_ain[15] && !prg_write; 6497 assign chr_allow = flags[15]; 6498 assign chr_aout = {5'b10_000, chr_bank, chr_ain[12:0]}; 6499 assign vram_ce = chr_ain[13]; 6500 assign vram_a10 = flags[14] ? chr_ain[10] : chr_ain[11]; 6501endmodule 6502 6503// 34 - BxROM or NINA-001 6504module Mapper34(input clk, input ce, input reset, 6505 input [31:0] flags, 6506 input [15:0] prg_ain, output [21:0] prg_aout, 6507 input prg_read, prg_write, // Read / write signals 6508 input [7:0] prg_din, 6509 output prg_allow, // Enable access to memory for the specified operation. 6510 input [13:0] chr_ain, output [21:0] chr_aout, 6511 output chr_allow, // Allow write 6512 output vram_a10, // Value for A10 address line 6513 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6514 reg [1:0] prg_bank; 6515 reg [3:0] chr_bank_0, chr_bank_1; 6516 6517 wire NINA = (flags[13:11] != 0); // NINA is used when there is more than 8kb of CHR 6518 always @(posedge clk) if (reset) begin 6519 prg_bank <= 0; 6520 chr_bank_0 <= 0; 6521 chr_bank_1 <= 1; // To be compatible with BxROM 6522 end else if (ce && prg_write) begin 6523 if (!NINA) begin // BxROM 6524 if (prg_ain[15]) 6525 prg_bank <= prg_din[1:0]; 6526 end else begin // NINA 6527 if (prg_ain == 16'h7ffd) 6528 prg_bank <= prg_din[1:0]; 6529 else if (prg_ain == 16'h7ffe) 6530 chr_bank_0 <= prg_din[3:0]; 6531 else if (prg_ain == 16'h7fff) 6532 chr_bank_1 <= prg_din[3:0]; 6533 end 6534 end 6535 6536 wire [21:0] prg_aout_tmp = {5'b00_000, prg_bank, prg_ain[14:0]}; 6537 assign chr_allow = flags[15]; 6538 assign chr_aout = {6'b10_0000, chr_ain[12] == 0 ? chr_bank_0 : chr_bank_1, chr_ain[11:0]}; 6539 assign vram_ce = chr_ain[13]; 6540 assign vram_a10 = flags[14] ? chr_ain[10] : chr_ain[11]; 6541 6542 wire prg_is_ram = (prg_ain >= 'h6000 && prg_ain < 'h8000) && NINA; 6543 assign prg_allow = prg_ain[15] && !prg_write || 6544 prg_is_ram; 6545 wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]}; 6546 assign prg_aout = prg_is_ram ? prg_ram : prg_aout_tmp; 6547endmodule 6548 6549// 41 - Caltron 6-in-1 6550module Mapper41(input clk, input ce, input reset, 6551 input [31:0] flags, 6552 input [15:0] prg_ain, output [21:0] prg_aout, 6553 input prg_read, prg_write, // Read / write signals 6554 input [7:0] prg_din, 6555 output prg_allow, // Enable access to memory for the specified operation. 6556 input [13:0] chr_ain, output [21:0] chr_aout, 6557 output chr_allow, // Allow write 6558 output vram_a10, // Value for A10 address line 6559 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6560 reg [2:0] prg_bank; 6561 reg [1:0] chr_outer_bank, chr_inner_bank; 6562 reg mirroring; 6563 6564 always @(posedge clk) if (reset) begin 6565 prg_bank <= 0; 6566 chr_outer_bank <= 0; 6567 chr_inner_bank <= 0; 6568 mirroring <= 0; 6569 end else if (ce && prg_write) begin 6570 if (prg_ain[15:11] == 5'b01100) begin 6571 {mirroring, chr_outer_bank, prg_bank} <= prg_ain[5:0]; 6572 end else if (prg_ain[15] && prg_bank[2]) begin 6573 // The Inner CHR Bank Select only can be written while the PRG ROM bank is 4, 5, 6, or 7 6574 chr_inner_bank <= prg_din[1:0]; 6575 end 6576 end 6577 6578 assign prg_aout = {4'b00_00, prg_bank, prg_ain[14:0]}; 6579 assign chr_allow = flags[15]; 6580 assign chr_aout = {5'b10_000, chr_outer_bank, chr_inner_bank, chr_ain[12:0]}; 6581 assign vram_ce = chr_ain[13]; 6582 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 6583 assign prg_allow = prg_ain[15] && !prg_write; 6584endmodule 6585 6586// #68 - Sunsoft-4 - Game After Burner, and some japanese games. MAX: 128kB PRG, 256kB CHR 6587module Mapper68(input clk, input ce, input reset, 6588 input [31:0] flags, 6589 input [15:0] prg_ain, output [21:0] prg_aout, 6590 input prg_read, prg_write, // Read / write signals 6591 input [7:0] prg_din, 6592 output prg_allow, // Enable access to memory for the specified operation. 6593 input [13:0] chr_ain, output [21:0] chr_aout, 6594 output chr_allow, // Allow write 6595 output vram_a10, // Value for A10 address line 6596 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6597 reg [6:0] chr_bank_0, chr_bank_1, chr_bank_2, chr_bank_3; 6598 reg [6:0] nametable_0, nametable_1; 6599 reg [2:0] prg_bank; 6600 reg use_chr_rom; 6601 reg mirroring; 6602 always @(posedge clk) if (reset) begin 6603 chr_bank_0 <= 0; 6604 chr_bank_1 <= 0; 6605 chr_bank_2 <= 0; 6606 chr_bank_3 <= 0; 6607 nametable_0 <= 0; 6608 nametable_1 <= 0; 6609 prg_bank <= 0; 6610 use_chr_rom <= 0; 6611 mirroring <= 0; 6612 end else if (ce) begin 6613 if (prg_ain[15] && prg_write) begin 6614// $write("REG[%d] <= %X\n", prg_ain[14:12], prg_din); 6615 case(prg_ain[14:12]) 6616 0: chr_bank_0 <= prg_din[6:0]; // $8000-$8FFF: 2kB CHR bank at $0000 6617 1: chr_bank_1 <= prg_din[6:0]; // $9000-$9FFF: 2kB CHR bank at $0800 6618 2: chr_bank_2 <= prg_din[6:0]; // $A000-$AFFF: 2kB CHR bank at $1000 6619 3: chr_bank_3 <= prg_din[6:0]; // $B000-$BFFF: 2kB CHR bank at $1800 6620 4: nametable_0 <= prg_din[6:0]; // $C000-$CFFF: 1kB Nametable register 0 at $2000 6621 5: nametable_1 <= prg_din[6:0]; // $D000-$DFFF: 1kB Nametable register 1 at $2400 6622 6: {use_chr_rom, mirroring} <= {prg_din[4], prg_din[0]}; // $E000-$EFFF: Nametable control 6623 7: prg_bank <= prg_din[2:0]; 6624 endcase 6625 end 6626 end 6627 wire [2:0] prgout = (prg_ain[14] ? 3'b111 : prg_bank); 6628 assign prg_aout = {5'b00_000, prgout, prg_ain[13:0]}; 6629 assign prg_allow = prg_ain[15] && !prg_write; 6630 6631 reg [6:0] chrout; 6632 always begin 6633 casez(chr_ain[12:11]) 6634 0: chrout = chr_bank_0; 6635 1: chrout = chr_bank_1; 6636 2: chrout = chr_bank_2; 6637 3: chrout = chr_bank_3; 6638 endcase 6639 end 6640 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 6641 wire [6:0] nameout = (vram_a10 == 0) ? nametable_0 : nametable_1; 6642 6643 assign chr_allow = flags[15]; 6644 assign chr_aout = (chr_ain[13] == 0) ? {4'b10_00, chrout, chr_ain[10:0]} : {5'b10_001, nameout, chr_ain[9:0]}; 6645 assign vram_ce = chr_ain[13] && !use_chr_rom; 6646 6647endmodule 6648 6649// 69 - Sunsoft FME-7 6650module Mapper69(input clk, input ce, input reset, 6651 input [31:0] flags, 6652 input [15:0] prg_ain, output [21:0] prg_aout, 6653 input prg_read, prg_write, // Read / write signals 6654 input [7:0] prg_din, 6655 output prg_allow, // Enable access to memory for the specified operation. 6656 input [13:0] chr_ain, output [21:0] chr_aout, 6657 output chr_allow, // Allow write 6658 output reg vram_a10, // Value for A10 address line 6659 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 6660 output reg irq); 6661 reg [7:0] chr_bank[0:7]; 6662 reg [4:0] prg_bank[0:3]; 6663 reg [1:0] mirroring; 6664 reg irq_countdown, irq_trigger; 6665 reg [15:0] irq_counter; 6666 reg [3:0] addr; 6667 reg ram_enable, ram_select; 6668 wire [16:0] new_irq_counter = irq_counter - {15'b0, irq_countdown}; 6669 always @(posedge clk) if (reset) begin 6670 chr_bank[0] <= 0; 6671 chr_bank[1] <= 0; 6672 chr_bank[2] <= 0; 6673 chr_bank[3] <= 0; 6674 chr_bank[4] <= 0; 6675 chr_bank[5] <= 0; 6676 chr_bank[6] <= 0; 6677 chr_bank[7] <= 0; 6678 prg_bank[0] <= 0; 6679 prg_bank[1] <= 0; 6680 prg_bank[2] <= 0; 6681 prg_bank[3] <= 0; 6682 mirroring <= 0; 6683 irq_countdown <= 0; 6684 irq_trigger <= 0; 6685 irq_counter <= 0; 6686 addr <= 0; 6687 ram_enable <= 0; 6688 ram_select <= 0; 6689 irq <= 0; 6690 end else if (ce) begin 6691 irq_counter <= new_irq_counter[15:0]; 6692 if (irq_trigger && new_irq_counter[16]) irq <= 1; 6693 if (!irq_trigger) irq <= 0; 6694 6695 if (prg_ain[15] & prg_write) begin 6696 case (prg_ain[14:13]) 6697 0: addr <= prg_din[3:0]; 6698 1: begin 6699 case(addr) 6700 0,1,2,3,4,5,6,7: chr_bank[addr[2:0]] <= prg_din; 6701 8,9,10,11: prg_bank[addr[1:0]] <= prg_din[4:0]; 6702 12: mirroring <= prg_din[1:0]; 6703 13: {irq_countdown, irq_trigger} <= {prg_din[7], prg_din[0]}; 6704 14: irq_counter[7:0] <= prg_din; 6705 15: irq_counter[15:8] <= prg_din; 6706 endcase 6707 if (addr == 8) {ram_enable, ram_select} <= prg_din[7:6]; 6708 end 6709 endcase 6710 end 6711 end 6712 always begin 6713 casez(mirroring[1:0]) 6714 2'b00 : vram_a10 = {chr_ain[10]}; // vertical 6715 2'b01 : vram_a10 = {chr_ain[11]}; // horizontal 6716 2'b1? : vram_a10 = {mirroring[0]}; // 1 screen lower 6717 endcase 6718 end 6719 reg [4:0] prgout; 6720 reg [7:0] chrout; 6721 always begin 6722 casez(prg_ain[15:13]) 6723 3'b011: prgout = prg_bank[0]; 6724 3'b100: prgout = prg_bank[1]; 6725 3'b101: prgout = prg_bank[2]; 6726 3'b110: prgout = prg_bank[3]; 6727 3'b111: prgout = 5'b11111; 6728 default: prgout = 5'bxxxxx; 6729 endcase 6730 chrout = chr_bank[chr_ain[12:10]]; 6731 end 6732 wire ram_cs = (prg_ain[15] == 0 && ram_select); 6733 assign prg_aout = {1'b0, ram_cs, 2'b00, prgout[4:0], prg_ain[12:0]}; 6734 assign prg_allow = ram_cs ? ram_enable : !prg_write; 6735 assign chr_allow = flags[15]; 6736 assign chr_aout = {4'b10_00, chrout, chr_ain[9:0]}; 6737 assign vram_ce = chr_ain[13]; 6738endmodule 6739 6740// #71,#232 - Camerica 6741module Mapper71(input clk, input ce, input reset, 6742 input [31:0] flags, 6743 input [15:0] prg_ain, output [21:0] prg_aout, 6744 input prg_read, prg_write, // Read / write signals 6745 input [7:0] prg_din, 6746 output prg_allow, // Enable access to memory for the specified operation. 6747 input [13:0] chr_ain, output [21:0] chr_aout, 6748 output chr_allow, // Allow write 6749 output vram_a10, // Value for A10 address line 6750 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6751 reg [3:0] prg_bank; 6752 reg ciram_select; 6753 wire mapper232 = (flags[7:0] == 232); 6754 always @(posedge clk) if (reset) begin 6755 prg_bank <= 0; 6756 ciram_select <= 0; 6757 end else if (ce) begin 6758 if (prg_ain[15] && prg_write) begin 6759 $write("%X <= %X (bank = %x)\n", prg_ain, prg_din, prg_bank); 6760 if (!prg_ain[14] && mapper232) // $8000-$BFFF Outer bank select (only on iNES 232) 6761 prg_bank[3:2] <= prg_din[4:3]; 6762 if (prg_ain[14:13] == 0) // $8000-$9FFF Fire Hawk Mirroring 6763 ciram_select <= prg_din[4]; 6764 if (prg_ain[14]) // $C000-$FFFF Bank select 6765 prg_bank <= {mapper232 ? prg_bank[3:2] : prg_din[3:2], prg_din[1:0]}; 6766 end 6767 end 6768 reg [3:0] prgout; 6769 always begin 6770 casez({prg_ain[14], mapper232}) 6771 2'b0?: prgout = prg_bank; 6772 2'b10: prgout = 4'b1111; 6773 2'b11: prgout = {prg_bank[3:2], 2'b11}; 6774 endcase 6775 end 6776 assign prg_aout = {4'b00_00, prgout, prg_ain[13:0]}; 6777 assign prg_allow = prg_ain[15] && !prg_write; 6778 assign chr_allow = flags[15]; 6779 assign chr_aout = {9'b10_0000_000, chr_ain[12:0]}; 6780 assign vram_ce = chr_ain[13]; 6781 // XXX(ludde): Fire hawk uses flags[14] == 0 while no other game seems to do that. 6782 // So when flags[14] == 0 we use ciram_select instead. 6783 assign vram_a10 = flags[14] ? chr_ain[10] : ciram_select; 6784endmodule 6785 6786// #79,#113 - NINA-03 / NINA-06 6787module Mapper79(input clk, input ce, input reset, 6788 input [31:0] flags, 6789 input [15:0] prg_ain, output [21:0] prg_aout, 6790 input prg_read, prg_write, // Read / write signals 6791 input [7:0] prg_din, 6792 output prg_allow, // Enable access to memory for the specified operation. 6793 input [13:0] chr_ain, output [21:0] chr_aout, 6794 output chr_allow, // Allow write 6795 output vram_a10, // Value for A10 address line 6796 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 6797 reg [2:0] prg_bank; 6798 reg [3:0] chr_bank; 6799 reg mirroring; // 0: Horizontal, 1: Vertical 6800 wire mapper113 = (flags[7:0] == 113); // NINA-06 6801 always @(posedge clk) if (reset) begin 6802 prg_bank <= 0; 6803 chr_bank <= 0; 6804 mirroring <= 0; 6805 end else if (ce) begin 6806 if (prg_ain[15:13] == 3'b010 && prg_ain[8] && prg_write) 6807 {mirroring, chr_bank[3], prg_bank, chr_bank[2:0]} <= prg_din; 6808 end 6809 assign prg_aout = {4'b00_00, prg_bank, prg_ain[14:0]}; 6810 assign prg_allow = prg_ain[15] && !prg_write; 6811 assign chr_allow = flags[15]; 6812 assign chr_aout = {5'b10_000, chr_bank, chr_ain[12:0]}; 6813 assign vram_ce = chr_ain[13]; 6814 wire mirrconfig = mapper113 ? mirroring : flags[14]; // Mapper #13 has mapper controlled mirroring 6815 assign vram_a10 = mirrconfig ? chr_ain[10] : chr_ain[11]; // 0: horiz, 1: vert 6816endmodule 6817 6818// #105 - NES-EVENT. Retrofits an MMC3 with lots of extra logic. 6819module NesEvent(input clk, input ce, input reset, 6820 input [15:0] prg_ain, output reg [21:0] prg_aout, 6821 input [13:0] chr_ain, output [21:0] chr_aout, 6822 input [3:0] mmc1_chr, // Upper 4 CHR output control bits from MMC chip 6823 input [21:0] mmc1_aout, // PRG output address from MMC chip 6824 output irq); 6825 // $A000-BFFF: [...I OAA.] 6826 // I = IRQ control / initialization toggle 6827 // O = PRG Mode/Chip select 6828 // A = PRG Reg 'A' 6829 // Mapper gets "initialized" by setting I bit to 0 then to 1. 6830 // On powerup and reset, the first 32k of PRG (from the first PRG chip) is selected at $8000 *no matter what*. 6831 // PRG cannot be swapped until the mapper has been "initialized" by setting the 'I' bit to 0, then to '1'. This 6832 // toggling will "unlock" PRG swapping on the mapper. 6833 reg unlocked, old_val; 6834 reg [29:0] counter; 6835 6836 reg [3:0] oldbits; 6837 always @(posedge clk) if (reset) begin 6838 old_val <= 0; 6839 unlocked <= 0; 6840 counter <= 0; 6841 end else if (ce) begin 6842 // Handle unlock. 6843 if (mmc1_chr[3] && !old_val) unlocked <= 1; 6844 old_val <= mmc1_chr[3]; 6845 // The 'I' bit in $A000 controls the IRQ counter. When cleared, the IRQ counter counts up every cycle. When 6846 // set, the IRQ counter is reset to 0 and stays there (does not count), and the pending IRQ is acknowledged. 6847 counter <= mmc1_chr[3] ? 0 : counter + 1; 6848 6849 if (mmc1_chr != oldbits) begin 6850 $write("NESEV Control Bits: %X => %X (%d)\n", oldbits, mmc1_chr, unlocked); 6851 oldbits <= mmc1_chr; 6852 end 6853 end 6854 // In the official tournament, 'C' was closed, and the others were open, so the counter had to reach $2800000. 6855 assign irq = (counter[29:25] == 5'b10100); 6856 always begin 6857 if (!prg_ain[15]) begin 6858 // WRAM is always routed as usual. 6859 prg_aout = mmc1_aout; 6860 end else if (!unlocked) begin 6861 // Not initialized yet, mapper switch disabled. 6862 prg_aout = {7'b00_0000_0, prg_ain[14:0]}; 6863 end else if (mmc1_chr[2] == 0) begin 6864 // O=0: Use first PRG chip (first 128k), use 'A' PRG Reg, 32k swap 6865 prg_aout = {5'b00_000, mmc1_chr[1:0], prg_ain[14:0]}; 6866 end else begin 6867 // O=1: Use second PRG chip (second 128k), use 'B' PRG Reg, MMC1 style swap 6868 prg_aout = mmc1_aout; 6869 end 6870 end 6871 // 8kB CHR RAM. 6872 assign chr_aout = {9'b10_0000_000, chr_ain[12:0]}; 6873endmodule 6874 6875// mapper 165 6876module Mapper165(input clk, input ce, input reset, 6877 input [31:0] flags, 6878 input [15:0] prg_ain, output [21:0] prg_aout, 6879 input prg_read, prg_write, // Read / write signals 6880 input [7:0] prg_din, 6881 output prg_allow, // Enable access to memory for the specified operation. 6882 input chr_read, input [13:0] chr_ain, output [21:0] chr_aout, 6883 output chr_allow, // Allow write 6884 output vram_a10, // Value for A10 address line 6885 output vram_ce, // True if the address should be routed to the internal 2kB VRAM. 6886 output reg irq); 6887 reg [2:0] bank_select; // Register to write to next 6888 reg prg_rom_bank_mode; // Mode for PRG banking 6889 reg chr_a12_invert; // Mode for CHR banking 6890 reg mirroring; // 0 = vertical, 1 = horizontal 6891 reg irq_enable, irq_reload; // IRQ enabled, and IRQ reload requested 6892 reg [7:0] irq_latch, counter; // IRQ latch value and current counter 6893 reg ram_enable, ram_protect; // RAM protection bits 6894 reg [5:0] prg_bank_0, prg_bank_1; // Selected PRG banks 6895 wire prg_is_ram; 6896 6897 reg [6:0] chr_bank_0, chr_bank_1; // Selected CHR banks 6898 reg [7:0] chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5; 6899 reg latch_0, latch_1; 6900 6901 wire [7:0] new_counter = (counter == 0 || irq_reload) ? irq_latch : counter - 1; 6902 reg [3:0] a12_ctr; 6903 6904 always @(posedge clk) if (reset) begin 6905 irq <= 0; 6906 bank_select <= 0; 6907 prg_rom_bank_mode <= 0; 6908 chr_a12_invert <= 0; 6909 mirroring <= flags[14]; 6910 {irq_enable, irq_reload} <= 0; 6911 {irq_latch, counter} <= 0; 6912 {ram_enable, ram_protect} <= 0; 6913 {chr_bank_0, chr_bank_1, chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5} <= 0; 6914 {prg_bank_0, prg_bank_1} <= 0; 6915 a12_ctr <= 0; 6916 end else if (ce) begin 6917 6918 if (prg_write && prg_ain[15]) begin 6919 case({prg_ain[14], prg_ain[13], prg_ain[0]}) 6920 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, bank_select} <= {prg_din[7], prg_din[6], prg_din[2:0]}; // Bank select ($8000-$9FFE, even) 6921 3'b00_1: begin // Bank data ($8001-$9FFF, odd) 6922 case (bank_select) 6923 0: chr_bank_0 <= prg_din[7:1]; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); 6924 1: chr_bank_1 <= prg_din[7:1]; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); 6925 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); 6926 3: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); 6927 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); 6928 5: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); 6929 6: prg_bank_0 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); 6930 7: prg_bank_1 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF 6931 endcase 6932 end 6933 3'b01_0: mirroring <= prg_din[0]; // Mirroring ($A000-$BFFE, even) 6934 3'b01_1: {ram_enable, ram_protect} <= prg_din[7:6]; // PRG RAM protect ($A001-$BFFF, odd) 6935 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) 6936 3'b10_1: irq_reload <= 1; // IRQ reload ($C001-$DFFF, odd) 6937 3'b11_0: begin irq_enable <= 0; irq <= 0; end // IRQ disable ($E000-$FFFE, even) 6938 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) 6939 endcase 6940 end 6941 6942 // Trigger IRQ counter on rising edge of chr_ain[12] 6943 // All MMC3A's and non-Sharp MMC3B's will generate only a single IRQ when $C000 is $00. 6944 // This is because this version of the MMC3 generates IRQs when the scanline counter is decremented to 0. 6945 // In addition, writing to $C001 with $C000 still at $00 will result in another single IRQ being generated. 6946 // In the community, this is known as the "alternate" or "old" behavior. 6947 // All MMC3C's and Sharp MMC3B's will generate an IRQ on each scanline while $C000 is $00. 6948 // This is because this version of the MMC3 generates IRQs when the scanline counter is equal to 0. 6949 // In the community, this is known as the "normal" or "new" behavior. 6950 if (chr_ain[12] && a12_ctr == 0) begin 6951 counter <= new_counter; 6952 if ( (counter != 0 || irq_reload) && new_counter == 0 && irq_enable) begin 6953// $write("MMC3 SCANLINE IRQ!\n"); 6954 irq <= 1; 6955 end 6956 irq_reload <= 0; 6957 end 6958 a12_ctr <= chr_ain[12] ? 4'b1111 : (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; 6959 end 6960 6961 // The PRG bank to load. Each increment here is 8kb. So valid values are 0..63. 6962 reg [5:0] prgsel; 6963 always @* begin 6964 casez({prg_ain[14:13], prg_rom_bank_mode}) 6965 3'b00_0: prgsel = prg_bank_0; // $8000 mode 0 6966 3'b00_1: prgsel = 6'b111110; // $8000 fixed to second last bank 6967 3'b01_?: prgsel = prg_bank_1; // $A000 mode 0,1 6968 3'b10_0: prgsel = 6'b111110; // $C000 fixed to second last bank 6969 3'b10_1: prgsel = prg_bank_0; // $C000 mode 1 6970 3'b11_?: prgsel = 6'b111111; // $E000 fixed to last bank 6971 endcase 6972 end 6973 wire [21:0] prg_aout_tmp = {3'b00_0, prgsel, prg_ain[12:0]}; 6974 6975// PPU reads $0FD0: latch 0 is set to $FD for subsequent reads 6976// PPU reads $0FE0: latch 0 is set to $FE for subsequent reads 6977// PPU reads $1FD0 through $1FDF: latch 1 is set to $FD for subsequent reads 6978// PPU reads $1FE0 through $1FEF: latch 1 is set to $FE for subsequent reads 6979 always @(posedge clk) if (ce && chr_read) begin 6980 latch_0 <= (chr_ain & 14'h3fff) == 14'h0fd0 ? 0 : (chr_ain & 14'h3fff) == 14'h0fe0 ? 1 : latch_0; 6981 latch_1 <= (chr_ain & 14'h3ff0) == 14'h1fd0 ? 0 : (chr_ain & 14'h3ff0) == 14'h1fe0 ? 1 : latch_1; 6982 end 6983 6984 // The CHR bank to load. Each increment here is 1kb. So valid values are 0..255. 6985 reg [7:0] chrsel; 6986 always @* begin 6987 casez({chr_ain[12] ^ chr_a12_invert, latch_0, latch_1}) 6988 3'b0_0?: chrsel = {chr_bank_0, chr_ain[10]}; // 2Kb page 6989 3'b0_1?: chrsel = {chr_bank_1, chr_ain[10]}; // 2Kb page 6990 3'b1_?0: chrsel = chr_bank_2; 6991 3'b1_?1: chrsel = chr_bank_4; 6992 endcase 6993 end 6994 6995 assign {chr_allow, chr_aout} = {flags[15] && (chrsel < 4), 4'b10_00, chrsel, chr_ain[9:0]}; 6996 6997 assign prg_is_ram = prg_ain >= 'h6000 && prg_ain < 'h8000 && ram_enable && !(ram_protect && prg_write); 6998 assign prg_allow = prg_ain[15] && !prg_write || prg_is_ram; 6999 wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]}; 7000 assign prg_aout = prg_is_ram ? prg_ram : prg_aout_tmp; 7001 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 7002 assign vram_ce = chr_ain[13]; 7003endmodule 7004 7005// iNES Mapper 228 represents the board used by Active Enterprises for Action 52 and Cheetahmen II. 7006module Mapper228(input clk, input ce, input reset, 7007 input [31:0] flags, 7008 input [15:0] prg_ain, output [21:0] prg_aout, 7009 input prg_read, prg_write, // Read / write signals 7010 input [7:0] prg_din, 7011 output prg_allow, // Enable access to memory for the specified operation. 7012 input [13:0] chr_ain, output [21:0] chr_aout, 7013 output chr_allow, // Allow write 7014 output vram_a10, // Value for A10 address line 7015 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 7016 reg mirroring; 7017 reg [1:0] prg_chip; 7018 reg [4:0] prg_bank; 7019 reg prg_bank_mode; 7020 reg [5:0] chr_bank; 7021 always @(posedge clk) if (reset) begin 7022 {mirroring, prg_chip, prg_bank, prg_bank_mode} <= 0; 7023 chr_bank <= 0; 7024 end else if (ce) begin 7025 if (prg_ain[15] & prg_write) begin 7026 {mirroring, prg_chip, prg_bank, prg_bank_mode} <= prg_ain[13:5]; 7027 chr_bank <= {prg_ain[3:0], prg_din[1:0]}; 7028 end 7029 end 7030 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 7031 wire prglow = prg_bank_mode ? prg_bank[0] : prg_ain[14]; 7032 wire [1:0] addrsel = {prg_chip[1], prg_chip[1] ^ prg_chip[0]}; 7033 assign prg_aout = {1'b0, addrsel, prg_bank[4:1], prglow, prg_ain[13:0]}; 7034 assign prg_allow = prg_ain[15] && !prg_write; 7035 assign chr_allow = flags[15]; 7036 assign chr_aout = {3'b10_0, chr_bank, chr_ain[12:0]}; 7037 assign vram_ce = chr_ain[13]; 7038endmodule 7039 7040module Mapper234(input clk, input ce, input reset, 7041 input [31:0] flags, 7042 input [15:0] prg_ain, output [21:0] prg_aout, 7043 input prg_read, prg_write, // Read / write signals 7044 input [7:0] prg_din, 7045 output prg_allow, // Enable access to memory for the specified operation. 7046 input [13:0] chr_ain, output [21:0] chr_aout, 7047 output chr_allow, // Allow write 7048 output vram_a10, // Value for A10 address line 7049 output vram_ce); // True if the address should be routed to the internal 2kB VRAM. 7050 reg [2:0] block, inner_chr; 7051 reg mode, mirroring, inner_prg; 7052 always @(posedge clk) if (reset) begin 7053 block <= 0; 7054 {mode, mirroring} <= 0; 7055 inner_chr <= 0; 7056 inner_prg <= 0; 7057 end else if (ce) begin 7058 if (prg_read && prg_ain[15:7] == 9'b1111_1111_1) begin 7059 // Outer bank control $FF80 - $FF9F 7060 if (prg_ain[6:0] < 7'h20 && (block == 0)) begin 7061 {mirroring, mode} <= prg_din[7:6]; 7062 block <= prg_din[3:1]; 7063 {inner_chr[2], inner_prg} <= {prg_din[0], prg_din[0]}; 7064 end 7065 // Inner bank control ($FFE8-$FFF7) 7066 if (prg_ain[6:0] >= 7'h68 && prg_ain[6:0] < 7'h78) begin 7067 {inner_chr[2], inner_prg} <= mode ? {prg_din[6], prg_din[0]} : {inner_chr[2], inner_prg}; 7068 inner_chr[1:0] <= prg_din[5:4]; 7069 end 7070 end 7071 end 7072 assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10]; 7073 assign prg_aout = {3'b00_0, block, inner_prg, prg_ain[14:0]}; 7074 assign chr_aout = {3'b10_0, block, inner_chr, chr_ain[12:0]}; 7075 assign prg_allow = prg_ain[15] && !prg_write; 7076 assign chr_allow = flags[15]; 7077 assign vram_ce = chr_ain[13]; 7078endmodule 7079 7080module MultiMapper(input clk, input ce, input ppu_ce, input reset, 7081 input [19:0] ppuflags, // Misc flags from PPU for MMC5 cheating 7082 input [31:0] flags, // Misc flags from ines header {prg_size(3), chr_size(3), mapper(8)} 7083 input [15:0] prg_ain, output reg [21:0] prg_aout,// PRG Input / Output Address Lines 7084 input prg_read, prg_write, // PRG Read / write signals 7085 input [7:0] prg_din, output reg [7:0] prg_dout, // PRG Data 7086 input [7:0] prg_from_ram, // PRG Data from RAM 7087 output reg prg_allow, // PRG Allow write access 7088 input chr_read, // Read from CHR 7089 input [13:0] chr_ain, output reg [21:0] chr_aout,// CHR Input / Output Address Lines 7090 output reg [7:0] chr_dout, // Value to override CHR data with 7091 output reg has_chr_dout, // True if CHR data should be overridden 7092 output reg chr_allow, // CHR Allow write 7093 output reg vram_a10, // CHR Value for A10 address line 7094 output reg vram_ce, // CHR True if the address should be routed to the internal 2kB VRAM. 7095 output reg irq); 7096 wire mmc0_prg_allow, mmc0_vram_a10, mmc0_vram_ce, mmc0_chr_allow; 7097 wire [21:0] mmc0_prg_addr, mmc0_chr_addr; 7098 MMC0 mmc0(clk, ce, flags, prg_ain, mmc0_prg_addr, prg_read, prg_write, prg_din, mmc0_prg_allow, 7099 chr_ain, mmc0_chr_addr, mmc0_chr_allow, mmc0_vram_a10, mmc0_vram_ce); 7100 7101 wire mmc1_prg_allow, mmc1_vram_a10, mmc1_vram_ce, mmc1_chr_allow; 7102 wire [21:0] mmc1_prg_addr, mmc1_chr_addr; 7103 MMC1 mmc1(clk, ce, reset, flags, prg_ain, mmc1_prg_addr, prg_read, prg_write, prg_din, mmc1_prg_allow, 7104 chr_ain, mmc1_chr_addr, mmc1_chr_allow, mmc1_vram_a10, mmc1_vram_ce); 7105 7106 wire map28_prg_allow, map28_vram_a10, map28_vram_ce, map28_chr_allow; 7107 wire [21:0] map28_prg_addr, map28_chr_addr; 7108 Mapper28 map28(clk, ce, reset, flags, prg_ain, map28_prg_addr, prg_read, prg_write, prg_din, map28_prg_allow, 7109 chr_ain, map28_chr_addr, map28_chr_allow, map28_vram_a10, map28_vram_ce); 7110 7111 wire mmc2_prg_allow, mmc2_vram_a10, mmc2_vram_ce, mmc2_chr_allow; 7112 wire [21:0] mmc2_prg_addr, mmc2_chr_addr; 7113 MMC2 mmc2(clk, ppu_ce, reset, flags, prg_ain, mmc2_prg_addr, prg_read, prg_write, prg_din, mmc2_prg_allow, 7114 chr_read, chr_ain, mmc2_chr_addr, mmc2_chr_allow, mmc2_vram_a10, mmc2_vram_ce); 7115 7116 wire mmc3_prg_allow, mmc3_vram_a10, mmc3_vram_ce, mmc3_chr_allow, mmc3_irq; 7117 wire [21:0] mmc3_prg_addr, mmc3_chr_addr; 7118 MMC3 mmc3(clk, ppu_ce, reset, flags, prg_ain, mmc3_prg_addr, prg_read, prg_write, prg_din, mmc3_prg_allow, 7119 chr_ain, mmc3_chr_addr, mmc3_chr_allow, mmc3_vram_a10, mmc3_vram_ce, mmc3_irq); 7120 7121 wire mmc4_prg_allow, mmc4_vram_a10, mmc4_vram_ce, mmc4_chr_allow; 7122 wire [21:0] mmc4_prg_addr, mmc4_chr_addr; 7123 MMC4 mmc4(clk, ppu_ce, reset, flags, prg_ain, mmc4_prg_addr, prg_read, prg_write, prg_din, mmc4_prg_allow, 7124 chr_read, chr_ain, mmc4_chr_addr, mmc4_chr_allow, mmc4_vram_a10, mmc4_vram_ce); 7125 7126 wire mmc5_prg_allow, mmc5_vram_a10, mmc5_vram_ce, mmc5_chr_allow, mmc5_irq; 7127 wire [21:0] mmc5_prg_addr, mmc5_chr_addr; 7128 wire [7:0] mmc5_chr_dout, mmc5_prg_dout; 7129 wire mmc5_has_chr_dout; 7130 MMC5 mmc5(clk, ppu_ce, reset, flags, ppuflags, prg_ain, mmc5_prg_addr, prg_read, prg_write, prg_din, mmc5_prg_dout, mmc5_prg_allow, 7131 chr_ain, mmc5_chr_addr, mmc5_chr_dout, mmc5_has_chr_dout, 7132 mmc5_chr_allow, mmc5_vram_a10, mmc5_vram_ce, mmc5_irq); 7133 7134 wire map13_prg_allow, map13_vram_a10, map13_vram_ce, map13_chr_allow; 7135 wire [21:0] map13_prg_addr, map13_chr_addr; 7136 Mapper13 map13(clk, ce, reset, flags, prg_ain, map13_prg_addr, prg_read, prg_write, prg_din, map13_prg_allow, 7137 chr_ain, map13_chr_addr, map13_chr_allow, map13_vram_a10, map13_vram_ce); 7138 7139 wire map15_prg_allow, map15_vram_a10, map15_vram_ce, map15_chr_allow; 7140 wire [21:0] map15_prg_addr, map15_chr_addr; 7141 Mapper15 map15(clk, ce, reset, flags, prg_ain, map15_prg_addr, prg_read, prg_write, prg_din, map15_prg_allow, 7142 chr_ain, map15_chr_addr, map15_chr_allow, map15_vram_a10, map15_vram_ce); 7143 7144 wire map16_prg_allow, map16_vram_a10, map16_vram_ce, map16_chr_allow, map16_irq; 7145 wire [21:0] map16_prg_addr, map16_chr_addr; 7146 wire [7:0] map16_prg_dout; 7147 Mapper16 map16(clk, ce, reset, flags, prg_ain, map16_prg_addr, prg_read, prg_write, prg_din, map16_prg_dout, map16_prg_allow, 7148 chr_ain, map16_chr_addr, map16_chr_allow, map16_vram_a10, map16_vram_ce, map16_irq); 7149 7150 wire map34_prg_allow, map34_vram_a10, map34_vram_ce, map34_chr_allow; 7151 wire [21:0] map34_prg_addr, map34_chr_addr; 7152 Mapper34 map34(clk, ce, reset, flags, prg_ain, map34_prg_addr, prg_read, prg_write, prg_din, map34_prg_allow, 7153 chr_ain, map34_chr_addr, map34_chr_allow, map34_vram_a10, map34_vram_ce); 7154 7155 wire map41_prg_allow, map41_vram_a10, map41_vram_ce, map41_chr_allow; 7156 wire [21:0] map41_prg_addr, map41_chr_addr; 7157 Mapper41 map41(clk, ce, reset, flags, prg_ain, map41_prg_addr, prg_read, prg_write, prg_din, map41_prg_allow, 7158 chr_ain, map41_chr_addr, map41_chr_allow, map41_vram_a10, map41_vram_ce); 7159 7160 wire map42_prg_allow, map42_vram_a10, map42_vram_ce, map42_chr_allow, map42_irq; 7161 wire [21:0] map42_prg_addr, map42_chr_addr; 7162 Mapper42 map42(clk, ce, reset, flags, prg_ain, map42_prg_addr, prg_read, prg_write, prg_din, map42_prg_allow, 7163 chr_ain, map42_chr_addr, map42_chr_allow, map42_vram_a10, map42_vram_ce, map42_irq); 7164 7165 wire map66_prg_allow, map66_vram_a10, map66_vram_ce, map66_chr_allow; 7166 wire [21:0] map66_prg_addr, map66_chr_addr; 7167 Mapper66 map66(clk, ce, reset, flags, prg_ain, map66_prg_addr, prg_read, prg_write, prg_din, map66_prg_allow, 7168 chr_ain, map66_chr_addr, map66_chr_allow, map66_vram_a10, map66_vram_ce); 7169 7170 wire map68_prg_allow, map68_vram_a10, map68_vram_ce, map68_chr_allow; 7171 wire [21:0] map68_prg_addr, map68_chr_addr; 7172 Mapper68 map68(clk, ce, reset, flags, prg_ain, map68_prg_addr, prg_read, prg_write, prg_din, map68_prg_allow, 7173 chr_ain, map68_chr_addr, map68_chr_allow, map68_vram_a10, map68_vram_ce); 7174 7175 wire map69_prg_allow, map69_vram_a10, map69_vram_ce, map69_chr_allow, map69_irq; 7176 wire [21:0] map69_prg_addr, map69_chr_addr; 7177 Mapper69 map69(clk, ce, reset, flags, prg_ain, map69_prg_addr, prg_read, prg_write, prg_din, map69_prg_allow, 7178 chr_ain, map69_chr_addr, map69_chr_allow, map69_vram_a10, map69_vram_ce, map69_irq); 7179 7180 wire map71_prg_allow, map71_vram_a10, map71_vram_ce, map71_chr_allow; 7181 wire [21:0] map71_prg_addr, map71_chr_addr; 7182 Mapper71 map71(clk, ce, reset, flags, prg_ain, map71_prg_addr, prg_read, prg_write, prg_din, map71_prg_allow, 7183 chr_ain, map71_chr_addr, map71_chr_allow, map71_vram_a10, map71_vram_ce); 7184 7185 wire map79_prg_allow, map79_vram_a10, map79_vram_ce, map79_chr_allow; 7186 wire [21:0] map79_prg_addr, map79_chr_addr; 7187 Mapper79 map79(clk, ce, reset, flags, prg_ain, map79_prg_addr, prg_read, prg_write, prg_din, map79_prg_allow, 7188 chr_ain, map79_chr_addr, map79_chr_allow, map79_vram_a10, map79_vram_ce); 7189 7190 wire map165_prg_allow, map165_vram_a10, map165_vram_ce, map165_chr_allow, map165_irq; 7191 wire [21:0] map165_prg_addr, map165_chr_addr; 7192 Mapper165 map165(clk, ppu_ce, reset, flags, prg_ain, map165_prg_addr, prg_read, prg_write, prg_din, map165_prg_allow, 7193 chr_read, chr_ain, map165_chr_addr, map165_chr_allow, map165_vram_a10, map165_vram_ce, map165_irq); 7194 7195 wire map228_prg_allow, map228_vram_a10, map228_vram_ce, map228_chr_allow; 7196 wire [21:0] map228_prg_addr, map228_chr_addr; 7197 Mapper228 map228(clk, ce, reset, flags, prg_ain, map228_prg_addr, prg_read, prg_write, prg_din, map228_prg_allow, 7198 chr_ain, map228_chr_addr, map228_chr_allow, map228_vram_a10, map228_vram_ce); 7199 7200 7201 wire map234_prg_allow, map234_vram_a10, map234_vram_ce, map234_chr_allow; 7202 wire [21:0] map234_prg_addr, map234_chr_addr; 7203 Mapper234 map234(clk, ce, reset, flags, prg_ain, map234_prg_addr, prg_read, prg_write, prg_from_ram, map234_prg_allow, 7204 chr_ain, map234_chr_addr, map234_chr_allow, map234_vram_a10, map234_vram_ce); 7205 7206 wire rambo1_prg_allow, rambo1_vram_a10, rambo1_vram_ce, rambo1_chr_allow, rambo1_irq; 7207 wire [21:0] rambo1_prg_addr, rambo1_chr_addr; 7208 Rambo1 rambo1(clk, ce, reset, flags, prg_ain, rambo1_prg_addr, prg_read, prg_write, prg_din, rambo1_prg_allow, 7209 chr_ain, rambo1_chr_addr, rambo1_chr_allow, rambo1_vram_a10, rambo1_vram_ce, rambo1_irq); 7210 7211 wire [21:0] nesev_prg_addr, nesev_chr_addr; 7212 wire nesev_irq; 7213 NesEvent nesev(clk, ce, reset, prg_ain, nesev_prg_addr, chr_ain, nesev_chr_addr, mmc1_chr_addr[16:13], mmc1_prg_addr, nesev_irq); 7214 7215 // Mask 7216 reg [5:0] prg_mask; 7217 reg [6:0] chr_mask; 7218 7219 always @* begin 7220 case(flags[10:8]) 7221 0: prg_mask = 6'b000000; 7222 1: prg_mask = 6'b000001; 7223 2: prg_mask = 6'b000011; 7224 3: prg_mask = 6'b000111; 7225 4: prg_mask = 6'b001111; 7226 5: prg_mask = 6'b011111; 7227 default: prg_mask = 6'b111111; 7228 endcase 7229 7230 case(flags[13:11]) 7231 0: chr_mask = 7'b0000000; 7232 1: chr_mask = 7'b0000001; 7233 2: chr_mask = 7'b0000011; 7234 3: chr_mask = 7'b0000111; 7235 4: chr_mask = 7'b0001111; 7236 5: chr_mask = 7'b0011111; 7237 6: chr_mask = 7'b0111111; 7238 7: chr_mask = 7'b1111111; 7239 endcase 7240 7241 irq = 0; 7242 prg_dout = 8'hff; 7243 has_chr_dout = 0; 7244 chr_dout = mmc5_chr_dout; 7245// 0 = Working 7246// 1 = Working 7247// 2 = Working 7248// 3 = Working 7249// 4 = Working 7250// 5 = Working 7251// 7 = Working 7252// 9 = Working 7253// 10 = Working 7254// 11 = Working 7255// 13 = Working 7256// 15 = Working 7257// 16 = Working minus EEPROM support 7258// 28 = Working 7259// 34 = Working 7260// 41 = Working 7261// 42 = Working 7262// 47 = Working 7263// 64 = Tons of GFX bugs 7264// 66 = Working 7265// 68 = Working 7266// 69 = Working 7267// 71 = Working 7268// 79 = Working 7269// 105 = Working 7270// 113 = Working 7271// 118 = Working 7272// 119 = Working 7273// 158 = Tons of GFX bugs 7274// 165 = GFX corrupted 7275// 209 = Not Tested 7276// 228 = Working 7277// 234 = Not Tested 7278 case(flags[7:0]) 7279 1: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {mmc1_prg_addr, mmc1_prg_allow, mmc1_chr_addr, mmc1_vram_a10, mmc1_vram_ce, mmc1_chr_allow}; 7280 9: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {mmc2_prg_addr, mmc2_prg_allow, mmc2_chr_addr, mmc2_vram_a10, mmc2_vram_ce, mmc2_chr_allow}; 7281 118, // TxSROM connects A17 to CIRAM A10. 7282 119, // TQROM uses the Nintendo MMC3 like other TxROM boards but uses the CHR bank number specially. 7283 47, // Mapper 047 is a MMC3 multicart 7284 206, // MMC3 w/o IRQ or WRAM support 7285 4: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq} = {mmc3_prg_addr, mmc3_prg_allow, mmc3_chr_addr, mmc3_vram_a10, mmc3_vram_ce, mmc3_chr_allow, mmc3_irq}; 7286 7287 10: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {mmc4_prg_addr, mmc4_prg_allow, mmc4_chr_addr, mmc4_vram_a10, mmc4_vram_ce, mmc4_chr_allow}; 7288 7289 5: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, has_chr_dout, prg_dout, irq} = {mmc5_prg_addr, mmc5_prg_allow, mmc5_chr_addr, mmc5_vram_a10, mmc5_vram_ce, mmc5_chr_allow, mmc5_has_chr_dout, mmc5_prg_dout, mmc5_irq}; 7290 7291 0, 7292 2, 7293 3, 7294 7, 7295 28: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map28_prg_addr, map28_prg_allow, map28_chr_addr, map28_vram_a10, map28_vram_ce, map28_chr_allow}; 7296 7297 13: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map13_prg_addr, map13_prg_allow, map13_chr_addr, map13_vram_a10, map13_vram_ce, map13_chr_allow}; 7298 15: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map15_prg_addr, map15_prg_allow, map15_chr_addr, map15_vram_a10, map15_vram_ce, map15_chr_allow}; 7299 7300 16: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, prg_dout, irq} = {map16_prg_addr, map16_prg_allow, map16_chr_addr, map16_vram_a10, map16_vram_ce, map16_chr_allow, map16_prg_dout, map16_irq}; 7301 7302 34: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map34_prg_addr, map34_prg_allow, map34_chr_addr, map34_vram_a10, map34_vram_ce, map34_chr_allow}; 7303 41: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map41_prg_addr, map41_prg_allow, map41_chr_addr, map41_vram_a10, map41_vram_ce, map41_chr_allow}; 7304 7305 64, 7306 158: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq} = {rambo1_prg_addr, rambo1_prg_allow, rambo1_chr_addr, rambo1_vram_a10, rambo1_vram_ce, rambo1_chr_allow, rambo1_irq}; 7307 7308 42: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq} = {map42_prg_addr, map42_prg_allow, map42_chr_addr, map42_vram_a10, map42_vram_ce, map42_chr_allow, map42_irq}; 7309 7310 11, 7311 66: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map66_prg_addr, map66_prg_allow, map66_chr_addr, map66_vram_a10, map66_vram_ce, map66_chr_allow}; 7312 68: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map68_prg_addr, map68_prg_allow, map68_chr_addr, map68_vram_a10, map68_vram_ce, map68_chr_allow}; 7313 69: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq} = {map69_prg_addr, map69_prg_allow, map69_chr_addr, map69_vram_a10, map69_vram_ce, map69_chr_allow, map69_irq}; 7314 7315 71, 7316 232: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map71_prg_addr, map71_prg_allow, map71_chr_addr, map71_vram_a10, map71_vram_ce, map71_chr_allow}; 7317 7318 79, 7319 113: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map79_prg_addr, map79_prg_allow, map79_chr_addr, map79_vram_a10, map79_vram_ce, map79_chr_allow}; 7320 7321 105: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq}= {nesev_prg_addr, mmc1_prg_allow, nesev_chr_addr, mmc1_vram_a10, mmc1_vram_ce, mmc1_chr_allow, nesev_irq}; 7322 7323 165: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq} = {map165_prg_addr, map165_prg_allow, map165_chr_addr, map165_vram_a10, map165_vram_ce, map165_chr_allow, map165_irq}; 7324 7325 228: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map228_prg_addr, map228_prg_allow, map228_chr_addr, map228_vram_a10, map228_vram_ce, map228_chr_allow}; 7326 234: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map234_prg_addr, map234_prg_allow, map234_chr_addr, map234_vram_a10, map234_vram_ce, map234_chr_allow}; 7327 default: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {mmc0_prg_addr, mmc0_prg_allow, mmc0_chr_addr, mmc0_vram_a10, mmc0_vram_ce, mmc0_chr_allow}; 7328 endcase 7329 if (prg_aout[21:20] == 2'b00) 7330 prg_aout[19:0] = {prg_aout[19:14] & prg_mask, prg_aout[13:0]}; 7331 if (chr_aout[21:20] == 2'b10) 7332 chr_aout[19:0] = {chr_aout[19:13] & chr_mask, chr_aout[12:0]}; 7333 // Remap the CHR address into VRAM, if needed. 7334 chr_aout = vram_ce ? {11'b11_0000_0000_0, vram_a10, chr_ain[9:0]} : chr_aout; 7335 prg_aout = (prg_ain < 'h2000) ? {11'b11_1000_0000_0, prg_ain[10:0]} : prg_aout; 7336 prg_allow = prg_allow || (prg_ain < 'h2000); 7337 end 7338endmodule 7339 7340// PRG = 0.... 7341// CHR = 10... 7342// CHR-VRAM = 1100 7343// CPU-RAM = 1110 7344// CARTRAM = 1111 7345 // Copyright (c) 2012-2013 Ludvig Strigeus 7346// This program is GPL Licensed. See COPYING for the full license. 7347 7348 7349// Copyright (c) 2012-2013 Ludvig Strigeus 7350// This program is GPL Licensed. See COPYING for the full license. 7351 7352module video( 7353 input clk, 7354 input [5:0] color, 7355 input [8:0] count_h, 7356 input [8:0] count_v, 7357 input mode, 7358 input ypbpr, 7359 input smoothing, 7360 input scanlines, 7361 input overscan, 7362 input palette, 7363 7364 7365 output VGA_HS, 7366 output VGA_VS, 7367 output [3:0] VGA_R, 7368 output [3:0] VGA_G, 7369 output [3:0] VGA_B, 7370 7371 output osd_visible 7372); 7373 7374reg clk2 = 1'b0; 7375always @(posedge clk) clk2 <= ~clk2; 7376wire clkv = mode ? clk2 : clk; 7377 7378wire [5:0] R_out, G_out, B_out; 7379 7380 7381 7382// NTSC UnsaturatedV6 palette 7383//see: http://www.firebrandx.com/nespalette.html 7384/*reg [15:0] pal_unsat_lut[0:63]; 7385initial $readmemh("nes_palette_unsaturatedv6.txt", pal_unsat_lut);*/ 7386 7387// FCEUX palette 7388reg [15:0] pal_fcelut[0:63]; 7389initial begin 7390 pal_fcelut[0] = 16'h39ce; 7391 pal_fcelut[1] = 16'h4464; 7392 pal_fcelut[2] = 16'h5400; 7393 pal_fcelut[3] = 16'h4c08; 7394 pal_fcelut[4] = 16'h3811; 7395 pal_fcelut[5] = 16'h0815; 7396 pal_fcelut[6] = 16'h0014; 7397 pal_fcelut[7] = 16'h002f; 7398 pal_fcelut[8] = 16'h00a8; 7399 pal_fcelut[9] = 16'h0100; 7400 pal_fcelut[10] = 16'h0140; 7401 pal_fcelut[11] = 16'h08e0; 7402 pal_fcelut[12] = 16'h2ce3; 7403 pal_fcelut[13] = 16'h0000; 7404 pal_fcelut[14] = 16'h0000; 7405 pal_fcelut[15] = 16'h0000; 7406 pal_fcelut[16] = 16'h5ef7; 7407 pal_fcelut[17] = 16'h75c0; 7408 pal_fcelut[18] = 16'h74e4; 7409 pal_fcelut[19] = 16'h7810; 7410 pal_fcelut[20] = 16'h5c17; 7411 pal_fcelut[21] = 16'h2c1c; 7412 pal_fcelut[22] = 16'h00bb; 7413 pal_fcelut[23] = 16'h0539; 7414 pal_fcelut[24] = 16'h01d1; 7415 pal_fcelut[25] = 16'h0240; 7416 pal_fcelut[26] = 16'h02a0; 7417 pal_fcelut[27] = 16'h1e40; 7418 pal_fcelut[28] = 16'h4600; 7419 pal_fcelut[29] = 16'h0000; 7420 pal_fcelut[30] = 16'h0000; 7421 pal_fcelut[31] = 16'h0000; 7422 pal_fcelut[32] = 16'h7fff; 7423 pal_fcelut[33] = 16'h7ee7; 7424 pal_fcelut[34] = 16'h7e4b; 7425 pal_fcelut[35] = 16'h7e28; 7426 pal_fcelut[36] = 16'h7dfe; 7427 pal_fcelut[37] = 16'h59df; 7428 pal_fcelut[38] = 16'h31df; 7429 pal_fcelut[39] = 16'h1e7f; 7430 pal_fcelut[40] = 16'h1efe; 7431 pal_fcelut[41] = 16'h0b50; 7432 pal_fcelut[42] = 16'h2769; 7433 pal_fcelut[43] = 16'h4feb; 7434 pal_fcelut[44] = 16'h6fa0; 7435 pal_fcelut[45] = 16'h3def; 7436 pal_fcelut[46] = 16'h0000; 7437 pal_fcelut[47] = 16'h0000; 7438 pal_fcelut[48] = 16'h7fff; 7439 pal_fcelut[49] = 16'h7f95; 7440 pal_fcelut[50] = 16'h7f58; 7441 pal_fcelut[51] = 16'h7f3a; 7442 pal_fcelut[52] = 16'h7f1f; 7443 pal_fcelut[53] = 16'h6f1f; 7444 pal_fcelut[54] = 16'h5aff; 7445 pal_fcelut[55] = 16'h577f; 7446 pal_fcelut[56] = 16'h539f; 7447 pal_fcelut[57] = 16'h53fc; 7448 pal_fcelut[58] = 16'h5fd5; 7449 pal_fcelut[59] = 16'h67f6; 7450 pal_fcelut[60] = 16'h7bf3; 7451 pal_fcelut[61] = 16'h6318; 7452 pal_fcelut[62] = 16'h0000; 7453 pal_fcelut[63] = 16'h0000; 7454 7455end 7456 7457wire [14:0] pixel = pal_fcelut[color][14:0]; 7458 7459// Horizontal and vertical counters 7460reg [9:0] h, v; 7461wire hpicture = (h < 512); // 512 lines of picture 7462wire hend = (h == 681); // End of line, 682 pixels. 7463wire vpicture = (v < (480 >> mode)); // 480 lines of picture 7464wire vend = (v == (523 >> mode)); // End of picture, 524 lines. (Should really be 525 according to NTSC spec) 7465 7466wire [14:0] doubler_pixel; 7467wire doubler_sync; 7468 7469scan_double doubler(clk, pixel, 7470 count_v[8], // reset_frame 7471 (count_h[8:3] == 42), // reset_line 7472 {v[0], h[9] ? 9'd0 : h[8:0] + 9'd1}, // 0-511 for line 1, or 512-1023 for line 2. 7473 doubler_pixel); // pixel is outputted 7474 7475 7476reg [8:0] old_count_v; 7477wire sync_frame = (old_count_v == 9'd511) && (count_v == 9'd0); 7478 7479assign doubler_sync = sync_frame; 7480 7481always @(posedge clkv) begin 7482 h <= (hend || (mode ? sync_frame : doubler_sync)) ? 10'd0 : h + 10'd1; 7483 if(mode ? sync_frame : doubler_sync) v <= 0; 7484 else if (hend) v <= vend ? 10'd0 : v + 10'd1; 7485 7486 old_count_v <= count_v; 7487end 7488 7489wire [14:0] pixel_v = (!hpicture || !vpicture) ? 15'd0 : mode ? pixel : doubler_pixel; 7490wire darker = !mode && v[0] && scanlines; 7491 7492// display overlay to hide overscan area 7493// based on Mario3, DoubleDragon2, Shadow of the Ninja 7494wire ol = overscan && ( (h > 512-16) || 7495 (h < 20) || 7496 (v < (mode ? 6 : 12)) || 7497 (v > (mode ? 240-10 : 480-20)) 7498 ); 7499 7500wire [4:0] vga_r = ol ? {4'b0, pixel_v[4:4]} : (darker ? {1'b0, pixel_v[4:1]} : pixel_v[4:0]); 7501wire [4:0] vga_g = ol ? {4'b0, pixel_v[9:9]} : (darker ? {1'b0, pixel_v[9:6]} : pixel_v[9:5]); 7502wire [4:0] vga_b = ol ? {4'b0, pixel_v[14:14]} : (darker ? {1'b0, pixel_v[14:11]} : pixel_v[14:10]); 7503wire sync_h = ((h >= (512 + 23 + (mode ? 18 : 35))) && (h < (512 + 23 + (mode ? 18 : 35) + 82))); 7504wire sync_v = ((v >= (mode ? 240 + 5 : 480 + 10)) && (v < (mode ? 240 + 14 : 480 + 12))); 7505 7506 7507assign VGA_HS = !sync_h; 7508assign VGA_VS = !sync_v; 7509assign VGA_R = vga_r[4:1]; 7510assign VGA_G = vga_g[4:1]; 7511assign VGA_B = vga_b[4:1]; 7512 7513endmodule 7514/* 7515The virtual NES cartridge 7516At the moment this stores the entire cartridge 7517in SPRAM, in the future it could stream data from 7518SQI flash, which is more than fast enough 7519*/ 7520 7521module cart_mem( 7522 input clock, 7523 input reset, 7524 7525 input reload, 7526 input [3:0] index, 7527 7528 output cart_ready, 7529 output reg [31:0] flags_out, 7530 //address into a given section - 0 is the start of CHR and PRG, 7531 //region is selected using the select lines for maximum flexibility 7532 //in partitioning 7533 input [20:0] address, 7534 7535 input prg_sel, chr_sel, 7536 input ram_sel, //for cart SRAM (NYI) 7537 7538 input rden, wren, 7539 7540 input [7:0] write_data, 7541 output [7:0] read_data, 7542 7543 //Flash load interface 7544 output flash_csn, 7545 output flash_sck, 7546 output flash_mosi, 7547 input flash_miso 7548); 7549 7550reg load_done; 7551initial load_done = 1'b0; 7552 7553wire cart_ready = load_done; 7554// Does the image use CHR RAM instead of ROM? (i.e. UNROM or some MMC1) 7555wire is_chram = flags_out[15]; 7556// Work out whether we're in the SPRAM, used for the main ROM, or the extra 8k SRAM 7557wire spram_en = prg_sel | (!is_chram && chr_sel); 7558wire sram_en = ram_sel | (is_chram && chr_sel); 7559 7560wire [16:0] decoded_address; 7561assign decoded_address = chr_sel ? {1'b1, address[15:0]} : address[16:0]; 7562 7563reg [15:0] load_addr; 7564wire [14:0] spram_address = load_done ? decoded_address[16:2] : load_addr[14:0]; 7565 7566wire load_wren; 7567wire spram_wren = load_done ? (spram_en && wren) : load_wren; 7568wire [3:0] spram_mask = load_done ? (4'b0001 << decoded_address[1:0]) : 4'b1111; 7569wire [3:0] spram_maskwren = spram_wren ? spram_mask : 4'b0000; 7570 7571wire [31:0] load_write_data; 7572wire [31:0] spram_write_data = load_done ? {write_data, write_data, write_data, write_data} : load_write_data; 7573 7574wire [31:0] spram_read_data; 7575 7576wire [7:0] csram_read_data; 7577// Demux the 32-bit memory 7578assign read_data = sram_en ? csram_read_data : 7579 (decoded_address[1] ? (decoded_address[0] ? spram_read_data[31:24] : spram_read_data[23:16]) : (decoded_address[0] ? spram_read_data[15:8] : spram_read_data[7:0])); 7580 7581 // The SRAM, used either for PROG_SRAM or CHR_SRAM 7582generic_ram #( 7583 .WIDTH(8), 7584 .WORDS(8192) 7585) sram_i ( 7586 .clock(clock), 7587 .reset(reset), 7588 .address(decoded_address[12:0]), 7589 .wren(wren&sram_en), 7590 .write_data(write_data), 7591 .read_data(csram_read_data) 7592); 7593// The SPRAM (with a generic option), which stores 7594// the ROM 7595 7596 reg [7:0] spram_mem0[0:32767]; 7597 reg [7:0] spram_mem1[0:32767]; 7598 reg [7:0] spram_mem2[0:32767]; 7599 reg [7:0] spram_mem3[0:32767]; 7600 reg [31:0] spram_dout_pre; 7601 always @(posedge clock) 7602 begin 7603 spram_dout_pre[7:0] <= spram_mem0[spram_address]; 7604 spram_dout_pre[15:8] <= spram_mem1[spram_address]; 7605 spram_dout_pre[23:16] <= spram_mem2[spram_address]; 7606 spram_dout_pre[31:24] <= spram_mem3[spram_address]; 7607 if(spram_maskwren[0]) spram_mem0[spram_address] <= spram_write_data[7:0]; 7608 if(spram_maskwren[1]) spram_mem1[spram_address] <= spram_write_data[15:8]; 7609 if(spram_maskwren[2]) spram_mem2[spram_address] <= spram_write_data[23:16]; 7610 if(spram_maskwren[3]) spram_mem3[spram_address] <= spram_write_data[31:24]; 7611 end; 7612 assign spram_read_data = spram_dout_pre; 7613 7614 7615wire flashmem_valid = !load_done; 7616wire flashmem_ready; 7617assign load_wren = flashmem_ready && (load_addr != 16'h8000); 7618wire [23:0] flashmem_addr = (24'h100000 + (index_lat << 18)) | {load_addr, 2'b00}; 7619reg [3:0] index_lat; 7620reg load_done_pre; 7621 7622reg [7:0] wait_ctr; 7623// Flash memory load interface 7624always @(posedge clock) 7625begin 7626 if (reset == 1'b1) begin 7627 load_done_pre <= 1'b0; 7628 load_done <= 1'b0; 7629 load_addr <= 16'h0000; 7630 flags_out <= 32'h00000000; 7631 wait_ctr <= 8'h00; 7632 index_lat <= 4'h0; 7633 end else begin 7634 if (reload == 1'b1) begin 7635 load_done_pre <= 1'b0; 7636 load_done <= 1'b0; 7637 load_addr <= 16'h0000; 7638 flags_out <= 32'h00000000; 7639 wait_ctr <= 8'h00; 7640 index_lat <= index; 7641 end else begin 7642 if(!load_done_pre) begin 7643 if (flashmem_ready == 1'b1) begin 7644 if (load_addr == 16'h8000) begin 7645 load_done_pre <= 1'b1; 7646 flags_out <= load_write_data; //last word is mapper flags 7647 end else begin 7648 load_addr <= load_addr + 1'b1; 7649 end; 7650 end 7651 end else begin 7652 if (wait_ctr < 8'hFF) 7653 wait_ctr <= wait_ctr + 1; 7654 else 7655 load_done <= 1'b1; 7656 end 7657 7658 end 7659 end 7660end 7661 7662 7663 7664icosoc_flashmem flash_i ( 7665 .clk(clock), 7666 .reset(reset), 7667 .valid(flashmem_valid), 7668 .ready(flashmem_ready), 7669 .addr(flashmem_addr), 7670 .rdata(load_write_data), 7671 7672 .spi_cs(flash_csn), 7673 .spi_sclk(flash_sck), 7674 .spi_mosi(flash_mosi), 7675 .spi_miso(flash_miso) 7676); 7677 7678endmodule 7679