reg [2:0] failandloss;
        assign {vgar, vgag, vgab} =
-               ((vgax > `XOFS) && (vgax < (`XOFS + 161)) && (vgay > `YOFS) && (vgay < (`YOFS + 144))) ? {failandloss[2],2'b0,failandloss[1],2'b0,failandloss[0],1'b0} :
+               ((vgax > `XOFS) && (vgax < (`XOFS + 161)) && (vgay > `YOFS) && (vgay < (`YOFS + 144))) ? {failandloss[2],failandloss[1],1'b0,failandloss[2],failandloss[1],1'b0,failandloss[0],1'b0} :
                ((vgax < 640) && (vgay < 480)) ? 8'b00000000 :
                8'b00000000;
        
 
        wire [10:0] tileaddr = {tileno, vypos[2:0]};
        reg [7:0] tilehigh, tilelow;
        wire [1:0] prepal = {tilehigh[7-vxpos[2:0]], tilelow[7-vxpos[2:0]]};
-       assign pixdata = {rBGP[{prepal,1'b1}],rBGP[{prepal,1'b0}]};
+       assign pixdata = 2'b11-{rBGP[{prepal,1'b1}],rBGP[{prepal,1'b0}]};
        
        wire decode_tiledata = (addr >= 16'h8000) && (addr <= 16'h97FF);
        wire decode_bgmap1 = (addr >= 16'h9800) && (addr <= 16'h9BFF);
 
 
 `timescale 1ns / 1ps
-module ROM(
+module SimROM(
        input [15:0] address,
        inout [7:0] data,
        input clk,
        reg rdlatch = 0;
        reg [7:0] odata;
 
-       // synthesis attribute ram_style of rom is block
-       reg [7:0] rom [1023:0];
+       reg [7:0] rom [32767:0];
        initial $readmemh("rom.hex", rom);
 
        wire decode = address[15:13] == 0;
        
        initial $readmemh("fpgaboot.hex", brom0);
        initial $readmemh("gbboot.hex", brom1);
+       
+`ifdef isim
+       initial romno <= 1;
+`endif
 
        wire decode = address[15:8] == 0;
        wire [7:0] odata = (romno == 0) ? brom0[addrlatch] : brom1[addrlatch];
        parameter ADDR_PROGADDRM = 16'hFF61;
        parameter ADDR_PROGADDRL = 16'hFF62;
        parameter ADDR_PROGDATA = 16'hFF63;
+       parameter ADDR_MBC = 16'hFF64;
        
        reg rdlatch = 0, wrlatch = 0;
        reg [15:0] addrlatch = 0;
        
        reg [22:0] progaddr;
        
+       reg [7:0] mbc_emul = 8'b00000101;       // High bit is whether we're poking flash
+                                               // low 7 bits are the MBC that we are emulating
+       
        assign cr_nADV = 0;     /* Addresses are always valid! :D */
        assign cr_nCE = 0;      /* The chip is enabled */
        assign cr_nLB = 0;      /* Lower byte is enabled */
        
        wire decode = (addrlatch[15:14] == 2'b00) /* extrom */ || (addrlatch[15:13] == 3'b101) /* extram */ || (addrlatch == ADDR_PROGDATA);
        
+       reg [3:0] rambank = 0;
+       reg [8:0] rombank = 1;
+       
        assign cr_nOE = decode ? ~rdlatch : 1;
-       assign cr_nWE = decode ? ~wrlatch : 1;
+       assign cr_nWE = (decode && ((addrlatch == ADDR_PROGDATA) || (mbc_emul[6:0] == 0))) ? ~wrlatch : 1;
        
        assign cr_DQ = (~cr_nOE) ? 16'bzzzzzzzzzzzzzzzz : {8'b0, datalatch};
-       assign cr_A = (address[15:14] == 2'b00) ? /* extrom */ {9'b0,address[13:0]} :
-                       (address[15:13] == 3'b101) ? {1'b1, 9'b0, address[12:0]} :
-                       (address == ADDR_PROGDATA) ? progaddr :
+       assign cr_A = (addrlatch[15:14] == 2'b00) ? /* extrom, home bank */ {9'b0,addrlatch[13:0]} :
+                       (addrlatch[15:14] == 2'b01) ? /* extrom, paged bank */ {rombank, addrlatch[13:0]} :
+                       (addrlatch[15:13] == 3'b101) ? /* extram */ {1'b1, 5'b0, rambank, addrlatch[12:0]} :
+                       (addrlatch == ADDR_PROGDATA) ? progaddr :
                        23'b0;
        
-       reg [7:0] regbuf;
-       
        always @(posedge clk) begin
                case (address)
                ADDR_PROGADDRH: if (wr) progaddrh <= data;
                                        progaddr <= {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]};
                                        {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]} <= {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]} + 23'b1;
                                end
+               ADDR_MBC:       begin
+                                       mbc_emul <= data;
+                                       rambank <= 0;
+                                       rombank <= 1;
+                               end
                endcase
+               
+               if (mbc_emul[6:0] == 5) begin
+                       if ((address[15:12] == 4'h2) && wr)
+                               rombank <= {rombank[8], data};
+                       else if ((address[15:12] == 4'h3) && wr)
+                               rombank <= {data[0], rombank[7:0]};
+                       else if ((address[15:12] == 4'h4) && wr)
+                               rambank <= data[3:0];
+               end
+               
                rdlatch <= rd;
                wrlatch <= wr;
                addrlatch <= address;
                .rd(rd[1]));
        
 `ifdef isim
-       ROM rom(
+       SimROM rom(
                .address(addr[0]),
                .data(data[0]),
                .clk(clk),
                .vgar(r),
                .vgag(g),
                .vgab(b));
-       
+
+       Switches sw(
+               .clk(clk),
+               .address(addr[0]),
+               .data(data[0]),
+               .wr(wr[0]),
+               .rd(rd[0]),
+               .ledout(leds),
+               .switches(switches)
+               );
+
        AddrMon amon(
                .clk(clk), 
                .addr(addr[0]),
                        (state == 2'b10) ? 4'b1000 :
                                           4'b0100) );
         
-       Switches sw(
-               .clk(clk),
-               .address(addr[0]),
-               .data(data[0]),
-               .wr(wr[0]),
-               .rd(rd[0]),
-               .ledout(leds),
-               .switches(switches)
-               );
-
        UART nouart (   /* no u */
                .clk(clk),
                .addr(addr[0]),
 
   return poll(&pfd, 1, timeout) == 1;
 }
 
-void expect(char *s, int len)
+int expect(char *s, int len)
 {
   int i;
   char c;
   for (i=0; i < len; i++)
   {
-    if (waitchar(100) == 0)
+    if (waitchar(1000) == 0)
     {
       fprintf(stderr, "Timeout reached in expect (expected %c)\n", s[i]);
-      return;
+      return 1;
     }
     while (read(0, &c, 1) == 0)
       fprintf(stderr, "Short read...\n");
     if (c != s[i])
+    {
       fprintf(stderr, "Expect failed: expected %d, got %d (pos %d)\n", s[i], c, i);
+      return 1;
+    }
   }
+  return 0;
 }
 
 void expect_no_chars()
   }
   if (cs)
     fprintf(stderr, "Expect no chars failed: got %d chars\n", cs);
-  
-  
 }
 
 void main(int argc, char **argv)
   unsigned char buf[259];
   int sz;
   int rfd;
+  int tc = 0;
   
   if (argc < 2)
   {
   expect_no_chars();
   while ((sz = read(rfd, buf+3, 255)) > 0)
   {
+    int rv;
     buf[0] = 0x1B;
     buf[1] = 'D';
     buf[2] = sz+1;
+    tc += sz;
+    retry:
     dowrite(buf, sz + 3);
-    fprintf(stderr, "Data sent\n");
-    expect("D", 1);
+    fprintf(stderr, "Data sent (%d)\n", tc);
+    rv = expect("D", 1);
     expect_no_chars();
+    if (rv)
+    {
+      printf("Failure to ack... retrying\n");
+      dowrite("...", 3);
+      rv = expect("...", 3);
+      expect_no_chars();
+      goto retry;
+    }
   }
   exit(0);
 }
\ No newline at end of file