diff --git a/css/ui.css b/css/ui.css index 4507c00a..0c38b524 100644 --- a/css/ui.css +++ b/css/ui.css @@ -20,16 +20,18 @@ } .tooltipbox .tooltiptext { visibility: hidden; - width: 120px; - background-color: black; + width: 500px; + background-color: #660000; color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; - /* Position the tooltip */ position: absolute; z-index: 10; + /*
 tag wrap */
+     white-space: pre-wrap;       /* css-3 */
+     white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
 }
 .tooltipbox:hover .tooltiptext {
     visibility: visible;
diff --git a/presets/verilog/ball_paddle.v b/presets/verilog/ball_paddle.v
new file mode 100644
index 00000000..31c14788
--- /dev/null
+++ b/presets/verilog/ball_paddle.v
@@ -0,0 +1,106 @@
+`include "hvsync_generator.v"
+
+module ball_paddle_top(clk, hpaddle, hsync, vsync, rgb);
+
+  input clk;
+  input hpaddle;
+  output hsync, vsync;
+  output [2:0] rgb;
+  wire display_on;
+  wire [8:0] hpos;
+  wire [8:0] vpos;
+  
+  reg [8:0] paddle_pos;
+  
+  reg [8:0] ball_x = 128;
+  reg [8:0] ball_y = 128;
+  reg signed [1:0] ball_vel_x = 0;
+  reg ball_vel_y = BALL_VEL_DOWN;
+  
+  localparam BALL_VEL_DOWN = 1;
+  localparam BALL_VEL_UP = 0;
+  
+  localparam PADDLE_WIDTH = 31;
+  localparam BALL_SIZE = 8;
+  
+  hvsync_generator hvsync_gen(
+    .clk(clk),
+    .hsync(hsync),
+    .vsync(vsync),
+    .display_on(display_on),
+    .hpos(hpos),
+    .vpos(vpos)
+  );
+
+  // TODO: only works when paddle at bottom of screen!
+  always @(posedge hsync)
+    if (!hpaddle)
+      paddle_pos <= vpos;
+
+  // TODO: unsigned compare doesn't work in JS
+  wire [8:0] paddle_rel_x = ((hpos-paddle_pos) & 9'h1ff);
+  wire paddle_gfx = paddle_rel_x < PADDLE_WIDTH;
+  
+  wire [8:0] ball_rel_x = (hpos-ball_x);
+  wire [8:0] ball_rel_y = (vpos-ball_y);
+  
+  wire ball_gfx = ball_rel_x < BALL_SIZE
+  	       && ball_rel_y < BALL_SIZE;
+  
+  wire [5:0] hcell = hpos[8:3];
+  wire [5:0] vcell = vpos[8:3];
+  wire lr_border = hcell==0 || hcell==31;
+
+  wire main_gfx;
+  
+  always @(posedge clk)
+    case (vpos[8:3])
+      0: main_gfx = 1;
+      28: main_gfx = paddle_gfx | lr_border;
+      default: main_gfx = lr_border;
+    endcase;
+  
+  wire ball_pixel_collide = main_gfx & ball_gfx;
+  
+  /* verilator lint_off MULTIDRIVEN */
+  reg [4:0] ball_collide_bits = 0;
+  /* verilator lint_on MULTIDRIVEN */
+
+  always @(posedge clk)
+    if (ball_pixel_collide) begin
+      if (paddle_gfx) begin // did we collide w/ paddle?
+        ball_collide_bits[4] <= 1;
+      end else begin // collided with playfield
+        if (!ball_rel_x[2] & !ball_rel_y[2]) ball_collide_bits[0] <= 1;
+        if (ball_rel_x[2] & !ball_rel_y[2]) ball_collide_bits[1] <= 1;
+        if (!ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[2] <= 1;
+        if (ball_rel_x[2] & ball_rel_y[2]) ball_collide_bits[3] <= 1;
+      end
+    end
+  
+  always @(posedge vsync)
+    begin
+      if (ball_collide_bits[4]) begin // collided with paddle?
+        reg signed [1:0] ball_paddle_dx = ball_x[6:5] - paddle_pos[6:5];
+        ball_vel_y <= BALL_VEL_UP; // paddle top
+        ball_vel_x <= ball_vel_x + ball_paddle_dx;
+      end else casez (ball_collide_bits[3:0]) // collided with playfield
+        0: ;
+        4'b01?1: if (ball_vel_x<0) ball_vel_x <= -ball_vel_x-1; // left
+        4'b101?: if (ball_vel_x>=0) ball_vel_x <= -ball_vel_x-1; // right
+        4'b1100: ball_vel_y <= BALL_VEL_UP;
+        4'b0011: ball_vel_y <= BALL_VEL_DOWN;
+      endcase;
+      ball_collide_bits <= 0;
+      ball_x <= ball_x + 9'(ball_vel_x) + 9'(ball_vel_x>=0); // TODO: signed?
+      ball_y <= ball_y + (ball_vel_y==BALL_VEL_DOWN?1:-1);
+    end;
+  
+  wire grid_gfx = (((hpos&7)==0) || ((vpos&7)==0));
+
+  wire r = display_on && (grid_gfx | ball_gfx);
+  wire g = display_on && (main_gfx | ball_gfx);
+  wire b = display_on && ball_gfx;
+  assign rgb = {b,g,r};
+
+endmodule
diff --git a/presets/verilog/hvsync_generator.v b/presets/verilog/hvsync_generator.v
index 99ec0e00..3415412d 100644
--- a/presets/verilog/hvsync_generator.v
+++ b/presets/verilog/hvsync_generator.v
@@ -1,12 +1,12 @@
 
 module hvsync_generator(
-  clk, hsync, vsync, inDisplayArea, CounterX, CounterY);
+  clk, hsync, vsync, display_on, hpos, vpos);
 
   input clk;
   output hsync, vsync;
-  output inDisplayArea;
-  output [8:0] CounterX;
-  output [8:0] CounterY;
+  output reg display_on;
+  output reg [8:0] hpos;
+  output reg [8:0] vpos;
 
   // constant declarations for VGA sync parameters
   localparam H_DISPLAY       = 256; // horizontal display area
@@ -25,35 +25,32 @@ module hvsync_generator(
   localparam START_V_RETRACE = V_DISPLAY + V_B_BORDER;
   localparam END_V_RETRACE   = V_DISPLAY + V_B_BORDER + V_RETRACE - 1;
 
-  reg [8:0] CounterX;
-  reg [8:0] CounterY;
-  wire CounterXmaxed = (CounterX==H_MAX);
-  wire CounterYmaxed = (CounterY==V_MAX);
+  wire hmaxxed = (hpos==H_MAX);
+  wire vmaxxed = (vpos==V_MAX);
 
   always @(posedge clk)   
-    if(CounterXmaxed)
-      CounterX <= 0;
+    if(hmaxxed)
+      hpos <= 0;
     else
-      CounterX <= CounterX + 1;
+      hpos <= hpos + 1;
 
   always @(posedge clk)
-    if(CounterXmaxed)
-      if (!CounterYmaxed)
-        CounterY <= CounterY + 1;
+    if(hmaxxed)
+      if (!vmaxxed)
+        vpos <= vpos + 1;
       else
-        CounterY <= 0;
+        vpos <= 0;
 
   reg vga_HS, vga_VS;
   always @(posedge clk)
   begin
-    vga_HS <= (CounterX>=280 && CounterX<288); // change this value to move the display horizontally
-    vga_VS <= (CounterY==START_V_RETRACE); // change this value to move the display vertically
+    vga_HS <= (hpos>=280 && hpos<288); // change this value to move the display horizontally
+    vga_VS <= (vpos==START_V_RETRACE); // change this value to move the display vertically
   end
 
-  reg inDisplayArea;
   always @(posedge clk)
   begin
-    inDisplayArea <= (CounterX VL_EXTENDS_II(x,lbits,rhs); }
+
+  var VL_LTES_III = this.VL_LTES_III = function(x,lbits,y,lhs,rhs) {
+    return VL_EXTENDS_II(x,lbits,lhs) <= VL_EXTENDS_II(x,lbits,rhs); }
+
+  var VL_GTES_III = this.VL_GTES_III = function(x,lbits,y,lhs,rhs) {
+    return VL_EXTENDS_II(x,lbits,lhs) >= VL_EXTENDS_II(x,lbits,rhs); }
+
+//
+
 function VerilatorBase() {
-  this.VL_RAND_RESET_I = function(bits) { return Math.floor(Math.random() * (1< maxv) ? maxv : v;
+  }
+
   this.start = function() {
     // TODO
     video = new RasterVideo(mainElement,videoWidth,videoHeight);
     video.create();
     setKeyboardFromMap(video, switches, VERILOG_KEYCODE_MAP);
 		$(video.canvas).mousemove(function(e) {
-			paddle_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width());
-			paddle_y = Math.floor(e.offsetY * video.canvas.height / $(video.canvas).height() - 20);
+			paddle_x = clamp(4,255,Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 20));
+			paddle_y = clamp(4,255,Math.floor(e.offsetY * video.canvas.height / $(video.canvas).height() - 20));
 		});
     audio = new SampleAudio(AUDIO_FREQ);
     idata = video.getFrameData();
diff --git a/src/ui.js b/src/ui.js
index aff27b10..b609880a 100644
--- a/src/ui.js
+++ b/src/ui.js
@@ -172,7 +172,7 @@ function scrollProfileView(_ed) {
 }
 
 function newEditor(mode) {
-  var isAsm = (mode != 'text/x-csrc');
+  var isAsm = mode=='6502' || mode =='z80';
   editor = CodeMirror(document.getElementById('editor'), {
     theme: 'mbo',
     lineNumbers: true,