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