mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-06 13:30:01 +00:00
updated presets; verilog code dup detect; need to handle local/ include files somehow
This commit is contained in:
parent
94a932c08d
commit
2dbc60aa2e
@ -1 +1 @@
|
||||
Subproject commit ebf81921f80024e3e94c7a8e1235ab59464fa5ef
|
||||
Subproject commit 4334727f0e07acd4541b0a7b8f81a5984cd4aafe
|
75
demo.html
75
demo.html
@ -34,9 +34,10 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="https://twitter.com/8bitworkshop">@8bitworkshop</a>
|
||||
<span class="navbar-brand"><a target="_new" href="https://twitter.com/8bitworkshop" class="twitter-follow-button" data-show-count="false">Follow @8bitworkshop</a></span>
|
||||
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
<a class="navbar-brand" href="./blog/">Blog</a>
|
||||
<a class="navbar-brand" href="https://www.amazon.com/default/e/B01N7J10NF/ref=dp_byline_cont_pop_book_1">Books</a>
|
||||
<a class="navbar-brand" href="https://www.amazon.com/default/e/B01N7J10NF/ref=dp_byline_cont_pop_book_1" target="_blank" onclick="ga('send', 'event', 'books', 'click');">Books</a>
|
||||
</div>
|
||||
<div id="navbar" class="hidden-sm hidden-xs">
|
||||
<form class="navbar-form navbar-right">
|
||||
@ -80,11 +81,12 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
We've got debugging tools too; single step through your code and use our CPU Cycle Analyzer to
|
||||
develop that perfect Stella kernel.
|
||||
</p>
|
||||
<img class="img-responsive" src="images/atarivcs.jpg">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h2>Arcade Games</h2>
|
||||
<p>
|
||||
You can develop your own games on classic arcade game hardware, using our in-browser C compiler.
|
||||
You can develop your own games on classic arcade game hardware, using our in-browser C compiler targeting the Z80 CPU.
|
||||
Platforms include
|
||||
<a href="redir.html?platform=vicdual">VIC Dual</a>,
|
||||
<a href="redir.html?platform=mw8080bw">Midway 8080</a>,
|
||||
@ -92,8 +94,54 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
<a href="redir.html?platform=vector-z80color">Atari Vector</a>,
|
||||
and
|
||||
<a href="redir.html?platform=williams-z80">Williams</a>.
|
||||
<img class="img-responsive" src="images/arcadegames.jpg">
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
We're always adding new things here, so subscribe to our mailing list for updates!
|
||||
</p>
|
||||
<style> .gumroad-follow-form-embed { zoom: 1; } .gumroad-follow-form-embed:before, .gumroad-follow-form-embed:after { display: table; line-height: 0; content: ""; } .gumroad-follow-form-embed:after { clear: both; } .gumroad-follow-form-embed * { margin: 0; border: 0; padding: 0; outline: 0; box-sizing: border-box !important; float: left !important; } .gumroad-follow-form-embed input { border-radius: 4px; border-top-right-radius: 0; border-bottom-right-radius: 0; font-family: -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 15px; line-height: 20px; background: #fff; border: 1px solid #ddd; border-right: 0; color: #aaa; padding: 10px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.02); background-position: top right; background-repeat: no-repeat; text-rendering: optimizeLegibility; font-smoothing: antialiased; -webkit-appearance: none; -moz-appearance: caret; width: 65% !important; height: 40px !important; } .gumroad-follow-form-embed button { border-radius: 4px; border-top-left-radius: 0; border-bottom-left-radius: 0; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12); -webkit-transition: all .05s ease-in-out; transition: all .05s ease-in-out; display: inline-block; padding: 11px 15px 12px; cursor: pointer; color: #fff; font-size: 15px; line-height: 100%; font-family: -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", Helvetica, Arial, sans-serif; background: #36a9ae; border: 1px solid #31989d; filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#5ccfd4, endColorstr=#329ca1, GradientType=0)"; background: -webkit-linear-gradient(#5ccfd4, #329ca1); background: linear-gradient(to bottom, #5ccfd4, #329ca1); height: 40px !important; width: 35% !important; } </style> <form action="https://gumroad.com/follow_from_embed_form" class="form gumroad-follow-form-embed" method="post"> <input name="seller_id" type="hidden" value="1507538753888"> <input name="email" placeholder="Your email address" type="email"> <button data-custom-highlight-color="" type="submit">Subscribe</button> </form>
|
||||
<p></p>
|
||||
<!-- Begin MailChimp Signup Form -->
|
||||
<!--
|
||||
<link href="//cdn-images.mailchimp.com/embedcode/classic-10_7.css" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
|
||||
/* Add your own MailChimp form style overrides in your site stylesheet or in this style block.
|
||||
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
|
||||
</style>
|
||||
<div id="mc_embed_signup">
|
||||
<form action="https://8bitworkshop.us19.list-manage.com/subscribe/post?u=819ee5274c8c9c1afe2005023&id=75411a270f" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
|
||||
<div id="mc_embed_signup_scroll">
|
||||
<h2>We're always adding new things here, so subscribe to our mailing list for updates!</h2>
|
||||
<div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
|
||||
<div class="mc-field-group">
|
||||
<label for="mce-EMAIL">Email Address <span class="asterisk">*</span>
|
||||
</label>
|
||||
<input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
|
||||
</div>
|
||||
<div class="mc-field-group">
|
||||
<label for="mce-FNAME">First Name (optional)</label>
|
||||
<input type="text" value="" name="FNAME" class="" id="mce-FNAME">
|
||||
</div>
|
||||
<div class="mc-field-group">
|
||||
<label for="mce-LNAME">Last Name (optional)</label>
|
||||
<input type="text" value="" name="LNAME" class="" id="mce-LNAME">
|
||||
</div>
|
||||
<div id="mce-responses" class="clear">
|
||||
<div class="response" id="mce-error-response" style="display:none"></div>
|
||||
<div class="response" id="mce-success-response" style="display:none"></div>
|
||||
</div>
|
||||
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_819ee5274c8c9c1afe2005023_75411a270f" tabindex="-1" value=""></div>
|
||||
<div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script><script type='text/javascript'>(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';fnames[3]='ADDRESS';ftypes[3]='address';fnames[4]='PHONE';ftypes[4]='phone';}(jQuery));var $mcj = jQuery.noConflict(true);</script>
|
||||
-->
|
||||
<!--End mc_embed_signup-->
|
||||
</div>
|
||||
<!--
|
||||
<div class="col-md-4">
|
||||
<h2>Hardware Design</h2>
|
||||
@ -113,12 +161,12 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1541021304&linkCode=as2&tag=pzp-20&linkId=c149f6365c0a676065eb6d7c5f8dd6ae">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1541021304&linkCode=as2&tag=pzp-20&linkId=c149f6365c0a676065eb6d7c5f8dd6ae" onclick="ga('send', 'event', 'books', 'click', 'vcs');">
|
||||
<img border="0" src="//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=US&ASIN=1541021304&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL250_&tag=pzp-20" ></a>
|
||||
<img src="//ir-na.amazon-adsystem.com/e/ir?t=pzp-20&l=am2&o=1&a=1541021304" />
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1541021304&linkCode=as2&tag=pzp-20&linkId=c149f6365c0a676065eb6d7c5f8dd6ae">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1541021304&linkCode=as2&tag=pzp-20&linkId=c149f6365c0a676065eb6d7c5f8dd6ae" onclick="ga('send', 'event', 'books', 'click', 'vcs');">
|
||||
<h3>Making Games For The Atari 2600</h3>
|
||||
</a>
|
||||
<p>The Atari 2600 was released in 1977, and now there's finally a book about how to write games for it! You'll learn about the 6502 CPU, NTSC frames, scanlines, cycle counting, players, missiles, collisions, procedural generation, pseudo-3D, and more. While using the manual, take advantage of our Web-based IDE to write 6502 assembly code, and see your code run instantly in the browser. We'll cover the same programming tricks that master programmers used to make classic games. Create your own graphics and sound, and share your games with friends!</p>
|
||||
@ -126,18 +174,31 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=2f3c42111bffe3466830939fff4053fc">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=2f3c42111bffe3466830939fff4053fc" onclick="ga('send', 'event', 'books', 'click', 'arcade');">
|
||||
<img border="0" src="//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=US&ASIN=1545484759&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL250_&tag=pzp-20" ></a>
|
||||
<img src="//ir-na.amazon-adsystem.com/e/ir?t=pzp-20&l=am2&o=1&a=1545484759" />
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=2f3c42111bffe3466830939fff4053fc">
|
||||
<a target="_blank" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=2f3c42111bffe3466830939fff4053fc" onclick="ga('send', 'event', 'books', 'click', 'arcade');">
|
||||
<h3>Making 8-Bit Arcade Games in C</h3>
|
||||
</a>
|
||||
<p>With this book, you'll learn all about the hardware of Golden Age 8-bit arcade games produced in the late 1970s to early 1980s. We'll learn how to use the C programming language to write code for the Z80 CPU. The following arcade platforms are covered: * Midway 8080 (Space Invaders) * VIC Dual (Carnival) * Galaxian/Scramble (Namco) * Atari Color Vector * Williams (Defender, Robotron) We'll describe how to create video and sound for each platform. Use the online 8bitworkshop IDE to compile your C programs and play them right in the browser!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
|
@ -48,6 +48,9 @@ TODO:
|
||||
- compile stuck when errors unchanged
|
||||
- sound mute?
|
||||
- $error updates source editor
|
||||
- Revert loads cached files?
|
||||
- Verilog compile spins forever?
|
||||
- how to revert included files?
|
||||
|
||||
WEB WORKER FORMAT
|
||||
|
||||
|
@ -10,16 +10,18 @@ module ball_absolute_top(clk, reset, hsync, vsync, rgb);
|
||||
wire [8:0] hpos;
|
||||
wire [8:0] vpos;
|
||||
|
||||
reg [8:0] ball_hpos;
|
||||
reg [8:0] ball_vpos;
|
||||
reg [8:0] ball_hpos; // ball current X position
|
||||
reg [8:0] ball_vpos; // ball current Y position
|
||||
|
||||
reg [8:0] ball_horiz_initial = 128;
|
||||
reg [8:0] ball_horiz_move = -2;
|
||||
reg [8:0] ball_vert_initial = 128;
|
||||
reg [8:0] ball_vert_move = 2;
|
||||
reg [8:0] ball_horiz_move = -2; // ball current X velocity
|
||||
reg [8:0] ball_vert_move = 2; // ball current Y velocity
|
||||
|
||||
localparam BALL_SIZE = 4;
|
||||
localparam ball_horiz_initial = 128; // ball initial X position
|
||||
localparam ball_vert_initial = 128; // ball initial Y position
|
||||
|
||||
localparam BALL_SIZE = 4; // ball size (in pixels)
|
||||
|
||||
// video sync generator
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
@ -34,9 +36,11 @@ module ball_absolute_top(clk, reset, hsync, vsync, rgb);
|
||||
always @(posedge vsync or posedge reset)
|
||||
begin
|
||||
if (reset) begin
|
||||
// reset ball position to center
|
||||
ball_hpos <= ball_horiz_initial;
|
||||
ball_vpos <= ball_vert_initial;
|
||||
end else begin
|
||||
// add velocity vector to ball position
|
||||
ball_hpos <= ball_hpos + ball_horiz_move;
|
||||
ball_vpos <= ball_vpos + ball_vert_move;
|
||||
end
|
||||
@ -54,19 +58,22 @@ module ball_absolute_top(clk, reset, hsync, vsync, rgb);
|
||||
ball_horiz_move <= -ball_horiz_move;
|
||||
end
|
||||
|
||||
// offset of ball position from video beam
|
||||
wire [8:0] ball_hdiff = hpos - ball_hpos;
|
||||
wire [8:0] ball_vdiff = vpos - ball_vpos;
|
||||
|
||||
// ball graphics output
|
||||
wire ball_hgfx = ball_hdiff < BALL_SIZE;
|
||||
wire ball_vgfx = ball_vdiff < BALL_SIZE;
|
||||
wire ball_gfx = ball_hgfx && ball_vgfx;
|
||||
|
||||
// collide with vertical and horizontal boundaries
|
||||
// these are set when the ball touches a border
|
||||
wire ball_vert_collide = ball_vpos >= 240 - BALL_SIZE;
|
||||
wire ball_horiz_collide = ball_hpos >= 256 - BALL_SIZE;
|
||||
|
||||
wire grid_gfx = (((hpos&7)==0) && ((vpos&7)==0));
|
||||
|
||||
// combine signals to RGB output
|
||||
wire grid_gfx = (((hpos&7)==0) && ((vpos&7)==0));
|
||||
wire r = display_on && (ball_hgfx | ball_gfx);
|
||||
wire g = display_on && (grid_gfx | ball_gfx);
|
||||
wire b = display_on && (ball_vgfx | ball_gfx);
|
||||
|
@ -13,34 +13,34 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
wire [8:0] hpos;
|
||||
wire [8:0] vpos;
|
||||
|
||||
reg [8:0] paddle_pos;
|
||||
reg [8:0] paddle_pos; // paddle X position
|
||||
|
||||
reg [8:0] ball_x;
|
||||
reg [8:0] ball_y;
|
||||
reg ball_dir_x;
|
||||
reg ball_speed_x;
|
||||
reg ball_dir_y;
|
||||
reg [8:0] ball_x; // ball X position
|
||||
reg [8:0] ball_y; // ball Y position
|
||||
reg ball_dir_x; // ball X direction (0=left, 1=right)
|
||||
reg ball_speed_x; // ball speed (0=1 pixel/frame, 1=2 pixels/frame)
|
||||
reg ball_dir_y; // ball Y direction (0=up, 1=down)
|
||||
|
||||
reg brick_array [0:BRICKS_H*BRICKS_V-1]; // 16*8 = 128 bits
|
||||
|
||||
wire [3:0] score0;
|
||||
wire [3:0] score1;
|
||||
wire [3:0] lives;
|
||||
reg incscore;
|
||||
wire [3:0] score0; // score right digit
|
||||
wire [3:0] score1; // score left digit
|
||||
wire [3:0] lives; // # lives remaining
|
||||
reg incscore; // incscore signal
|
||||
reg declives = 0; // TODO
|
||||
|
||||
localparam BRICKS_H = 16;
|
||||
localparam BRICKS_V = 8;
|
||||
localparam BRICKS_H = 16; // # of bricks across
|
||||
localparam BRICKS_V = 8; // # of bricks down
|
||||
|
||||
localparam BALL_DIR_LEFT = 0;
|
||||
localparam BALL_DIR_RIGHT = 1;
|
||||
|
||||
localparam BALL_DIR_DOWN = 1;
|
||||
localparam BALL_DIR_UP = 0;
|
||||
|
||||
localparam PADDLE_WIDTH = 31;
|
||||
localparam BALL_SIZE = 6;
|
||||
|
||||
localparam PADDLE_WIDTH = 31; // horizontal paddle size
|
||||
localparam BALL_SIZE = 6; // square ball size
|
||||
|
||||
// video sync generator
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
@ -52,35 +52,37 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
);
|
||||
|
||||
// scoreboard
|
||||
|
||||
wire score_gfx; // output from score generator
|
||||
player_stats stats(.reset(reset),
|
||||
.score0(score0), .score1(score1), .incscore(incscore),
|
||||
.lives(lives), .declives(declives));
|
||||
|
||||
wire score_gfx;
|
||||
|
||||
scoreboard_generator score_gen(
|
||||
.score0(score0), .score1(score1), .lives(lives),
|
||||
.vpos(vpos), .hpos(hpos),
|
||||
.board_gfx(score_gfx));
|
||||
|
||||
wire [5:0] hcell = hpos[8:3];
|
||||
wire [5:0] vcell = vpos[8:3];
|
||||
wire lr_border = hcell==0 || hcell==31;
|
||||
wire [5:0] hcell = hpos[8:3]; // horizontal brick index
|
||||
wire [5:0] vcell = vpos[8:3]; // vertical brick index
|
||||
wire lr_border = hcell==0 || hcell==31; // along horizontal border?
|
||||
|
||||
// TODO: unsigned compare doesn't work in JS
|
||||
wire [8:0] paddle_rel_x = ((hpos-paddle_pos) & 9'h1ff);
|
||||
|
||||
// player paddle graphics signal
|
||||
wire paddle_gfx = (vcell == 28) && (paddle_rel_x < PADDLE_WIDTH);
|
||||
|
||||
wire [8:0] ball_rel_x = (hpos-ball_x);
|
||||
wire [8:0] ball_rel_y = (vpos-ball_y);
|
||||
|
||||
// difference between ball position and video beam
|
||||
wire [8:0] ball_rel_x = (hpos - ball_x);
|
||||
wire [8:0] ball_rel_y = (vpos - ball_y);
|
||||
|
||||
// ball graphics signal
|
||||
wire ball_gfx = ball_rel_x < BALL_SIZE
|
||||
&& ball_rel_y < BALL_SIZE;
|
||||
|
||||
reg main_gfx;
|
||||
reg brick_present;
|
||||
reg [6:0] brick_index;
|
||||
reg main_gfx; // main graphics signal (bricks and borders)
|
||||
reg brick_present; // 1 when we are drawing a brick
|
||||
reg [6:0] brick_index;// index into array of current brick
|
||||
// brick graphics signal
|
||||
wire brick_gfx = lr_border || (brick_present && vpos[2:0] != 0 && hpos[3:1] != 4);
|
||||
|
||||
// scan bricks: compute brick_index and brick_present flag
|
||||
@ -92,14 +94,11 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
if (hpos[3:0] == 8) begin
|
||||
// compute brick index
|
||||
brick_index <= {vpos[5:3], hpos[7:4]};
|
||||
//main_gfx <= 0; // 2 pixel horiz spacing between bricks
|
||||
end
|
||||
// every 17th pixel
|
||||
else if (hpos[3:0] == 9) begin
|
||||
// load brick bit from array
|
||||
brick_present <= brick_array[brick_index];
|
||||
end else begin
|
||||
//main_gfx <= brick_present && vpos[2:0] != 0; // 1 pixel vert. spacing
|
||||
end
|
||||
end else begin
|
||||
brick_present <= 0;
|
||||
@ -111,6 +110,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
if (!hpaddle)
|
||||
paddle_pos <= vpos;
|
||||
|
||||
// 1 when ball signal intersects main (brick + border) signal
|
||||
wire ball_pixel_collide = main_gfx & ball_gfx;
|
||||
|
||||
/* verilator lint_off MULTIDRIVEN */
|
||||
@ -141,6 +141,7 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
incscore <= 0; // reset incscore
|
||||
end
|
||||
|
||||
// computes position of ball in relation to center of paddle
|
||||
wire signed [8:0] ball_paddle_dx = ball_x - paddle_pos + 8;
|
||||
|
||||
// ball bounce: determine new velocity/direction
|
||||
@ -189,9 +190,11 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
always @(negedge vsync or posedge reset)
|
||||
begin
|
||||
if (reset) begin
|
||||
// reset ball position to top center
|
||||
ball_x <= 128;
|
||||
ball_y <= 180;
|
||||
end else begin
|
||||
// move ball horizontal and vertical position
|
||||
if (ball_dir_x == BALL_DIR_RIGHT)
|
||||
ball_x <= ball_x + (ball_speed_x?1:0) + 1;
|
||||
else
|
||||
@ -223,8 +226,8 @@ module ball_paddle_top(clk, reset, hpaddle, hsync, vsync, rgb);
|
||||
endcase
|
||||
end
|
||||
|
||||
// combine signals to RGB output
|
||||
wire grid_gfx = (((hpos&7)==0) || ((vpos&7)==0));
|
||||
|
||||
wire r = display_on && (ball_gfx | paddle_gfx);
|
||||
wire g = display_on && (main_gfx | ball_gfx);
|
||||
wire b = display_on && (grid_gfx | ball_gfx | brick_present);
|
||||
|
@ -9,7 +9,6 @@ module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
||||
wire display_on;
|
||||
wire [8:0] hpos;
|
||||
wire [8:0] vpos;
|
||||
reg ball_reset;
|
||||
|
||||
// 9-bit ball timers
|
||||
reg [8:0] ball_htimer;
|
||||
@ -26,7 +25,11 @@ module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
||||
// 5-bit constants to load into counters
|
||||
localparam ball_horiz_prefix = 5'b01100; // 192
|
||||
localparam ball_vert_prefix = 5'b01111; // 240
|
||||
|
||||
// reset ball; will be unset when video beam reaches center position
|
||||
reg ball_reset;
|
||||
|
||||
// video sync generator
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
@ -64,10 +67,10 @@ module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
||||
if (reset)
|
||||
ball_reset <= 1;
|
||||
else if (hpos == 128 && vpos == 128)
|
||||
ball_reset <= 0;
|
||||
ball_reset <= 0; // un-reset when beam reaches center position
|
||||
end
|
||||
|
||||
// collide with vertical and horizontal boundaries
|
||||
// collide with vertical and horizontal boundaries?
|
||||
wire ball_vert_collide = ball_vgfx && vpos >= 240;
|
||||
wire ball_horiz_collide = ball_hgfx && hpos >= 256 && vpos == 255;
|
||||
|
||||
@ -75,7 +78,7 @@ module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
||||
always @(posedge ball_vert_collide or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
ball_vert_move <= 4'd9;
|
||||
ball_vert_move <= 4'd9; // initial vertical velocity
|
||||
else
|
||||
ball_vert_move <= (4'd9 ^ 4'd11) ^ ball_vert_move; // change dir.
|
||||
end
|
||||
@ -84,13 +87,13 @@ module ball_slip_counter_top(clk, reset, hsync, vsync, rgb);
|
||||
always @(posedge ball_horiz_collide or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
ball_horiz_move <= 4'd10;
|
||||
ball_horiz_move <= 4'd10; // initial horizontal velocity
|
||||
else
|
||||
ball_horiz_move <= (4'd10 ^ 4'd12) ^ ball_horiz_move; // change dir.
|
||||
end
|
||||
|
||||
// compute ball display
|
||||
wire ball_hgfx = ball_htimer >= 508;
|
||||
wire ball_hgfx = ball_htimer >= 508; // 512-508 = 4 pixel ball
|
||||
wire ball_vgfx = ball_vtimer >= 508;
|
||||
wire ball_gfx = ball_hgfx && ball_vgfx;
|
||||
|
||||
|
@ -3,12 +3,14 @@
|
||||
|
||||
`include "hvsync_generator.v"
|
||||
|
||||
// module for 10-digit bitmap ROM
|
||||
module digits10_case(digit, yofs, bits);
|
||||
|
||||
input [3:0] digit;
|
||||
input [2:0] yofs;
|
||||
output reg [4:0] bits;
|
||||
input [3:0] digit; // digit 0-9
|
||||
input [2:0] yofs; // vertical offset (0-4)
|
||||
output reg [4:0] bits; // output (5 bits)
|
||||
|
||||
// combine {digit,yofs} into single ROM address
|
||||
wire [6:0] caseexpr = {digit,yofs};
|
||||
|
||||
always @(*)
|
||||
@ -79,13 +81,13 @@ endmodule
|
||||
|
||||
module digits10_array(digit, yofs, bits);
|
||||
|
||||
input [3:0] digit;
|
||||
input [2:0] yofs;
|
||||
output [4:0] bits;
|
||||
input [3:0] digit; // digit 0-9
|
||||
input [2:0] yofs; // vertical offset (0-4)
|
||||
output [4:0] bits; // output (5 bits)
|
||||
|
||||
reg [4:0] bitarray[0:15][0:4];
|
||||
reg [4:0] bitarray[0:15][0:4]; // ROM array
|
||||
|
||||
assign bits = bitarray[digit][yofs];
|
||||
assign bits = bitarray[digit][yofs]; // assign module output
|
||||
|
||||
integer i,j;
|
||||
|
||||
@ -157,6 +159,7 @@ module digits10_array(digit, yofs, bits);
|
||||
end
|
||||
endmodule
|
||||
|
||||
// test module
|
||||
module test_numbers_top(clk, reset, hsync, vsync, rgb);
|
||||
|
||||
input clk, reset;
|
||||
|
@ -10,18 +10,18 @@ module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||
output reg [8:0] hpos;
|
||||
output reg [8:0] vpos;
|
||||
|
||||
// constant declarations for TV-simulator sync parameters
|
||||
// horizontal
|
||||
// declarations for TV-simulator sync parameters
|
||||
// horizontal constants
|
||||
parameter H_DISPLAY = 256; // horizontal display width
|
||||
parameter H_BACK = 23; // horizontal left border (back porch)
|
||||
parameter H_FRONT = 7; // horizontal right border (front porch)
|
||||
parameter H_SYNC = 23; // horizontal sync width
|
||||
// vertical
|
||||
// vertical constants
|
||||
parameter V_DISPLAY = 240; // vertical display height
|
||||
parameter V_TOP = 5; // vertical top border
|
||||
parameter V_BOTTOM = 14; // vertical bottom border
|
||||
parameter V_SYNC = 3; // vertical sync # lines
|
||||
// derived
|
||||
// derived constants
|
||||
parameter H_SYNC_START = H_DISPLAY + H_FRONT;
|
||||
parameter H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1;
|
||||
parameter H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1;
|
||||
@ -29,8 +29,8 @@ module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||
parameter V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1;
|
||||
parameter V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1;
|
||||
|
||||
wire hmaxxed = (hpos == H_MAX) || reset;
|
||||
wire vmaxxed = (vpos == V_MAX) || reset;
|
||||
wire hmaxxed = (hpos == H_MAX) || reset; // set when hpos is maximum
|
||||
wire vmaxxed = (vpos == V_MAX) || reset; // set when vpos is maximum
|
||||
|
||||
// horizontal position counter
|
||||
always @(posedge clk)
|
||||
@ -53,6 +53,7 @@ module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||
vpos <= vpos + 1;
|
||||
end
|
||||
|
||||
// display_on is set when beam is in "safe" visible frame
|
||||
assign display_on = (hpos<H_DISPLAY) && (vpos<V_DISPLAY);
|
||||
|
||||
endmodule
|
||||
|
@ -1,15 +1,15 @@
|
||||
`ifndef LFSR_V
|
||||
`define LFSR_V
|
||||
|
||||
module LFSR(clk,reset,enable,lfsr);
|
||||
module LFSR(clk, reset, enable, lfsr);
|
||||
|
||||
parameter TAPS = 8'b11101;
|
||||
parameter INVERT = 0;
|
||||
localparam NBITS = $size(TAPS);
|
||||
parameter TAPS = 8'b11101; // bitmask for taps
|
||||
parameter INVERT = 0; // invert feedback bit?
|
||||
localparam NBITS = $size(TAPS); // bit width (derived from TAPS)
|
||||
|
||||
input clk, reset;
|
||||
input enable;
|
||||
output reg [NBITS-1:0] lfsr;
|
||||
input enable; // only perform shift when enable=1
|
||||
output reg [NBITS-1:0] lfsr; // shift register
|
||||
|
||||
wire feedback = lfsr[NBITS-1] ^ INVERT;
|
||||
|
||||
|
@ -10,9 +10,11 @@ module paddles_top(clk, reset, hsync, vsync, hpaddle, vpaddle, rgb);
|
||||
wire [8:0] hpos;
|
||||
wire [8:0] vpos;
|
||||
|
||||
// player position (only set at VSYNC)
|
||||
reg [7:0] player_x;
|
||||
reg [7:0] player_y;
|
||||
|
||||
// paddle position (set continuously during frame)
|
||||
reg [7:0] paddle_x;
|
||||
reg [7:0] paddle_y;
|
||||
|
||||
|
@ -12,17 +12,22 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
wire [8:0] hpos;
|
||||
wire [8:0] vpos;
|
||||
|
||||
// player car position (set at VSYNC)
|
||||
reg [7:0] player_x;
|
||||
reg [7:0] player_y;
|
||||
// paddle position (set continuously during frame)
|
||||
reg [7:0] paddle_x;
|
||||
reg [7:0] paddle_y;
|
||||
// enemy car position
|
||||
reg [7:0] enemy_x = 128;
|
||||
reg [7:0] enemy_y = 128;
|
||||
reg enemy_dir = 0;
|
||||
// enemy car direction, 1=right, 0=left
|
||||
reg enemy_dir = 0;
|
||||
|
||||
reg [15:0] track_pos = 0;
|
||||
reg [7:0] speed = 31;
|
||||
reg [15:0] track_pos = 0; // player position along track (16 bits)
|
||||
reg [7:0] speed = 31; // player velocity along track (8 bits)
|
||||
|
||||
// video sync generator
|
||||
hvsync_generator hvsync_gen(
|
||||
.clk(clk),
|
||||
.reset(0),
|
||||
@ -33,6 +38,14 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
.vpos(vpos)
|
||||
);
|
||||
|
||||
// set paddle registers
|
||||
always @(posedge hsync)
|
||||
begin
|
||||
if (!hpaddle) paddle_x <= vpos[7:0];
|
||||
if (!vpaddle) paddle_y <= vpos[7:0];
|
||||
end
|
||||
|
||||
// wire up car sprite ROM
|
||||
wire [3:0] car_sprite_yofs;
|
||||
wire [7:0] car_sprite_bits;
|
||||
|
||||
@ -40,16 +53,19 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
.yofs(car_sprite_yofs),
|
||||
.bits(car_sprite_bits));
|
||||
|
||||
// signals for player sprite generator
|
||||
wire player_vstart = {1'd0,player_y} == vpos;
|
||||
wire player_hstart = {1'd0,player_x} == hpos;
|
||||
wire player_gfx;
|
||||
wire player_is_drawing;
|
||||
|
||||
// signals for enemy sprite generator
|
||||
wire enemy_vstart = {1'd0,enemy_y} == vpos;
|
||||
wire enemy_hstart = {1'd0,enemy_x} == hpos;
|
||||
wire enemy_gfx;
|
||||
wire enemy_is_drawing;
|
||||
|
||||
// player sprite generator
|
||||
sprite_renderer player_renderer(
|
||||
.clk(clk),
|
||||
.vstart(player_vstart),
|
||||
@ -60,6 +76,7 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
.gfx(player_gfx),
|
||||
.in_progress(player_is_drawing));
|
||||
|
||||
// enemy sprite generator
|
||||
sprite_renderer enemy_renderer(
|
||||
.clk(clk),
|
||||
.vstart(enemy_vstart),
|
||||
@ -69,17 +86,14 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
.rom_bits(car_sprite_bits),
|
||||
.gfx(enemy_gfx),
|
||||
.in_progress(player_is_drawing));
|
||||
|
||||
always @(posedge hsync)
|
||||
begin
|
||||
if (!hpaddle) paddle_x <= vpos[7:0];
|
||||
if (!vpaddle) paddle_y <= vpos[7:0];
|
||||
end
|
||||
|
||||
|
||||
// signals for enemy bouncing off left/right borders
|
||||
wire enemy_hit_left = (enemy_x == 64);
|
||||
wire enemy_hit_right = (enemy_x == 192);
|
||||
wire enemy_hit_edge = enemy_hit_left || enemy_hit_right;
|
||||
|
||||
// update player, enemy, track counters
|
||||
// runs once per frame
|
||||
always @(posedge vsync)
|
||||
begin
|
||||
player_x <= paddle_x;
|
||||
@ -101,6 +115,7 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
speed <= speed - 1;
|
||||
end
|
||||
|
||||
// set to 1 when player collides with enemy or track
|
||||
reg frame_collision;
|
||||
|
||||
always @(posedge clk)
|
||||
@ -109,10 +124,12 @@ module racing_game_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
||||
else if (vsync)
|
||||
frame_collision <= 0;
|
||||
|
||||
// track graphics signals
|
||||
wire track_offside = (hpos[7:5]==0) || (hpos[7:5]==7);
|
||||
wire track_shoulder = (hpos[7:3]==3) || (hpos[7:3]==28);
|
||||
wire track_gfx = (vpos[5:1]!=track_pos[5:1]) && track_offside;
|
||||
|
||||
// combine signals for RGB output
|
||||
wire r = display_on && (player_gfx || enemy_gfx || track_shoulder);
|
||||
wire g = display_on && (player_gfx || track_gfx);
|
||||
wire b = display_on && (enemy_gfx || track_shoulder);
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
`include "hvsync_generator.v"
|
||||
`include "ram.v"
|
||||
|
||||
@ -53,14 +54,12 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb,
|
||||
output [15:0] rom_addr; // sprite ROM address
|
||||
input [15:0] rom_data; // sprite ROM data
|
||||
|
||||
// copy of sprite data from RAM
|
||||
// copy of sprite data from RAM (N entries)
|
||||
reg [7:0] sprite_xpos[0:N-1];
|
||||
reg [7:0] sprite_ypos[0:N-1];
|
||||
reg [7:0] sprite_attr[0:N-1];
|
||||
|
||||
// mapping of N sprites to M line slots
|
||||
reg [NB-1:0] sprite_to_line[0:M-1];
|
||||
|
||||
// M sprite slots
|
||||
reg [7:0] line_xpos[0:M-1]; // X pos for M slots
|
||||
reg [7:0] line_yofs[0:M-1]; // Y pos for M slots
|
||||
reg [7:0] line_attr[0:M-1]; // attr for M slots
|
||||
@ -74,6 +73,7 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb,
|
||||
reg [8:0] write_ofs;
|
||||
reg [15:0] out_bitmap;
|
||||
reg [7:0] out_attr;
|
||||
reg romload;
|
||||
|
||||
// which sprite are we currently reading?
|
||||
wire [NB-1:0] load_index = hpos[NB:1];
|
||||
@ -122,43 +122,49 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb,
|
||||
endcase
|
||||
end
|
||||
end else if (hpos < N*2) begin
|
||||
// setup vars for next phase
|
||||
k <= 0;
|
||||
romload <= 0;
|
||||
// select the sprites that will appear in this scanline
|
||||
case (hpos[0])
|
||||
// compute Y offset of sprite relative to scanline
|
||||
0: z <= 8'(vpos - sprite_ypos[i]);
|
||||
// sprite is active if Y offset is 0..15
|
||||
1: begin
|
||||
// sprite is active if Y offset is 0..15
|
||||
if (z < 16) begin
|
||||
line_xpos[j] <= sprite_xpos[i]; // save X pos
|
||||
line_yofs[j] <= z; // save Y offset
|
||||
sprite_to_line[j] <= i; // save main array index
|
||||
line_attr[j] <= sprite_attr[i]; // save attr
|
||||
line_active[j] <= 1; // mark sprite active
|
||||
j <= j + 1; // inc counter
|
||||
end
|
||||
i <= i + 1; // inc main array counter
|
||||
end
|
||||
endcase
|
||||
end else if (hpos < N*2+M*24) begin
|
||||
end else if (hpos < N*2+M*18) begin
|
||||
// setup vars for next phase
|
||||
j <= 0;
|
||||
// divide hpos by 24 (8 setup + 16 render)
|
||||
if ((hpos[3:0] < 8) ^^ hpos[4]) begin
|
||||
// render sprites into write buffer
|
||||
case (hpos[3:0])
|
||||
// grab index into main sprite array
|
||||
0: i <= sprite_to_line[k];
|
||||
// load scanline buffer offset to write
|
||||
1: write_ofs <= {~vpos[0], sprite_xpos[i]};
|
||||
// set ROM address and fetch bitmap
|
||||
2: rom_addr <= {4'b0, sprite_attr[i][7:4], line_yofs[k]};
|
||||
// fetch 0 if sprite is inactive
|
||||
3: out_bitmap <= line_active[k] ? rom_data : 0;
|
||||
// load attribute for sprite
|
||||
4: out_attr <= sprite_attr[i];
|
||||
// disable sprite for next scanline
|
||||
6: line_active[k] <= 0;
|
||||
// go to next sprite in 2ndary buffer
|
||||
7: k <= k + 1;
|
||||
// if sprite shift register is empty, load new sprite
|
||||
if (out_bitmap == 0) begin
|
||||
case (romload)
|
||||
0: begin
|
||||
// set ROM address and fetch bitmap
|
||||
rom_addr <= {4'b0, line_attr[k][7:4], line_yofs[k]};
|
||||
end
|
||||
1: begin
|
||||
// load scanline buffer offset to write
|
||||
write_ofs <= {~vpos[0], line_xpos[k]};
|
||||
// fetch 0 if sprite is inactive
|
||||
out_bitmap <= line_active[k] ? rom_data : 0;
|
||||
// load attribute for sprite
|
||||
out_attr <= line_attr[k];
|
||||
// disable sprite for next scanline
|
||||
line_active[k] <= 0;
|
||||
// go to next sprite in 2ndary buffer
|
||||
k <= k + 1;
|
||||
end
|
||||
endcase
|
||||
romload <= !romload;
|
||||
end else begin
|
||||
// write color to scanline buffer if low bit == 1
|
||||
if (out_bitmap[0])
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
.include "hvsync_generator.v"
|
||||
.include "font_cp437_8x8.v"
|
||||
.include "ram.v"
|
||||
@ -140,11 +140,15 @@ MoveSprites:
|
||||
mov dx,@SpriteTable
|
||||
mov cx,#5
|
||||
MoveSLoop:
|
||||
mov ax,[dx] ; x/y pos
|
||||
mov bx,[dx+1] ; attributes/dir
|
||||
and bx,#3 ; bx = direction (0-3)
|
||||
mov ax,[dx] ; x/y pos
|
||||
mov bx,[dx+1] ; direction
|
||||
rol bx
|
||||
rol bx
|
||||
rol bx
|
||||
rol bx
|
||||
and bx,#3 ; bx = direction (0-3)
|
||||
add bx,@DirectionXY
|
||||
add ax,[bx] ; lookup & add to x/y
|
||||
add ax,[bx] ; lookup & add to x/y
|
||||
; make sure we don't collide with wall
|
||||
mov ex,ax
|
||||
add ex,#$08
|
||||
@ -170,19 +174,18 @@ MoveSLoop:
|
||||
bz DoNotUpdatePos
|
||||
; update x/y position
|
||||
mov [dx],ax ; store x/y pos
|
||||
inc dx
|
||||
inc dx
|
||||
NextSLoop:
|
||||
add dx,#2
|
||||
dec cx
|
||||
bnz MoveSLoop
|
||||
rts
|
||||
; Choose a new direction
|
||||
DoNotUpdatePos:
|
||||
mov bx,[dx+1] ; attributes/dir
|
||||
inc bx
|
||||
inc dx
|
||||
add dx,#1
|
||||
mov bx,[dx] ; direction
|
||||
add bx,@$1000
|
||||
mov [dx],bx
|
||||
inc dx
|
||||
sub dx,#1
|
||||
jmp NextSLoop
|
||||
|
||||
HelloWorld:
|
||||
@ -190,6 +193,7 @@ HelloWorld:
|
||||
.data 0
|
||||
|
||||
SpriteInitData:
|
||||
.data $b373 $1233
|
||||
.data $8363 $3456
|
||||
.data $8373 $4567
|
||||
.data $8383 $5678
|
||||
|
@ -592,27 +592,28 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
this.loadROM = function(title, output) {
|
||||
var mod;
|
||||
if (output.code) {
|
||||
try {
|
||||
mod = new Function('base', output.code);
|
||||
} catch (e) {
|
||||
this.printErrorCodeContext(e, output.code);
|
||||
throw e;
|
||||
// is code identical?
|
||||
if (current_output && current_output.code == output.code) {
|
||||
} else {
|
||||
try {
|
||||
mod = new Function('base', output.code);
|
||||
} catch (e) {
|
||||
this.printErrorCodeContext(e, output.code);
|
||||
throw e;
|
||||
}
|
||||
// compile Verilog code
|
||||
var base = new VerilatorBase();
|
||||
gen = new mod(base);
|
||||
//$.extend(gen, base);
|
||||
gen.__proto__ = base;
|
||||
current_output = output;
|
||||
module_name = output.name ? output.name.substr(1) : "top";
|
||||
trace_ports = current_output.ports;
|
||||
trace_signals = current_output.ports.concat(current_output.signals);
|
||||
trace_index = 0;
|
||||
// power on module
|
||||
this.poweron();
|
||||
}
|
||||
// compile Verilog code
|
||||
var base = new VerilatorBase();
|
||||
gen = new mod(base);
|
||||
//$.extend(gen, base);
|
||||
gen.__proto__ = base;
|
||||
current_output = output;
|
||||
module_name = output.name ? output.name.substr(1) : "top";
|
||||
trace_ports = current_output.ports;
|
||||
trace_signals = current_output.ports.concat(current_output.signals);
|
||||
trace_index = 0;
|
||||
// power on module
|
||||
this.poweron();
|
||||
} else {
|
||||
// TODO: :^P
|
||||
output = {program_rom_variable: title, program_rom: output};
|
||||
}
|
||||
// replace program ROM, if using the assembler
|
||||
if (output.program_rom && output.program_rom_variable) {
|
||||
@ -624,6 +625,7 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
} else {
|
||||
alert("No program_rom variable found (" + output.program_rom_variable + ")");
|
||||
}
|
||||
this.reset();
|
||||
}
|
||||
// restart audio
|
||||
restartAudio();
|
||||
|
@ -60,7 +60,7 @@ export class CodeProject {
|
||||
var m;
|
||||
while (m = re.exec(text)) {
|
||||
files.push(m[2]);
|
||||
files.push('local/'+m[2]); // TODO?
|
||||
//files.push('local/'+m[2]); // TODO: shows up 2x in interface
|
||||
}
|
||||
} else {
|
||||
var re = /^\s*([;#]|[/][/][#])link\s+"(.+?)"/gm;
|
||||
|
@ -1120,6 +1120,8 @@ function compileJSASM(asmcode, platform, options, is_inline) {
|
||||
result.output.program_rom = asmout;
|
||||
// cpu_platform__DOT__program_rom
|
||||
result.output.program_rom_variable = jsasm_module_top + "__DOT__program_rom";
|
||||
result.listings = {};
|
||||
result.listings[options.path] = {lines:result.lines};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user