2 <title>Digital Logic Simulator
</title>
4 <b>Your browser does not support JavaScript or JavaScript is disabled.
</b>
7 /* DEFAULT COLOR SETTINGS */
8 var color_on
= "#fe0"; /* color of objects in high state */
9 var color_on_hlt
= "#f90";
11 var color_off
= "#bbb"; /* color of objects in low state */
12 var color_off_hlt
= "#ddd";
14 var gate_stroke_style
= "#11f";
15 var gate_stroke_width
= 1;
17 var con_stroke_style_low
= "#000";
18 var con_stroke_style_high
= "#f00";
20 var con_stroke_width
= 1;
22 /* GENERAL DATA STRUCTRURES */
23 var stage
= new Array(); /* status of stage - all details stored here */
24 var stage_rows
= 0; /* number of rows on stage */
25 var stage_cols
= 0; /* number of columns on stage */
26 var grid_status
= 1; /* boolean status of stage grid lines */
27 var grid_size
= 60; /* this is stored here for reference */
28 var canvas
; /* object id of canvas tag */
29 var ctx
; /* context of canvas */
30 var item_selected
= "gate_and"; /* only one type of object can be drawn at a time */
31 var connection_started
= false; /* connections require two clicks - source and dest */
32 var connection_coord
= new Array(); /* new connection x1,y1,x2,y2 */
33 var clock_speed
= 0; /* speed of clock in seconds (can be fractional) */
34 var clock_status
= 0; /* status of normal clock signal */
35 var clock_timer
= null; /* stores clock timer so it can be stopped */
37 var out
= new Array(); /* output bit value */
38 var input
= new Array(); /* intput bit value */
40 /* change speed of clock */
43 clock_speed
= document
.getElementById("clock_speed_select").value
;
46 /* start and stop clock */
49 if(clock_timer
!= null ){
50 clearInterval(clock_timer
);
52 document
.getElementById("clock").innerHTML
= "Clock Start";
54 clock_timer
= setInterval("clk_adv()", clock_speed
* 1000);
55 document
.getElementById("clock").innerHTML
= "Clock Stop";
59 /* advance clock one step */
63 if(clock_status
> 1) { clock_status
= 0; }
69 if(clock_status
) { return 0; } else { return 1; }
72 /* each square on grid has an associated block of data tied to it */
73 function grid(type
, value
)
75 this.type
= type
; /* type of entity @ location */
76 this.value
= value
; /* many entities have a value associated */
77 this.name
= ''; /* used for inputs and outputs */
80 /* flip bit of specified input and call redraw on screen */
81 function input_flip(v
)
83 if(v
== 'undefined') { alert("Cannot flip unknown value"); }
85 if(input
[v
].val
== 0) { input
[v
].val
= 1 } /* set data value */
86 /* loop through all grids on stage, flipping inputs */
87 for(x
=0; x
< stage_cols
; x
++) {
88 for(y
= 0; y
< stage_rows
; y
++) {
89 if(stage
[x
][y
].type
== "input") {
90 stage
[x
][y
].val
= input
[v
].val
;
97 /* flip bit of specified output and call redraw on screen */
98 function output_flip(v
)
100 if(v
== 'undefined') { alert("Cannot flip unknown value"); }
101 if(out
[v
].val
== 0) { out
[v
].val
= 1; } else { out
[v
].val
= 0; }
102 // redraw output on screen
103 draw_output_simple(v
);
106 /* reset all outputs to zero and redraw on screen */
107 function output_reset()
109 for(var i
= 0; i
< 9; i
++) {
111 // redraw outputs on screen
112 draw_output_simple(i
);
116 /* converts decimal degrees to radians */
117 function deg_to_rad(deg
)
119 return (Math
.PI
/180)*deg
;
122 /* create all output data structures and draw inital values on screen */
123 function init_stage()
127 /* create blank grid data structure */
128 for(x
= 0; x
< stage_cols
; x
++) {
129 stage
[x
] = new Array();
130 for(y
= 0; y
< stage_rows
; y
++) {
131 stage
[x
][y
] = new grid('', '');
136 stage
[0][0].type
= "clock";
137 stage
[0][1].type
= "clock_";
140 for(x
= 0; x
< 5; x
++) {
141 stage
[15][x
+3].type
= "output";
142 stage
[15][x
+3].value
= 0;
143 stage
[15][x
+3].name
= x
;
147 for(y
= "A", x
= 0; x
< 5; x
++, y
= String
.fromCharCode(y
.charCodeAt() + 1)) {
148 stage
[0][x
+3].type
= "input";
149 stage
[0][x
+3].value
= 0;
150 stage
[0][x
+3].name
= y
;
153 /* reset all command buttons */
154 item_selected
= "gate_and";
155 document
.getElementById("gate_and").disabled
= true;
156 document
.getElementById("gate_nand").disabled
= false;
157 document
.getElementById("gate_nor").disabled
= false;
158 document
.getElementById("gate_not").disabled
= false;
159 document
.getElementById("gate_or").disabled
= false;
160 document
.getElementById("gate_xor").disabled
= false;
161 document
.getElementById("delete").disabled
= false;
162 document
.getElementById("gate_connect").disabled
= false;
168 move through each grid in stage and draw contents.
169 this function can be used to refresh the screen at any time.
171 function draw_stage()
174 /* loop through all grids on stage, drawing contents */
175 for(x
=0; x
< stage_cols
; x
++) {
176 for(y
= 0; y
< stage_rows
; y
++) {
177 switch(stage
[x
][y
].type
) {
179 draw_clock(x
,y
,clock_status
);
182 draw_clock(x
,y
,clock_neg(clock_status
));
194 /* draw lines (wires) connecting gates */
201 /* intial setup of page - must be called on page load */
205 /* initalize canvas element for use */
206 canvas
= document
.getElementById("stage");
207 ctx
= canvas
.getContext("2d");
208 /* get width and height of window and set stage (canvas) with it. */
209 canvas
.height
= window
.innerHeight
-125;
210 canvas
.width
= window
.innerWidth
- 45;
211 if(grid_status
) {draw_grid(); }
217 function draw_clock(x
,y
,phase
)
219 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
220 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
221 if(phase
> 1 || phase
< 0) { alert("Clock phase not sent"); return ; }
222 x
= (x
*grid_size
) + (grid_size
/2); /* offset
from conrner
of grid */
223 y
= (y
*grid_size
) + (grid_size
/2);
225 ctx
.strokeStyle
= con_stroke_style_high
;
226 ctx
.fillStyle
= con_stroke_style_high
;
228 ctx
.strokeStyle
= con_stroke_style_low
;
229 ctx
.fillStyle
= con_stroke_style_low
;
234 ctx
.arc(x
,y
,15, deg_to_rad(360), deg_to_rad(0), false);
236 ctx
.font
= "10pt Arial";
237 ctx
.textAlign
= "center";
238 ctx
.textBaseline
= "middle";
239 ctx
.fillText("CLK", x
, y
);
240 /* draw line over text */
251 draw connection (wire) from one component to another.
252 connections are automatically drawn from one place to another.
253 grids have a certain number of evenly-spaced nodes where a line can be drawn.
254 connections can only be drawn through grids that are empty.
255 inputs can only connect to outputs.
257 function draw_connect(x1
, y1
, x2
, y2
)
259 if(x1
== x2
&& y1
== y2
) { return; } /* cannot connect same grid */
260 x1
= x1
* grid_size
; y1
= y1
* grid_size
;
261 x2
= x2
* grid_size
; y2
= y2
* grid_size
;
262 /* TODO: draw line color on basis of output (high or low) */
265 ctx
.strokeStyle
= con_stroke_style_low
;
266 ctx
.lineWidth
= con_stroke_width
;
275 start new connection from one entity to another.
277 function start_connect(e
)
279 connection_started
= true;
280 var coords
= cnvs_get_grid(e
);
281 connection_coord
[0] = coords
[0];
282 connection_coord
[1] = coords
[1];
285 function stop_connect(e
)
287 connection_started
= false;
288 var coords
= cnvs_get_grid(e
);
289 connection_coord
[2] = coords
[0];
290 connection_coord
[3] = coords
[1];
294 // draw line on canvas
295 draw_connect(connection_coord
[0], connection_coord
[1], connection_coord
[2], connection_coord
[3]);
298 /* inputs have are represented by a character with a parameter v */
299 function draw_input(x
,y
)
301 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
302 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
303 var s
= stage
[x
][y
].value
;
304 var name
= stage
[x
][y
].name
;
305 x
= (x
*grid_size
) + (grid_size
/2); /* offset
from corner
of grid */
306 y
= (y
*grid_size
) + (grid_size
/2);
307 if(s
) { ctx
.strokeStyle
= color_on_hlt
} else { ctx
.strokeStyle
= color_off
; }
308 if(s
) { ctx
.fillStyle
= color_on
} else { ctx
.fillStyle
= color_off_hlt
; }
311 /* draw background circle */
313 ctx
.arc(x
,y
,15, deg_to_rad(360), deg_to_rad(0), false);
317 ctx
.arc(x
,y
,15, deg_to_rad(360), deg_to_rad(0), false);
320 if(s
) { ctx
.fillStyle
= color_on_hlt
} else { ctx
.fillStyle
= color_off
; }
321 /* draw character on top */
322 ctx
.font
= "15pt Arial";
323 ctx
.textAlign
= "center";
324 ctx
.textBaseline
= "middle";
325 ctx
.fillText(name
, x
, y
);
328 /* simple version with auto lookup to data structure */
329 function draw_input_simple(v
)
332 if(v
== 'undefined') { alert("Cannot modify unknown output"); }
333 // TODO: Make this work with lib function instead...
360 // TODO: cannot get position of input from this location - must search grid.
361 draw_input(input
[v
].xpos
, input
[v
].ypos
, x
, input
[v
].val
);
364 /* draw output button.
366 x = grid position on x axis.
367 y = grid position on y axis.
369 function draw_output(x
,y
)
371 var w
= 30; /* width of box */
372 var tx
= x
; var ty
= y
;
373 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
374 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
375 var s
= stage
[x
][y
].value
;
376 var name
= stage
[x
][y
].name
;
377 tx
= x
* grid_size
+ (grid_size
/ 2);
378 ty
= y
* grid_size
+ (grid_size
/ 2);
380 x
= (x
* grid_size
) + (grid_size
/ 5); /* offset from corner of grid */
381 y
= (y
* grid_size
) + (grid_size
/ 5);
383 /* draw filled box around char */
384 if(s
) { ctx
.fillStyle
= color_on
} else { ctx
.fillStyle
= color_off_hlt
; }
395 /* draw outline box around char */
396 if(s
) { ctx
.strokeStyle
= color_on_hlt
} else { ctx
.strokeStyle
= color_off
; }
407 /* draw char inside box */
408 if(s
) { ctx
.fillStyle
= color_on_hlt
; } else { ctx
.fillStyle
= color_off
; }
409 ctx
.font
= "15pt Arial";
410 ctx
.textAlign
= "center";
411 ctx
.textBaseline
= "middle";
412 ctx
.fillText(name
, tx
, ty
);
415 /* simple version with auto lookup to data structure */
416 function draw_output_simple(v
)
418 if(v
== 'undefined') { alert("Cannot modify unknown output"); }
419 // TODO: cannot get position of input from this location - must search grid.
420 draw_output(out
[v
].xpos
, out
[v
].ypos
, v
, out
[v
].val
);
423 /* draw faint gridlines on stage - used as a guide for the user */
426 var x
, y
; /* current x and y position */
427 var offset
= 10; /* x and y maximum offset (far bottom or side of the window) */
428 ctx
.strokeStyle
= "#ccc";
430 /* draw vertical lines */
431 for(x
= grid_size
, y
= 0, offset
= window
.innerWidth
; x
< window
.innerWidth
; x
= x
+ grid_size
)
435 ctx
.lineTo(x
,y
+offset
);
439 /* draw horizontal lines */
440 for(x
= 0, y
= grid_size
, offset
= window
.innerWidth
; y
< window
.innerWidth
; y
= y
+ grid_size
)
444 ctx
.lineTo(x
+offset
,y
);
450 function draw_and_gate(x
,y
)
452 var h
= grid_size
* .5; /* height of square of gate */
453 var w
= grid_size
* .250; /* width of square area of gate */
454 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
455 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
456 ctx
.strokeStyle
= gate_stroke_style
;
457 ctx
.lineWidth
= gate_stroke_width
;
458 x
= (grid_size
*.25) + (grid_size
*x
); /* offset from conrner of grid */
459 y
= (grid_size
*.25) + (grid_size
*y
);
463 ctx
.arc( x
+w
, y
+(h
/2), (h/2), deg_to_rad(-90), deg_to_rad(90), false);
464 ctx
.lineTo(x
+w
, y
+h
);
470 function draw_nand_gate(x
,y
)
472 var h
= grid_size
* .5; /* height of square of gate */
473 var w
= grid_size
* .250; /* width of square area of gate */
474 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
475 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
476 ctx
.strokeStyle
= gate_stroke_style
;
477 ctx
.lineWidth
= gate_stroke_width
;
478 x
= (grid_size
*.25) + (grid_size
*x
); /* offset from conrner of grid */
479 y
= (grid_size
*.25) + (grid_size
*y
);
483 ctx
.arc( x
+w
, y
+(h
/2), (h/2), deg_to_rad(-90), deg_to_rad(90), false);
484 ctx
.lineTo(x
+w
, y
+h
);
490 ctx
.arc( x
+(w
*2)+(grid_size
*.07), y
+(h
/2), grid_size
*.08, deg_to_rad(0), deg_to_rad(360), false);
494 function draw_not_gate(x
,y
)
496 var h
= grid_size
* .5; /* height of square of gate */
497 var w
= grid_size
* .375; /* width of square area of gate */
498 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
499 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
500 ctx
.strokeStyle
= gate_stroke_style
;
501 ctx
.lineWidth
= gate_stroke_width
;
502 ctx
.lineJoin
= 'bevel';
503 x
= (grid_size
*.25) + (grid_size
*x
); /* offset from conrner of grid */
504 y
= (grid_size
*.25) + (grid_size
*y
);
509 ctx
.lineTo(x
+w
,y
+(h
/2));
516 ctx
.arc( x
+w
+6, y
+(h
/2),grid_size
*.08, deg_to_rad(0), deg_to_rad(360), false);
520 function draw_or_gate(x
,y
)
522 var h
= grid_size
* .5; /* height of square of gate */
523 var w
= grid_size
* .20; /* width of square area of gate */
524 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
525 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
526 ctx
.strokeStyle
= gate_stroke_style
;
527 ctx
.lineWidth
= gate_stroke_width
;
528 ctx
.lineJoin
= 'bevel';
529 x
= (grid_size
*.25) + (grid_size
*x
); /* offset from conrner of grid */
530 y
= (grid_size
*.25) + (grid_size
*y
);
531 /* back curve - inputs */
533 ctx
.arc(x
-(2*w
), y
+(h
/2), h
, deg_to_rad(-30), deg_to_rad(30), false);
542 ctx
.arc(x
+w
, y
+h
, h
, deg_to_rad(-90), deg_to_rad(-30), false);
551 ctx
.arc(x
+w
, y
, h
, deg_to_rad(30), deg_to_rad(90), false);
555 function draw_nor_gate(x
,y
)
557 var h
= grid_size
* .5; /* height of square of gate */
558 var w
= grid_size
* .10; /* width of square area of gate */
559 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
560 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
561 ctx
.strokeStyle
= gate_stroke_style
;
562 ctx
.lineWidth
= gate_stroke_width
;
563 ctx
.lineJoin
= 'bevel';
564 x
= (grid_size
*.25) + (grid_size
*x
); /* offset from conrner of grid */
565 y
= (grid_size
*.25) + (grid_size
*y
);
566 /* back curve - inputs */
568 ctx
.arc(x
-(4*w
), y
+(h
/2), h
, deg_to_rad(-30), deg_to_rad(30), false);
577 ctx
.arc(x
+w
, y
+h
, h
, deg_to_rad(-90), deg_to_rad(-30), false);
586 ctx
.arc(x
+w
, y
, h
, deg_to_rad(30), deg_to_rad(90), false);
590 ctx
.arc(x
+(w
*3)+(grid_size
*.30), y
+(h
/2),grid_size
*.08, deg_to_rad(0), deg_to_rad(360), false);
594 function draw_xor_gate(x
,y
)
596 var h
= grid_size
* .5; /* height of square of gate */
597 var w
= grid_size
* .10; /* width of square area of gate */
598 if(x
== 'undefined' || y
== 'undefined') { alert("Coordinates Not Sent to Function"); return; }
599 if(x
< 0 || y
< 0) { alert("Coordinates Cannot Be Negative"); return ; }
600 ctx
.strokeStyle
= gate_stroke_style
;
601 ctx
.lineWidth
= gate_stroke_width
;
602 ctx
.lineJoin
= 'bevel';
603 x
= (grid_size
*.25) + (grid_size
*x
); /* offset from conrner of grid */
604 y
= (grid_size
*.25) + (grid_size
*y
);
605 /* back curve - inputs */
607 ctx
.arc(x
-(2*w
)-(grid_size
*.20), y
+(h
/2), h
, deg_to_rad(-30), deg_to_rad(30), false);
609 /* extra back curve - inputs */
611 ctx
.arc(x
-(2*w
)-(grid_size
*.315), y
+(h
/2), h
, deg_to_rad(-30), deg_to_rad(30), false);
620 ctx
.arc(x
+w
, y
+h
, h
, deg_to_rad(-90), deg_to_rad(-30), false);
629 ctx
.arc(x
+w
, y
, h
, deg_to_rad(30), deg_to_rad(90), false);
633 /* user changes what type of gate will be drawn next */
634 function change_selection(sel
)
636 var button
= document
.getElementById(sel
);
637 if(!button
) { alert("Cannot Find Selected Button"); return; }
638 /* enable old button */
639 document
.getElementById(item_selected
).disabled
= false;
640 //alert("enabling " + item_selected);
641 /* disable new button */
642 button
.disabled
= true;
647 /* returns coordinates of canvas in pixels */
648 function cnvs_get_coordinates(e
)
650 var x_offset
= canvas
.offsetLeft
;
651 var y_offset
= canvas
.offsetTop
;
652 if(canvas
== 'undefined') { alert("Canvas parameter is undefined"); }
653 x_offset
= e
.clientX
- x_offset
;
654 y_offset
= e
.clientY
- y_offset
;
655 document
.getElementById("xycoordinates").innerHTML
="Coordinates: (" + x_offset
+ "," + y_offset
+ ")";
656 return [x_offset
,y_offset
];
659 /* returns coordinates of canvas in grids 0,0 is top left corner */
660 function cnvs_get_grid(e
)
662 var coords
= cnvs_get_coordinates(e
);
663 return [Math
.floor(coords
[0] / grid_size
), Math
.floor(coords
[1] / grid_size
)];
666 /* canvas has been clicked find out which grid and make correct change to square if needed. */
667 function cnvs_clicked(e
)
669 var coords
= cnvs_get_coordinates(e
);
670 var x_pos
= Math
.floor(coords
[0] / grid_size
);
671 var y_pos
= Math
.floor(coords
[1] / grid_size
);
672 // TODO: create case starement for each type of entity
673 // if delete command, remove contents of grid
674 if(item_selected
== "delete") {
675 // cannot allow inputs and outputs to be deleted
676 if(stage
[x_pos
][y_pos
].type
== "input" || stage
[x_pos
][y_pos
].type
== "output") { return; }
677 stage
[x_pos
][y_pos
].type
= "";
681 // if an input or output, flip value
682 if(stage
[x_pos
][y_pos
].type
== "input") {
683 input_flip(stage
[x_pos
][y_pos
].value
);
687 if(stage
[x_pos
][y_pos
].type
== "output") {
691 // if connection started, begin connection process
692 if(item_selected
== "gate_connect"){
693 if(connection_started
== false){
700 // ...otherwise perform whatever the current selected function is
701 if(stage
[x_pos
][y_pos
].type
!= "") { return; } // check for presence of an item
702 switch(item_selected
) {
704 stage
[x_pos
][y_pos
].type
= "and";
705 draw_and_gate(x_pos
,y_pos
);
708 stage
[x_pos
][y_pos
].type
= "nand";
709 draw_nand_gate(x_pos
,y_pos
);
712 stage
[x_pos
][y_pos
].type
= "nor";
713 draw_nor_gate(x_pos
,y_pos
);
716 stage
[x_pos
][y_pos
].type
= "not";
717 draw_not_gate(x_pos
,y_pos
);
720 stage
[x_pos
][y_pos
].type
= "or";
721 draw_or_gate(x_pos
,y_pos
);
724 stage
[x_pos
][y_pos
].type
= "xor";
725 draw_xor_gate(x_pos
,y_pos
);
733 ctx
.font
= "60pt Arial";
734 ctx
.textAlign
= "center";
735 ctx
.textBaseline
= "middle";
736 ctx
.fillText("Digital Logic Simulator", 600, 100);
738 // instructions to continue
739 ctx
.font
= "20pt Arial";
740 ctx
.textAlign
= "center";
741 ctx
.textBaseline
= "middle";
742 ctx
.fillText("Click on Grid to Continue", 600, 400);
745 ctx
.fillStyle
= "#000000";
747 ctx
.moveTo(31.8, 0.0);
748 ctx
.lineTo(38.5, 0.0);
749 ctx
.lineTo(38.5, 6.7);
750 ctx
.lineTo(44.7, 6.7);
751 ctx
.lineTo(44.7, 0.0);
752 ctx
.lineTo(51.5, 0.0);
753 ctx
.lineTo(51.5, 20.2);
754 ctx
.lineTo(44.7, 20.2);
755 ctx
.lineTo(44.7, 13.5);
756 ctx
.lineTo(38.5, 13.5);
757 ctx
.lineTo(38.5, 20.2);
758 ctx
.lineTo(31.8, 20.2);
759 ctx
.lineTo(31.8, 0.0);
765 ctx
.moveTo(60.3, 6.7);
766 ctx
.lineTo(54.4, 6.7);
767 ctx
.lineTo(54.4, 0.0);
768 ctx
.lineTo(73.1, 0.0);
769 ctx
.lineTo(73.1, 6.7);
770 ctx
.lineTo(67.1, 6.7);
771 ctx
.lineTo(67.1, 20.2);
772 ctx
.lineTo(60.4, 20.2);
773 ctx
.lineTo(60.4, 6.7);
779 ctx
.moveTo(76.0, 0.0);
780 ctx
.lineTo(83.1, 0.0);
781 ctx
.lineTo(87.4, 7.1);
782 ctx
.lineTo(91.7, 0.0);
783 ctx
.lineTo(98.8, 0.0);
784 ctx
.lineTo(98.8, 20.2);
785 ctx
.lineTo(92.1, 20.2);
786 ctx
.lineTo(92.1, 10.2);
787 ctx
.lineTo(87.4, 17.4);
788 ctx
.lineTo(82.6, 10.2);
789 ctx
.lineTo(82.6, 20.2);
790 ctx
.lineTo(76.0, 20.2);
791 ctx
.lineTo(76.0, 0.0);
797 ctx
.moveTo(102.2, 0.0);
798 ctx
.lineTo(108.9, 0.0);
799 ctx
.lineTo(108.9, 13.5);
800 ctx
.lineTo(118.4, 13.5);
801 ctx
.lineTo(118.4, 20.2);
802 ctx
.lineTo(102.2, 20.2);
803 ctx
.lineTo(102.2, 0.0);
808 ctx
.fillStyle
= "#E44D26";
810 ctx
.moveTo(31.5, 138.0);
811 ctx
.lineTo(21.9, 29.5);
812 ctx
.lineTo(128.1, 29.5);
813 ctx
.lineTo(118.5, 138.0);
814 ctx
.lineTo(74.9, 150.0);
819 ctx
.fillStyle
= "#F16529";
821 ctx
.moveTo(75.0, 140.7);
822 ctx
.lineTo(110.1, 131.0);
823 ctx
.lineTo(118.5, 38.3);
824 ctx
.lineTo(75.0, 38.3);
829 ctx
.fillStyle
= "#EBEBEB";
831 ctx
.moveTo(75.0, 78.6);
832 ctx
.lineTo(57.4, 78.6);
833 ctx
.lineTo(56.2, 65.0);
834 ctx
.lineTo(75.0, 65.0);
835 ctx
.lineTo(75.0, 51.7);
836 ctx
.lineTo(75.0, 51.7);
837 ctx
.lineTo(41.6, 51.7);
838 ctx
.lineTo(42.0, 55.2);
839 ctx
.lineTo(45.2, 91.9);
840 ctx
.lineTo(75.0, 91.9);
844 ctx
.moveTo(75.0, 113.1);
845 ctx
.lineTo(74.9, 113.1);
846 ctx
.lineTo(60.1, 109.2);
847 ctx
.lineTo(59.2, 98.6);
848 ctx
.lineTo(52.0, 98.6);
849 ctx
.lineTo(45.8, 98.6);
850 ctx
.lineTo(47.7, 119.4);
851 ctx
.lineTo(74.9, 127.0);
852 ctx
.lineTo(75.0, 127.0);
857 ctx
.fillStyle
= "#FFFFFF";
859 ctx
.moveTo(75.0, 78.6);
860 ctx
.lineTo(75.0, 91.9);
861 ctx
.lineTo(91.4, 91.9);
862 ctx
.lineTo(89.8, 109.2);
863 ctx
.lineTo(75.0, 113.1);
864 ctx
.lineTo(75.0, 127.0);
865 ctx
.lineTo(102.2, 119.4);
866 ctx
.lineTo(102.5, 117.2);
867 ctx
.lineTo(105.6, 82.1);
868 ctx
.lineTo(105.9, 78.6);
869 ctx
.lineTo(102.3, 78.6);
873 ctx
.moveTo(75.0, 51.7);
874 ctx
.lineTo(75.0, 59.9);
875 ctx
.lineTo(75.0, 64.9);
876 ctx
.lineTo(75.0, 65.0);
877 ctx
.lineTo(107.1, 65.0);
878 ctx
.lineTo(107.1, 65.0);
879 ctx
.lineTo(107.1, 65.0);
880 ctx
.lineTo(107.4, 62.0);
881 ctx
.lineTo(108.0, 55.2);
882 ctx
.lineTo(108.3, 51.7);
888 <style type=
"text/css">
891 border: solid
1px #000;
895 <body onLoad=
"init_form();">
897 <center><h2>Digital Logic Simulator
</h2></center>
899 <button type=
"button" id=
"gate_and" onClick='change_selection(
"gate_and");'
disabled=
"disabled">AND
</button>
901 <button type=
"button" id=
"gate_nand" onClick='change_selection(
"gate_nand");'
>NAND
</button>
903 <button type=
"button" id=
"gate_nor" onClick='change_selection(
"gate_nor");'
>NOR
</button>
905 <button type=
"button" id=
"gate_not" onClick='change_selection(
"gate_not");'
>NOT
</button>
907 <button type=
"button" id=
"gate_or" onClick='change_selection(
"gate_or");'
>OR
</button>
909 <button type=
"button" id=
"gate_xor" onClick='change_selection(
"gate_xor");'
>XOR
</button>
911 <button type=
"button" id=
"delete" onClick='change_selection(
"delete");'
>Delete
</button>
913 <button type=
"button" id=
"gate_connect" onClick='change_selection(
"gate_connect");'
>Connect
</button>
915 <button type=
"button" id=
"move" onClick='change_selection(
"move");'
>Move
</button>
917 <button type=
"button" id=
"pan" onClick='change_selection(
"pan");'
>Pan
</button>
919 <button type=
"button" id=
"zoom" onClick='change_selection(
"zoom");'
>Zoom
</button>
921 <button type=
"button" id=
"clock" onClick='clk_toggle();'
>Clock Start
</button>
923 <select id=
"clock_speed_select" onChange='clk_change();'
>
924 <option value=
"5">Slow
</option>
925 <option value=
"1">Medium
</option>
926 <option value=
".5">Fast
</option>
927 <option value=
"-1">Unlimited
</option>
931 <div id=xycoordinates
> </div>
933 <canvas id=
"stage" width=
"200" height=
"200" onMouseMove=
"cnvs_get_coordinates(event)" onClick=
"cnvs_clicked(event);">
934 Your browser does not support HTML5 Canvas.