1. Contest #2... Example Programs

Sample programs are wanted. Do you have one that does something pretty cool? Please post the program here and let us know what it does. Remember to include the program inside of {{{ }}} tags.

See message:113859 for contest details

Jeremy

new topic     » topic index » view message » categorize

2. Re: Contest #2... Example Programs

Here is a very simple program that just starts a counter at 1, and goes into a loop forever incrementing and printing the counter out.

201 
213 
223 
?0 
301 
012 
new topic     » goto parent     » topic index » view message » categorize

3. Re: Contest #2... Example Programs

Here is a more complex program that counts from 1 to 5

201 
240 
904 
241 
904 
242 
904 
243 
904 
244 
904 
245 
904 
219 
316 
?0 
301 
820 
012 
100 
new topic     » goto parent     » topic index » view message » categorize

4. Re: Contest #2... Example Programs

201 r0=1    *** count to 100 *** 
215 r1=5 
611 r1+=r1 (10) 
711 r1*=r1 (100) 
901 [r1]=r0 (1) 
236 r3=6  (address of next line) 
?0  ? r0 
990 [r0]=r9 (0) 
301 r0+=1 
821 r2=[r1] 
032 goto r3 if r2 
100 halt 
201 r0=1     *** print fibonacci sequence *** 
215 r1=5 
711 r1*=r1 (25) 
901 [r1]=r0 (1) 
240 r4=0 
251 r5=1 
?5  ? r5 
237 r3=8  (address of next line) 
564 r6=r4 
665 r6+=r5 
?6  ? r6 
545 r4=r5 
556 r5=r6 
990 [r0]=r9 (0) 
301 r0+=1 
821 r2=[r1] 
032 goto r3 if r2 
edit: Dec 11
866 r6=[r6] (-1)  *** primes up to 1000 ***  
278 r7=8 
475 r7*=5   (40) 
475 r7*=5   (200) 
475 r7*=5   (1000) 
776 r7*=r6  (-1000) 
202 r0=2    (2 is first prime) 
810 r1=[r0] (is prime when r1=0) 
295 r9=5 
494 r9*=4   (20) 
091 if r1 not_prime 
?0          (print prime) 
530 r3=r0   (init counter) 
540 r4=r0   (init index) 
341 r4+=1 
554 r5=r4   (label2:) 
657 r5+=r7  (subtract 1000) 
299 r9=9 
493 r9*=3   (27) 
095 if r5 label3 
301 r0+=1 
550 r5=r0 
657 r5+=r7  (subtract 1000) 
297 r9=7 
095 if r5 main_loop 
100 halt 
300 nop 
636 r3+=r6  (subtract 1) 
299 r9=9 
398 r9+=8   (17) 
492 r9*=2   (34) 
093 if r3 label4 
904 [r4]=r0 (write nonzero to ram) 
530 r3=r0   (reset counter) 
341 r4+=1 
295 r9=5 
493 r9*=3   (15) 
094 if r4 label2 

new topic     » goto parent     » topic index » view message » categorize

5. Re: Contest #2... Example Programs

fibonacii (25)

NOTE This requires the amended spec that ram address zero is initialized to -1.

295 - r9 = 5   (loop counter) 
799 - r9 *= r9 (25) 
210 - r0 = 0   (first) 
221 - r1 = 1   (second) 
561 - r6 = r1  (first) ---> Loop point <--- 
572 - r7 = r2  (second) 
667 - r6 += r7 (tmp = first + second) 
512 - r1 = r2  (first = second 
526 - r2 = r6  (second = tmp) 
280 - r8 = 0   (location of our -1) 
888 - r8 = -1  (set r8 from ram addr 0) 
698 - r9 += r8 (deincrement loop counter) 
234 - r3 = 4   (loop point) 
039 -          (goto r3 if r9 != 0) 
?1  -          (print first) 

Jeremy

new topic     » goto parent     » topic index » view message » categorize

6. Re: Contest #2... Example Programs

This program prints out "9 8 7 6 5 4 3 2 1 "

224 set R2,4    Set loop start location 
239 set R3,9    Set the first number to be output 
210 set R1,0    Load RAM[0] (-1) ... 
811 set R1,[R1] into R1 
??3 put R3      Output number 
631 add R3,R1   Subtract 1 from number 
023 jmp R2,R3   Loop back if number not zero 

Annotated by DerekParnell

new topic     » goto parent     » topic index » view message » categorize

7. Re: Contest #2... Example Programs

Bouncing 1s

201000000000	set reg 0 to 1000000000 
211		set reg 1 to 1 
2210		set reg 2 to 10 
259		set reg 5 to 9 - loop counter 
240		set reg 4 to 1 - RAM address 
 
loop 
560		set reg 6 to reg 0 
661		add reg 1 to reg 6 
??6 
		set RAM to reg 6 
241		set reg 4 to 1 
645		add reg 5 to reg 4 (offsets by 1, so don't use RAM 0) 
964		set ram[4] to reg 6 
275		set reg 7 to 6	-loop destination 
883		set reg 8 to [3] (which is RAM 0 or -1) 
658		add reg 8 to reg 5 
712		multiply reg 1 by reg 2 
075		jump to reg 7, unless reg 5 = 0 
 
		now have ram pattern set up, so count up and down 
		reg 8 subtraction unit 
		reg 0 direction indicator (up or down) 
		reg 5 loop counter 
		reg 4 ram address 
		reg 1 current number 
		reg 2 loop 2 address 
		reg 6, reg 7 delay loops 
 
259		set reg 5 to 9 
201		set reg 0 to 1 - going up 
241		set reg 4 to 1 - first ram address 
 
loop 2 
2232		set reg 2 to 32 (loop2) 
814		get ram in reg[4] 
??1		print it 
2699		set reg 6 delay 
loop delay 1 
279		set reg 7 delay 
loop delay 2 
678		decrement reg 7 
2340		set reg 3 to 40 
037		go reg 3 unless reg 7=0   loop delay 2 
668		decrement reg 6 
2338		set reg 3 to 38 
036		goto reg 3 unless reg 6=0 loop delay 1 
 
640		add direction indicator (reg 0) to ram address (reg 4) 
--?4 
658		decrement loop counter	(or add reg 8 to reg 5) 
025		goto loop 2, unless 0 
259		set reg 5 to 9 
708		flip direction counter 
022		always goto loop 2 

new topic     » goto parent     » topic index » view message » categorize

8. Re: Contest #2... Example Programs

My interpreter won't run this. A lot of this stuff requires advanced features that's out of spec (such as setting reg 2 to 10 or treating lines with no valid instructions in them as comments).

ChrisB said...

Bouncing 1s

201000000000	set reg 0 to 1000000000 
211		set reg 1 to 1 
2210		set reg 2 to 10 
259		set reg 5 to 9 - loop counter 
240		set reg 4 to 1 - RAM address 
 
loop 
560		set reg 6 to reg 0 
661		add reg 1 to reg 6 
??6 
		set RAM to reg 6 
241		set reg 4 to 1 
645		add reg 5 to reg 4 (offsets by 1, so don't use RAM 0) 
964		set ram[4] to reg 6 
275		set reg 7 to 6	-loop destination 
883		set reg 8 to [3] (which is RAM 0 or -1) 
658		add reg 8 to reg 5 
712		multiply reg 1 by reg 2 
075		jump to reg 7, unless reg 5 = 0 
 
		now have ram pattern set up, so count up and down 
		reg 8 subtraction unit 
		reg 0 direction indicator (up or down) 
		reg 5 loop counter 
		reg 4 ram address 
		reg 1 current number 
		reg 2 loop 2 address 
		reg 6, reg 7 delay loops 
 
259		set reg 5 to 9 
201		set reg 0 to 1 - going up 
241		set reg 4 to 1 - first ram address 
 
loop 2 
2232		set reg 2 to 32 (loop2) 
814		get ram in reg[4] 
??1		print it 
2699		set reg 6 delay 
loop delay 1 
279		set reg 7 delay 
loop delay 2 
678		decrement reg 7 
2340		set reg 3 to 40 
037		go reg 3 unless reg 7=0   loop delay 2 
668		decrement reg 6 
2338		set reg 3 to 38 
036		goto reg 3 unless reg 6=0 loop delay 1 
 
640		add direction indicator (reg 0) to ram address (reg 4) 
--?4 
658		decrement loop counter	(or add reg 8 to reg 5) 
025		goto loop 2, unless 0 
259		set reg 5 to 9 
708		flip direction counter 
022		always goto loop 2 

new topic     » goto parent     » topic index » view message » categorize

9. Re: Contest #2... Example Programs

jimcbrown said...

My interpreter won't run this. A lot of this stuff requires advanced features that's out of spec (such as setting reg 2 to 10 or treating lines with no valid instructions in them as comments).

I think the revelant portion of the spec is

"Anything after the 3 digit instruction is a comment"

I guess I should have made that a little more clear. I'm sorry Chris, my interpreter will not run it either. You have to do things such as:

225  ; set register 2 to 5 
325  ; add to register 2 the number 5 

Register 2 will then contain 10.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

10. Re: Contest #2... Example Programs

Phew! I was worried for a moment that I'd be disqualified for not having a sufficiently advanced magic - er, interpreter.

jeremy said...
jimcbrown said...

My interpreter won't run this. A lot of this stuff requires advanced features that's out of spec (such as setting reg 2 to 10 or treating lines with no valid instructions in them as comments).

I think the revelant portion of the spec is

"Anything after the 3 digit instruction is a comment"

I guess I should have made that a little more clear. I'm sorry Chris, my interpreter will not run it either. You have to do things such as:

225  ; set register 2 to 5 
325  ; add to register 2 the number 5 

Register 2 will then contain 10.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

11. Re: Contest #2... Example Programs

Then according to the spec, I win! smile

LOL

My interpreter runs all your programs, does this also mean mines better, more versatile, and more robust than yours too!

What are your errors, lets see if I can help you!

Chris (chuckling lots)

(Back to drawing board, to 'dumb' down my VM, and only allow 3 digits in the instruction - this is fun)

new topic     » goto parent     » topic index » view message » categorize

12. Re: Contest #2... Example Programs

This one's for Matt:

265 r6=5    (width)  *** game of life *** 
462 r6*=2   (10) 
275 r7=5    (height) 
472 r7*=2   (10) 
289 r8=9    (stack pointer) 
484 r8*=4   (36) 
381 r8+=1   (37) 
483 r8*=3   (111) 
483 r8*=3   (333) 
483 r8*=3   (999) 
211 r1=1 
855 r5=[r5]   (-1) 
209 r0=9     (glider) 
304 r0+=4   (13) 
910 [r0]=r1       1 
606 r0+=r6          1 
301 r0+=1       1 1 1    
910 [r0]=r1 
606 r0+=r6 
910 [r0]=r1 
605 r0+=r5 
910 [r0]=r1 
605 r0+=r5 
910 [r0]=r1 
456 r5*=6 
455 r5*=5   (how many iterations) 
506 r0=r6   (cell address)  <-- main_loop 
302 r0+=2 
230 r3=0    (row counter) 
833 r3=[r3] (-1) 
737 r3*=r7 
220 r2=0    (col counter)   <-- row_loop 
822 r2=[r2] (-1) 
726 r2*=r6  (-width) 
321 r2+=1 
810 r1=[r0] (cell state) 
301 r0+=1 
??1 
321 r2+=1 
297 r9=7 
495 r9*=5   (35) 
092 if r2 col_loop 
810 r1=[r0] (cell state) 
301 r0+=1 
?1 
331 r3+=1 
296 r9=6 
495 r9*=5   (30) 
391 r9+=1   (31) 
093 if r3 row_loop 
200 r0=0 
506 r0=r6 (cell address) 
302 r0+=2 
230 r3=0  (counter = -width*height) 
833 r3=[r3] (-1) 
736 r3*=r6 
737 r3*=r7 
220 r2=0  (counter of living neighbors)  <-- neighbor_loop 
842 r4=[r2] (-1) 
514 r1=r4 
716 r1*=r6 
614 r1+=r4 
610 r1+=r0 
891 r9=[r1] (load neighbor northwest) 
629 r2+=r9 
311 r1+=1 
891 r9=[r1] (load neighbor north) 
629 r2+=r9 
311 r1+=1 
891 r9=[r1] (load neighbor northeast) 
629 r2+=r9 
616 r1+=r6 
891 r9=[r1] (load neighbor east) 
629 r2+=r9 
616 r1+=r6 
891 r9=[r1] (load neighbor southeast) 
629 r2+=r9 
614 r1+=r4 
891 r9=[r1] (load neighbor south) 
629 r2+=r9 
614 r1+=r4 
891 r9=[r1] (load neighbor southwest) 
629 r2+=r9 
640 r4+=r0 
894 r9=[r4] (load neighbor west) 
629 r2+=r9 
300 nop ??2 
810 r1=[r0] (load cell) 
299 r9=9 
495 r9*=5   (45) 
493 r9*=3   (135) 
392 r9+=2   (137) 
091 if r1 cell_alive 
240 r4=0                <-- dead_cell 
844 r4=[r4] (-1) 
443 r4*=3   (-3) 
642 r4+=r2  (dead cells live when 3 neighbors) 
297 r9=7 
497 r9*=7   (49) 
394 r9+=4   (53) 
492 r9*=2   (106) 
094 if r4 next_cell 
240 r4=0                 <-- push_cell 
844 r4=[r4] (-1) 
684 r8+=r4 
908 [r8]=r0  (put cell on the stack to invert later) 
301 r0+=1                <-- next_cell 
331 r3+=1 
299 r9=9 
492 r9*=2   (18) 
391 r9+=1   (19) 
493 r9*=3   (57) 
093 if r3 neighbor_loop 
808 r0=[r8]              <-- invert_loop 
295 r9=5 
495 r9*=5   (25) 
495 r9*=5   (125) 
090 if r0 invert_cell 
?0 
351 r5+=1 
299 r9=9 
394 r9+=4   (13) 
492 r9*=2   (26) 
095 if r5 main_loop 
100 halt 
810 r1=[r0]             <-- invert_cell 
220 r2=0 
822 r2=[r2] (-1) 
712 r1*=r2 
311 r1+=1 
910 [r0]=r1 
381 r8+=1 
298 r9=8 
497 r9*=7   (56) 
492 r9*=2   (112) 
391 r9+=1   (113) 
099 if r9 invert_loop 
240 r4=0              <-- cell_alive 
844 r4=[r4] (-1) 
443 r4*=3   (-3) 
642 r4+=r2 
299 r9=9 
398 r9+=8   (17) 
493 r9*=3   (51) 
493 r9*=3   (153) 
094 if r4 cell_alive2  (if neighbors!=3) 
300 nop 
297 r9=7 
497 r9*=7   (49) 
394 r9+=4   (53) 
492 r9*=2   (106) 
099 if r9 next_cell 
300 nop 
341 r4+=1              <-- cell_alive2 
299 r9=9 
398 r9+=8   (17) 
493 r9*=3   (51) 
492 r9*=2   (102) 
094 if r4 push_cell    (if neighbors!=2) 
297 r9=7 
497 r9*=7   (49) 
394 r9+=4   (53) 
492 r9*=2   (106) 
099 if r9 next_cell 

new topic     » goto parent     » topic index » view message » categorize

13. Re: Contest #2... Example Programs

Quicksort: recursive function using a stack. The quicksort function prints the upper index, pivot index, and upper index at each invocation, and displays the partially sorted array after partitioning. The stack grows downward from the top of ram, and is used for return address and saving local registers. Function arguments and return values are passed in registers.

288 r8=8    (stack pointer)   *** quicksort *** 
485 r8*=5   (40) 
485 r8*=5   (200) 
485 r8*=5   (1000) 
877 r7=[r7] (-1, keep it constant throughout) 
211 r1=1    (load the initial array starting at ram[1]) 
209 r0=9 
304 r0+=4   (13) 
403 r0*=3   (39) 
402 r0*=2   (78) 
901 [r1]=r0 
311 r1+=1 
207 r0=7 
403 r0*=3   (21) 
302 r0+=2   (23) 
901 [r1]=r0 
311 r1+=1 
209 r0=9 
405 r0*=5   (45) 
402 r0*=2   (90) 
901 [r1]=r0 
311 r1+=1 
208 r0=8 
901 [r1]=r0 
311 r1+=1 
207 r0=7 
405 r0*=5   (35) 
901 [r1]=r0 
311 r1+=1 
209 r0=9 
304 r0+=4   (13) 
901 [r1]=r0 
311 r1+=1 
207 r0=7 
407 r0*=7   (49) 
901 [r1]=r0 
311 r1+=1 
209 r0=9 
409 r0*=9   (81) 
302 r0+=2   (83) 
901 [r1]=r0 
311 r1+=1 
209 r0=9 
406 r0*=6   (54) 
901 [r1]=r0 
311 r1+=1 
208 r0=8 
407 r0*=7   (56) 
305 r0+=5   (61) 
901 [r1]=r0 
561 r6=r1   (upper index, constant throughout) 
208 r0=8 
407 r0*=7   (56) 
305 r0+=5   (61) 
687 r8+=r7 
908 [r8]=r0 (push return address) 
299 r9=9 
494 r9*=4   (36) 
391 r9+=1   (37) 
492 r9*=2   (74) 
099 if r9 show_array 
209 r0=9 
408 r0*=8   (72) 
301 r0+=1   (73) 
687 r8+=r7 
908 [r8]=r0 (push return address) 
201 r0=1    (lower index) 
516 r1=r6   (upper index) 
296 r9=6 
495 r9*=5   (30) 
391 r9+=1   (31) 
493 r9*=3   (93) 
099 if r9 quicksort 
100 halt 
201 r0=1    (lower index)     <-- show_array 
517 r1=r7   (-1) 
716 r1*=r6  (-upper index) 
610 r1+=r0  (loop counter) 
890 r9=[r0]           <-- show_loop 
301 r0+=1 
??9         (print value) 
311 r1+=1 
299 r9=9 
394 r9+=4   (13) 
493 r9*=3   (39) 
492 r9*=2   (78) 
091 if r1 show_loop 
890 r9=[r0] 
?9          (print value) 
898 r9=[r8] (pop return address) 
381 r8+=1 
099 goto r9 (ret) 
300 nop 
687 r8+=r7  <-- quicksort (r0: lower index, r1: upper index, [r8]=return address) 
918 [r8]=r1 (push upper index) 
687 r8+=r7 
908 [r8]=r0 (push lower index) 
717 r1*=r7 
520 r2=r0 
621 r2+=r1 
299 r9=9 
392 r9+=2   (11) 
495 r9*=5   (55) 
492 r9*=2   (110) 
092 if r2 check_index 
300 nop 
382 r8+=2   (pop upper and lower index)   <-- quicksort_done 
898 r9=[r8] (pop return address) 
381 r8+=1 
099 goto r9 (ret) 
627 r2+=r7   <-- check_index 
298 r9=8 
495 r9*=5   (40) 
493 r9*=3   (120) 
092 if r2 calculate_pivot1 
297 r9=7 
497 r9*=7   (49) 
394 r9+=4   (53) 
492 r9*=2   (106) 
099 if r9 quicksort_done   (lower index > upper index) 
311 r1+=1   <-- calculate_pivot1 
520 r2=r0 
621 r2+=r1 
299 r9=9 
492 r9*=2   (18) 
391 r9+=1   (19) 
497 r9*=7   (133) 
092 if r2 calculate_pivot2 
299 r9=9 
495 r9*=5   (45) 
392 r9+=2   (47) 
493 r9*=3   (141) 
099 if r9 found_pivot 
301 r0+=1   <-- calculate_pivot2 
520 r2=r0 
621 r2+=r1 
298 r9=8 
495 r9*=5   (40) 
493 r9*=3   (120) 
092 if r2 calculate_pivot1 
300 nop 
520 r2=r0   (pivot index)   <-- found_pivot 
838 r3=[r8] (lower index) 
381 r8+=1 
848 r4=[r8] (upper index) 
687 r8+=r7 
??3         (print lower index) 
??2         (print pivot index) 
?4          (print upper index) 
802 r0=[r2] (pivot value) 
814 r1=[r4] (upper value) 
912 [r2]=r1 (swap them) 
904 [r4]=r0 
523 r2=r3   (store index) 
554 r5=r4 
757 r5*=r7 
653 r5+=r3  (loop counter) 
300 nop 
803 r0=[r3] (index value)   <-- quicksort_loop 
814 r1=[r4] (pivot value) 
298 r9=8 
497 r9*=7   (56) 
493 r9*=3   (168) 
395 r9+=5   (173) 
687 r8+=r7 
998 [r8]=r9 (push return address) 
298 r9=8 
495 r9*=5   (40) 
493 r9*=3   (120) 
391 r9+=1   (121) 
492 r9*=2   (242) 
099 if r9 compare 
300 nop 
299 r9=9 
494 r9*=4   (36) 
391 r9+=1   (37) 
495 r9*=5   (185) 
090 if r0 quicksort_loop_next 
803 r0=[r3] (index value) 
812 r1=[r2] (store value) 
913 [r3]=r1 (swap them) 
902 [r2]=r0 
321 r2+=1 
300 nop 
300 nop 
331 r3+=1   <-- quicksort_loop_next 
351 r5+=1 
299 r9=9 
498 r9*=8   (72) 
397 r9+=7   (79) 
492 r9*=2   (158) 
095 if r5 quicksort_loop 
804 r0=[r4] (pivot value) 
812 r1=[r2] (store value) 
914 [r4]=r1 (swap them) 
902 [r2]=r0 
298 r9=8 
495 r9*=5   (40) 
495 r9*=5   (200) 
399 r9+=9   (209) 
687 r8+=r7 
998 [r8]=r9 (push return address) 
299 r9=9 
494 r9*=4   (36) 
391 r9+=1   (37) 
492 r9*=2   (74) 
099 if r9 show_array 
300 nop 
300 nop 
808 r0=[r8] (lower index) 
687 r8+=r7 
928 [r8]=r2 (push pivot index) 
512 r1=r2 
617 r1+=r7  (pivot index - 1) 
299 r9=9 
495 r9*=5   (45) 
495 r9*=5   (225) 
687 r8+=r7 
998 [r8]=r9 (push return address) 
296 r9=6 
495 r9*=5   (30) 
391 r9+=1   (31) 
493 r9*=3   (93) 
099 if r9 quicksort  (recursively call quicksort) 
300 nop 
808 r0=[r8] (pop pivot index) 
381 r8+=1 
301 r0+=1   (pivot index + 1) 
381 r8+=1 
818 r1=[r8] (load upper index) 
687 r8+=r7 
297 r9=7 
497 r9*=7   (49) 
394 r9+=4   (53) 
492 r9*=2   (106) 
687 r8+=r7 
998 [r8]=r9 (push return address) 
296 r9=6 
495 r9*=5   (30) 
391 r9+=1   (31) 
493 r9*=3   (93) 
099 if r9 quicksort  (recursively call quicksort) 
707 r0*=r7  <-- compare (returns with r0=0 if r0<=r1, r0=1 otherwise) 
610 r1+=r0  (find the difference and make a copy. increment the first copy  
501 r0=r1    and decrement the second copy until one of them reaches zero.) 
300 nop 
311 r1+=1           <-- compare_1 
298 r9=8 
498 r9*=8   (64) 
494 r9*=4   (256) 
090 if r0 compare_2  (return 0 if r0 <= r1) 
898 r9=[r8] (pop return address) 
381 r8+=1    
099 goto r9 (ret) 
300 nop 
300 nop 
607 r0+=r7           <-- compare_2 
298 r9=8 
495 r9*=5   (40) 
391 r9+=1   (41) 
493 r9*=3   (123) 
492 r9*=2   (246) 
091 if r1 compare_1 
201 r0=1    (return 1 if r0 > r1) 
898 r9=[r8] (pop return address) 
381 r8+=1    
099 goto r9 (ret) 

new topic     » goto parent     » topic index » view message » categorize

14. Re: Contest #2... Example Programs

tried to run you game of life on my VM but it crash.

C:\euphoria-40\work\win32\temp>eui hc1 PeteE-life.hc 
-1 1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 1 -1 -1 -1 -1 -1 -1 -1 
1 1 1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
 
c:\euphoria-40\work\win32\temp\hc1.ex:102 
subscript value 0 is out of bounds, reading from a sequence of length 1000 
 
--> See ex.err 

here the code of my vm

ED... SNIP... VM code removed as contest submissions shouldn't be submitted yet. ... BY JEREMY

new topic     » goto parent     » topic index » view message » categorize

15. Re: Contest #2... Example Programs

coconut said...

tried to run you game of life on my VM but it crash.

C:\euphoria-40\work\win32\temp>eui hc1 PeteE-life.hc 
-1 1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 1 -1 -1 -1 -1 -1 -1 -1 
1 1 1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
 
c:\euphoria-40\work\win32\temp\hc1.ex:102 
subscript value 0 is out of bounds, reading from a sequence of length 1000 
 
--> See ex.err 

here the code of my vm

ED... SNIP... VM code removed as contest submissions shouldn't be submitted yet. ... BY JEREMY

I think the issue is that your RAM is not compliant with the spec.

RAM[0] = -1, RAM[1..999] = 0

If it's anything different, then it's not compliant and will (probably) fail the tests.

new topic     » goto parent     » topic index » view message » categorize

16. Re: Contest #2... Example Programs

Pete, It was my error, my vm was initializing all ram to -1. After reading the constest rule once again I realized it must me all zero's except for ram[1]=-1

I corrected the error an now game of life work.

new topic     » goto parent     » topic index » view message » categorize

17. Re: Contest #2... Example Programs

edit: never mind its already answered.

looks like you need to add 1 to the ram value returned

new topic     » goto parent     » topic index » view message » categorize

18. Re: Contest #2... Example Programs

Corrected bouncing 1s (or a triangle wave)

300 ; bouncing 1s ver 2 
300 ; using nops to allow for less 'advanced' interpreters 
300 ; set reg 0 to -1, allows countdowns, not ued for anything else 
200 
800 
300 ; reg 1 will contain the number 
300 ; reg 2 will contain 10 
225 ; set reg 2 to 5 
422 ; reg 2 * 2 = 10 
211 ; reg 1 = 1 
300 
300 ; set base ram address to 100, hold 100 in ram[1] 
251 ; set reg 5 to 1 
752 ; reg 5 = reg 5 * reg 2 
752 ; reg 5 = reg 5 * reg 2 ( = 100) 
951 ; set ram[1] to reg 5 (100) 
595 ; set reg 9 to reg 5 (100) - this will be the base address for the ram pattern 
300 ; using reg 9 as mem address reg 
300 
278 ; r7 = 8 
300   672 ; r7 += r2 (12) - exceeds size of an integer 
292 ; r9 = 2 
979 ; [r9] = r7 (RAM 2 = 12 for quick recall) 
300 
300 ; set r9 back to 100 
291 
899							 
300 ; set each of the ram memory cells 
919 ; [9] = r1 
?1 
712 ; r1 *= r2 
670 ; r7 += r0 (-1) 
300 ; set r8 to jmp address (27) 
289 ; r8 = 9 
483 ; r8 *= 3 (27) 
391 ; inc r9 
087 ; jmp r8 r7!=0 
300 
272 ; r5 = 2 
877 ; r7 = [5] (back to 12) 
371 ; r7 += 1 (finishes at 0, so need extra 1) 
291 ; r9 = 1 
899 ; r9 = [9] (back to 100) 
300 
300 ; calculate jmp address 
285 ; r8 = 5 
489 ; r8 *= 9 
384 ; r8 += 4 (jmp address = 49) 
670 ; r7 += r0 (12 -1) 
300 ; now add r1 to each of the cells, except the last one 
839 ; r3 = [9] 
631 ; r3 += r1 
939 ; [9] = r3 
391 ; inc r9 
670 ; dec r7 (r7 += r0) 
?3 
087 ; jmp r8 r7!=0 
300 
300 ; now start cycling up and down ram, and printing it out 
300 ; set r9 back to 100 
291 ; r9 = 1 
899 ; r9 = [9]							 
272 ; r7 = 2 
877 ; r7 = [7] (back to 12) 
670 ; r7 += 1 (finishes at 0, so need extra 1) 
241 ; r4 = 1 will be direction switch - first up 
300 
300 ; r5 and r6 will be delay counters 
300 ; will store in [5] and [6] 
259 ; r5 = 9 
459 ; r5 *= 9	<- delay 
285 ; r8 = 5 
958 ; [8] = r5 
269 ; r6 = 9 
461 ; r6 *= 1	<- delay 
286 ; r8 = 6 
968 ; [8] = r6 
300 
300 ; calculate jmp address 
285 ; r8 = 5 
482 ; r8 *= 2 
487 ; r8 *= 8 
384 ; r8 += 7	(87) 
300 
300 
300 
300 ; main loop 
839 ; r3 = [9] 
?3 ; ?r3 
300 ; temporariliy store main loop jmp in [9] 
259 ; r5 = 9 
985 ; [5] = r8 
255 ; r5 = 5 
855 ; r5 = [5] 
300 ; outer delay loop 
266 ; r6 = 6 
866 ; r6 = [6] 
300 ; inner delay loop 
285 ; r8 = 5 
482 ; r8 *= 2 
489 ; r8 *= 9 
387 ; r8 += 7	(97) 
660 ; r6 += r0 
086 ; jmp r8 r6!=0 
266 ; r6 = 6 
866 ; r6 = [6] 
285 ; r8 = 5 
482 ; r8 *= 2 
489 ; r8 *= 9 
384 ; r8 += 4	(94) 
650 ; r5 += r0 
085 ; jmp r8 r6!=0 
255 ; r5 = 5 
855 ; r5 = [5] 
300 
300 ; pull off temp main loop loc 
289 ; r8 = 9 
888 ; r8 = [8] 
694 ; r9 += r4 inc address 
670 ; r7 += r0 dec conter 
087 ; loop r8 if r7 
740 ; r4 *= r0 flip direction 
272 ; r7 = 2 
877 ; r7 = [7] (back to 12) 
670 ; r7 += r0 dec counter 
088 ; jmp r8 
 

Fixed newly found fundamental error!

new topic     » goto parent     » topic index » view message » categorize

19. Re: Contest #2... Example Programs

ChrisB said...

Corrected bouncing 1s (or a triangle wave)

Pretty neat. I was getting type check errors, so I changed lines 20-21:

278 ; r7 = 8 
300 ; 

Matt

new topic     » goto parent     » topic index » view message » categorize

20. Re: Contest #2... Example Programs

Hi

Thanks Matt, high praise indeed.

This may may mean my VM is not 'in spec', so could JC clarify this - do we need to type check integers so they comply with euphoria integers or are euphoria atoms acceptable?

Chris

Sorry, just re read - RAM should store a euphoria integer, looks like atoms are unacceptable.

new topic     » goto parent     » topic index » view message » categorize

21. Re: Contest #2... Example Programs

I've posted source code for calculating the GCD of 47250 and 39690 (other numbers are possible, of course). You'll have to assemble the code. Get it here (zip file) or check out the mercurial repo at http://scm.openeuphoria.org/hg/contest (branch: matt-assembler).

To assemble:

$ eui assem.ex euclid.cpa division.cpa stack.cpa less-than.cpa > gcd.cpu 

Then you can run the gcd.cpu file with your interpreter. It prints the two numbers and then their GCD. Assembled, it comes out to just under 600 instructions, and should run for 388,834 steps.

Matt

new topic     » goto parent     » topic index » view message » categorize

22. Re: Contest #2... Example Programs

I just looked at Derek And Matt assembler to compare it to the one I written last weekend. I do the label fixup very differently. each time my assembler hit a forward reference to a label it reserve a fixed number of code instructions. Derek and Matt assembler use addition of power of 2, mine use power of tens. I reserve a register to hold number 10 and multiply the targer register with that number. I grow the address by a serie of "addi Rt n" and "mult Rt Rm". It doesn't need a second pass to fix the labels. When a label is met in the code the assembler immediatly lookup the pending fix and resolve them. There is 2 limitations to my system: to space allocated is always the same so it is oversized for small address. Secondly It limit the program address space to 0 - 9999. I could increase it but it would means more space lost. The main advantage of my system is it simplicity. Here my assembler code

/* 
NAME: hcasm.ex 
DESC: assembler for contest #2 cpu 
AUTHOR: Jacques Deschênes 
NOTE: 
 assembler syntax: 
   INSTRUCTION::= [:LABEL] OPCODE | OPCODE DEST INT | OPCODE DEST SOURCE 
   OPCODE::=JNZ|HALT|SETI|ADDI|MULTI|CPY|ADD|MUL|LOAD|STOR|PRNL|PRSP 
   DEST::=R0|R1|R2|R3|R4|R5|R6|R7|R8|R9 
   SOURCE::=R0|R1|R2|R3|R4|R5|R6|R7|R8|R9 
   INT::=[0..9]     
   COMMENT::= ; any text 
       
 exemples: 
   ADDI  R0 9   ;add 9 to R0 
   STOR  R0 R2  ;store contain of R0 in ram pointed by R2 
   MULI  R2 8   ;multiply r2 by 8   
  
 symbols can be used for ram locations and goto's 
 a goto label begin with ':' and should be the first token on the line 
 to define a ram symbol or any constant use the keyword .sym 
 
 .sym  name value 
  
 mnemonic and keywords are not case sensitive all code is converted to upper case. 
*/ 
 
include std/sequence.e 
include std/text.e 
include std/get.e 
 
with trace 
 
object _ 
 
constant --OPCODE MNEMONICS 
MNEMONICS={ 
  "JNZ",  -- jump if not zero  
  "HALT",     -- halt execution 
  "SETI",     -- set register immediate 
  "ADDI",     -- add register immediate 
  "MULI",     -- multiply register immediate 
  "CPY",     -- copy register 
  "ADD",     -- add register to register 
  "MUL",     -- multiply register to register  
  "LOAD",    -- load register  
  "STOR",    -- store register  
  "PRNL",        -- print line. 
  "PRSP"        -- print with space 
 }  
 
constant -- number of arguments used by each mnemonic 
ARG_COUNT={2,0,2,2,2,2,2,2,2,2,1,1} 
 
enum SYM_NAME, SYM_VAL 
enum URES_LBL, URES_LOC 
enum LBL_NAME, LBL_LOC 
sequence symbols={{"MINUS1"},{0}}, labels={{},{}}, file="", asm={}, hc={}, unresolved={{},{}} 
 
type digit(integer i) 
  return (i>='0' and i<='9') 
end type 
 
procedure read_file() 
object line 
integer fh 
 
   fh=open(file,"r") 
   if fh=-1 then 
     printf(1,"unknown file %s\n",{file}) 
     abort(2) 
   end if 
   line=gets(fh) 
   while sequence(line) do 
      if line[$]='\n' then line=line[1..$-1] end if 
      if length(line) and line[$]='\r' then line=line[1..$-1] end if 
      asm=append(asm,line) 
      line=gets(fh) 
   end while 
   close(fh)         
end procedure 
 
integer asm_line=0 
 
enum ERR_NONE=0, ERR_UNKNOWN_SYMBOL, ERR_MISSING_ARG, ERR_BAD_ARG, ERR_UNKNOWN_LABEL,  
     ERR_LOC_RESOLV, ERR_ALREADY_DEFINED, ERR_UNKNOWN_KEYWORD 
      
constant ERR_MSG={ 
                  "unknown symbol", 
                  "missing argument", 
                  "bad argument", 
                  "unknown label", 
                  "error while resolving back location", 
                  "this symbol already exist", 
                  "unknown keyword" 
                 } 
 
procedure error(integer err_code) 
  printf(1,"assembler error code %d: %s, at line %d\n",{err_code,ERR_MSG[err_code],asm_line}) 
  puts(1,asm[asm_line]&'\n') 
  abort(1) 
end procedure 
 
/* 
  keywords procedures 
  keywords are asembler directives and does not generate code 
  all keywords begin with a '.' 
*/ 
 
constant KEYWORDS={ 
  ".SYM" 
  } 
   
-- add a symbol to symbols table 
-- tokens[1] is symbol name, tokens[2] is value 
procedure add_symbol(sequence tokens) 
sequence t1, t2 
    
   t1=tokens[1] 
   if find(t1,symbols[SYM_NAME]) then 
     error(ERR_ALREADY_DEFINED) 
   end if 
   t2=value(tokens[2]) 
   if t2[1]!=GET_SUCCESS then 
     error(ERR_BAD_ARG) 
   end if 
   symbols[SYM_NAME]=append(symbols[SYM_NAME],t1) 
   symbols[SYM_VAL]=append(symbols[SYM_VAL],t2[2])    
end procedure 
 
constant rid_keywords={ 
                        routine_id("add_symbol") 
                      } 
 
 
procedure add_unresolved(sequence lbl, integer loc) 
integer p 
--trace(1) 
   p=find(lbl,unresolved[URES_LBL])  
   if not p then 
     unresolved[URES_LBL]=append(unresolved[URES_LBL],lbl) 
     unresolved[URES_LOC]=append(unresolved[URES_LOC],{loc}) 
   else 
     unresolved[URES_LOC][p] &= loc 
   end if   
end procedure 
 
procedure resolve(sequence lbl, integer addr) 
sequence loc2resolv, saddr 
integer p, pc, completed 
--trace(1)     
    p = find(lbl,unresolved[URES_LBL]) 
    if not p then return end if 
    loc2resolv=unresolved[URES_LOC][p] 
    saddr=sprintf("%04d",addr) 
    for i = 1 to length(loc2resolv) do 
       pc=loc2resolv[i] 
       completed=0 
       for j = 1 to 4 do 
          if hc[pc+(j-1)*2][1]!='3' then 
            exit 
          end if 
          hc[pc+(j-1)*2][3]=saddr[j] 
          if j=4 then 
            completed=1 
          end if 
       end for 
       if not completed then error(ERR_LOC_RESOLV) end if       
    end for 
    unresolved[URES_LBL]=unresolved[URES_LBL][1..p-1]&unresolved[URES_LBL][p+1..$] 
    unresolved[URES_LOC]=unresolved[URES_LOC][1..p-1]&unresolved[URES_LOC][p+1..$] 
end procedure 
 
/* 
  macros expansion routines 
*/ 
 
--MACRO: SETREG expansion: generate code to set a register 'r' with arbitrary integer 
-- if r <> 0 then use R0 to store multiplier else use R1 
function set_reg(sequence tokens) 
integer p,d,m, neg=0, val 
sequence r={}, t2={}, opcode={}, hc_lines={} 
 
     r=tokens[1] 
     if r[1]!='R' then 
        error(ERR_BAD_ARG) 
     end if 
     d=r[2] 
     t2=tokens[2] 
     if t2[1]=':' then --label reference 
       p=find(t2[2..$],labels[LBL_NAME]) 
       if p then 
         val=labels[LBL_LOC][p] 
         t2=sprintf("%04d",val) 
       else -- unresolved label 
         add_unresolved(t2[2..$],length(hc)+4) 
         val=9999 
         t2="0000" 
       end if 
     elsif t2[1]='-' and digit(t2[2]) then --negative number 
       neg=1 
       t2=value(t2[2..$]) 
       val=t2[2] 
       t2=sprintf("%d",val) 
     elsif digit(t2[1]) then --positive number     
       t2=value(t2) 
       if t2[1]!=GET_SUCCESS then 
         error(ERR_BAD_ARG) 
       end if 
       val=floor(t2[2]) 
       t2=sprintf("%d",val) 
     else  -- symbol reference 
       p=find(t2,symbols[SYM_NAME])  
       if not p then 
         error(ERR_UNKNOWN_SYMBOL) 
       end if 
       val=symbols[SYM_VAL][p]   
       if val<0 then 
         neg=1 
         val = -val 
       end if 
       t2=sprintf("%d",val)    
     end if 
     if d>'0' then  
       m='0' 
     else 
       m='1' 
     end if 
     if val < 10 then 
        opcode='2' & d & (val + '0') 
        hc_lines={opcode} 
     else 
        -- set d=0 
        opcode='2'&d&'0'  -- SETI Rd 0     
        hc_lines={opcode} 
        -- set m=10 ; multiplier 
        opcode='2'&m&'9'  -- SETI Rm 9 
        hc_lines&={opcode} 
        opcode='3'&m&'1'   -- ADDI  Rm 1 -> Rm=10 
        hc_lines&={opcode}         
        for i=1 to length(t2) do 
           opcode='3'& d & t2[i]  -- ADDI  Rd t2[i] 
           hc_lines &= {opcode} 
           if i<length(t2) then 
             opcode='7'&d&m -- MUL  Rd Rm -> Rd = Rd * 10 
             hc_lines&={opcode} 
           end if 
        end for  
     end if 
     if neg then 
        opcode='2'&m&'0' -- STI Rm 0 
        hc_lines&={opcode} 
        opcode='8'&m&m -- LOAD Rm Rm  ->  Rm = -1    
        hc_lines&={opcode} 
        opcode='7'&d&m  -- MUL Rd Rm  -> Rd = -Rd 
        hc_lines&={opcode} 
     end if 
     return hc_lines   
end function 
 
-- MACRO: SETRAM expansion: generate code to set ram to an arbitrary integer 
-- use R2 to store ram_address and R1 store value 
function set_ram(sequence tokens) -- SETRAM  ram_address value 
sequence hc_lines 
   hc_lines=set_reg({"R2",tokens[1]})&set_reg({"R1",tokens[2]}) --  R2 = ram_address, R1=value 
   hc_lines&={"912"} -- STOR  R1 R2 -> ram_address [R2]=R1 
   return hc_lines 
end function 
 
--MACRO: GOTO expansion: generate code for unconditional goto 
-- use R2 to store PC address and R0 set to 1  
function goto_(sequence tokens)  --  GOTO  code_address 
sequence address,hc_lines 
integer p     
     
    hc_lines= set_reg({"R2"} & tokens) 
    hc_lines &={"201","020"} -- SETI R0 0  and JNZ  R1 R0 
    return hc_lines 
end function 
 
 
--MACRO: STVAR var_address  Rv   expansion 
-- tokens[1]  var_address,  tokens[2] register containing value 
function store_var(sequence tokens) 
sequence  t2, hc_lines={} 
integer s      
 
     t2=tokens[2] 
     if t2[1]!='R' then 
       error(ERR_BAD_ARG) 
     end if 
     s=tokens[2][2] 
     hc_lines=set_reg({"R1"}&{tokens[1]})--set address in R1 
     hc_lines&={'9'&s&'1'}  -- STORE Rs R1 
     return hc_lines 
end function 
 
--MACRO: LDVAR Rv var_address expansion 
-- tokens[1] register to store value,  tokens[2] var_address 
function load_var(sequence tokens) 
sequence t1, hc_lines={} 
integer rv 
 
     t1= tokens[1] 
     if t1[1]!='R' then 
       error(ERR_BAD_ARG) 
     end if     
     rv=t1[2] 
     hc_lines=set_reg(tokens) 
     hc_lines&={"8"&rv&rv} 
     return hc_lines    
end function 
 
 
--MACRO: NOP expansion 
-- nop operation by adding constant 0 to R0 
function nop(sequence tokens) 
sequence comment 
integer p 
    comment=asm[asm_line] 
    p = find(';',comment) 
    if p then 
      comment=comment[p..$] 
    else 
      comment="" 
    end if 
    return {"300 "&comment} 
end function 
 
--MACRO: LPNZ :label Rc  expansion 
-- R2 is used to store label address 
-- :label is label to loop back,  Rc is control register for zero value 
function loop_not_zero(sequence tokens) 
sequence t2,hc_lines={} 
integer rc 
     
    t2=tokens[2] 
    if t2[1]!='R' then 
      error(ERR_BAD_ARG) 
    end if 
    rc=t2[2] 
    hc_lines=set_reg({"R2",tokens[1]}) 
    hc_lines&={"0"&'2'&rc} 
    return hc_lines 
end function 
 
constant -- list of macros 
MACROS={ 
  "SETREG", 
  "SETRAM", 
  "GOTO", 
  "STVAR", 
  "NOP", 
  "LPNZ", 
  "LDVAR" 
}   
 
constant-- number of arguments used by macro 
MAC_ARG_COUNT={2,2,1,2,0,2,2} 
 
constant rid_macros={ 
                     routine_id("set_reg"), 
                     routine_id("set_ram"), 
                     routine_id("goto_"), 
                     routine_id("store_var"), 
                     routine_id("nop"), 
                     routine_id("loop_not_zero"), 
                     routine_id("load_var")  
                    } 
 
 
enum ST_IDLE, ST_ARG1, ST_ARG2, ST_COMPLETED 
procedure parse(sequence tokens) 
integer p,i,m,acount, state=ST_IDLE 
sequence opcode, t 
--trace(1) 
--if asm_line=90 then trace(1) end if 
      if not length(tokens) then return end if -- empty or comment line 
      i=1 
      while state!=ST_COMPLETED and i <= length(tokens) do 
         t=tokens[i] 
         m=find(t,MNEMONICS) 
         switch state do 
           case ST_IDLE then 
             if t[1]=':' then 
                 labels[1]=append(labels[1],t[2..$]) -- label symbol 
                 labels[2]=append(labels[2],length(hc)) -- label address 
                 resolve(t[2..$],length(hc)) 
             elsif t[1]='.' then -- keyword 
                m=find(t,KEYWORDS) 
                if not m then 
                  error(ERR_UNKNOWN_KEYWORD) 
                end if 
                call_proc(rid_keywords[m],{tokens[2..$]}) 
                state=ST_COMPLETED 
                opcode={} 
             elsif m then 
                acount=ARG_COUNT[m] 
                if length(tokens[i+1..$])<acount then error(ERR_MISSING_ARG) end if 
                if ARG_COUNT[m]=0 then 
                  opcode={"100"}  -- HALT is the only mnemonic without argument 
                  state=ST_COMPLETED 
                  exit 
                elsif m<11  then 
                   opcode ={m-1+'0'} 
                elsif equal(t,"PRNL") then 
                   opcode="?" 
                else 
                   opcode="??" 
                end if 
                state=ST_ARG1 
             else 
                m=find(t,MACROS) 
                if not m then error(ERR_UNKNOWN_SYMBOL) end if 
                acount=MAC_ARG_COUNT[m] 
                if length(tokens[i+1..$])<acount then error(ERR_MISSING_ARG) end if 
                opcode=call_func(rid_macros[m],{tokens[i+1..$]}) 
                state=ST_COMPLETED 
             end if    
           case ST_ARG1 then 
             if t[1]!='R' then error(ERR_BAD_ARG) end if -- first arg always a register 
             p=t[2] 
             if p<'0' or p>'9' then error(ERR_BAD_ARG) end if 
             opcode&=p 
             if acount=1 then 
               opcode&=' ' 
               opcode={opcode} 
               state=ST_COMPLETED 
             else 
               state=ST_ARG2 
             end if 
           case ST_ARG2 then 
             if t[1]='R' then 
               p=t[2] 
             else 
               if digit(t[1]) then 
                 p=t[1] 
               else 
                 p=find(t,symbols[SYM_NAME]) 
                 if p then 
                   p=symbols[SYM_VAL][p] 
                   if p<0 or p>9 then 
                     p=' ' 
                   else 
                     p+='0' 
                   end if 
                 else 
                   p=' ' 
                 end if 
               end if   
             end if   
             if p<'0' or p>'9' then error(ERR_BAD_ARG) end if 
             opcode&=p & ' ' 
             opcode={opcode} 
             state=ST_COMPLETED   
         end switch 
         i += 1    
      end while 
      if state=ST_COMPLETED then 
        if length(opcode) then hc&=opcode end if 
      else 
        error(ERR_MISSING_ARG) 
      end if 
end procedure 
 
_ = date() 
_[1] += 1900 
constant CODE_HEADER={ 
  "300 ;GENERATOR: hcasm.ex  (macro assembler for contest #2 cpu)", 
  sprintf("300 ;TIMESTAMP: %4d-%02d-%02d %02d:%02d:%02d",_) 
} 
hc=CODE_HEADER 
 
procedure generate_code() 
sequence tokens, code, f_name 
integer p, fh, lc 
 
  for i = 1 to length(asm) do 
     asm_line=i 
     p=find(';',asm[i]) 
     if p then  
          code=upper(asm[i][1..p-1]) 
     else 
          code=upper(asm[i]) 
     end if     
     if length(code) then 
       lc=length(hc) 
       tokens=split(code,' ',1) 
       parse(tokens) 
       for j= lc+1 to length(hc) do 
         if length(hc[j])<4 then hc[j] &= repeat(32,4-length(hc[j])) end if 
       end for 
       if length(hc)>lc then 
          lc+=1 
          hc[lc] &= code 
       end if 
     end if      
  end for 
  p=find('.',file) 
  f_name=file[1..p]&"hc" 
  fh=open(f_name,"w") 
  for i=1 to length(hc) do 
    puts(fh,hc[i]&'\n') 
  end for 
  close(fh)      
end procedure 
 
procedure parse_args() 
sequence args 
 
   args=command_line() 
   if length(args)<3 then 
     puts(1,"USAGE: eui hcasm.ex asm_file\n") 
     abort(1) 
   end if 
   file=args[3] 
end procedure 
 
procedure main() 
  parse_args() 
  read_file() 
  generate_code() 
end procedure 
main() 

new topic     » goto parent     » topic index » view message » categorize

23. Re: Contest #2... Example Programs

coconut said...

Here my assembler code

Cool! Now where are some example programs! grin

Matt

new topic     » goto parent     » topic index » view message » categorize

24. Re: Contest #2... Example Programs

mattlewis said...
coconut said...

Here my assembler code

Cool! Now where are some example programs! grin

Matt

here my version of game of life for this assembler

nop ; TITLE: game of life  
nop ; AUTHOR: Jacques Deschênes 
nop ; life rules: 
nop ; 3 neighbor -> birth 
nop ; 2|3 neighbor -> survive 
nop ; <2|>3  neighbor -> die 
nop ; 
nop ;   glider initial shape 
nop ;      *           
nop ;       *          
nop ;     ***          
 
.sym t1 9       ; cell array 1 
.sym t2 409     ; cell array 2 
.sym max_gen -40 ; stop after 25 generation 
.sym size 20    ; size of grid 
.sym gencount 2 ; address of generation counter variable 
 
       seti R0 1 
       stvar gencount R0  ; generation counter 
       nop ; initialize the arrays  
       setreg R3 800 ; loop counter  
       seti R4 t1    ; first array address 
:L1    ldvar R0 minus1    ; load -1 in R0 
       seti R2 0     ; memset to 0 
       stor R2 R4     
       addi R4 1   
       add  R3 R0 
       lpnz :L1 R3   ; loop if R3 not 0 
       nop ;initialize t1 with a single glider in the top left corner 
       seti R3 1    ; value to store 
       setreg R4 31 ; store address 
       stor R3 R4 
       setreg R4 52 
       stor R3 R4 
       setreg R4 70 
       stor R3 R4 
       addi R4 1 
       stor R3 R4 
       addi R4 1 
       stor R3 R4    
       nop ; print generation 0 
       seti R0 0 
       prnl R0 
       setreg R5 30 ; t1 
       setreg R6 18 
       setreg R7 18 
:LC    load R0 R5 
       prsp R0 
       addi R5 1 
       ldvar R0 minus1 
       add R7 R0 
       setreg R2 :LC 
       jnz R2 R7 
       setreg R7 18 
       addi R5 2 
       ldvar R0 minus1 
       add R6 R0 
       prnl R6 
       setreg R2 :LC 
       jnz R2 R6 
       nop ; print generation number 
:glp   ldvar R3 gencount 
       prnl  R3     ; print generation number 
       setreg R4 size ; row increment                       
       setreg R5 30 ; t1 first cell  
       setreg R6 18 ; row counter        
       setreg R7 18 ; column counter 
       setreg R8 430; t2 first cell   
:g2    seti R9 0    ; neighbor counter 
       ldvar R0 minus1  ; put -1 in R0 
       cpy R1 R4    ; 20 -> R1 
       mul R1 R0    ; -20 -> R1  
       cpy R2 R5    ; &t1 -> R2 
       add R2 R1    ; &t1-20 -> R2 
       add R2 R0    ; &t1-21 -> R2 
       load R1 R2   ; begin row over neighbor count  
       add R9 R1    ;  
       addi R2 1    ;  
       load R1 R2 
       add R9 R1 
       addi R2 1 
       load R1 R2 
       add R9 R1    ; row over neighbord count completed 
       add R2 R4    ; begin current neighbor count 
       load R1 R2 
       add R9 R1 
       add R2 R0 
       add R2 R0 
       load R1 R2 
       add R9 R1    ;count complted for this row 
       add R2 R4    ; begin row under count 
       load R1 R2 
       add R9 R1 
       addi R2 1 
       load R1 R2 
       add R9 R1 
       addi R2 1  
       load R1 R2  
       add R9 R1   ;all neighbors counted.  
       setreg R2 :GT0 
       jnz R2 R9 
       goto :die   ; 0 neighbor die 
:GT0   ldvar R0 minus1 ; count >= 1 
       mul R9 R0  ; negate count            
       addi R9 1  ; check status of this cell 
       setreg R2 :GT1 
       jnz R2 R9 
       goto :die  ; 1 neighbor die     
:GT1   addi R9 1 
       setreg R2 :GT2 
       jnz R2 R9 
       goto :stabl  ; 2 neighbor stay as is.  
:GT2   addi R9 1 
       setreg R2 :die 
       jnz R2 R9     ; more than 3 neighbor die    
       seti R0 1      
       stor R0 R8    ; store 1 in t2 array 
       prsp R0 
       goto :nextc 
:stabl load R0 R5 
       stor R0 R8    ; copy cell t1 to t2 
       prsp R0 
       goto :nextc        
:die   seti R0 0 
       stor R0 R8    ; store 0 in t2 
       prsp R0 
:nextc addi R5 1     ; next cell 
       addi R8 1 
       ldvar R0 minus1 
       add  R7 R0 
       setreg R2 :nxc1 
       jnz R2 R7 
       setreg R7 18 
       ldvar R0 minus1 
       add R6 R0 
       prnl R6 
       setreg R2 :nxc0 
       jnz R2 R6 
       goto :gend 
:nxc0  ldvar R0 minus1  
       addi R5 2 
       addi R8 2 
:nxc1  goto :g2 
       nop ; check gencount stop if = max_gen 
:gend  ldvar R3 gencount 
       addi  R3 1 
       stvar gencount R3 
       setreg R0 max_gen 
       add R3 R0 
       setreg R2 :cpy 
       jnz R2 R3 
       halt 
:cpy   nop   ; copy t2 to 1 
       setreg r5 9 
       setreg r6 409 
       setreg r7 400 
:cpy1  load r0 r6 
       stor r0 r5 
       addi r5 1 
       addi r6 1 
       ldvar r3 minus1 
       add r7 r3 
       setreg r2 :cpy1 
       jnz r2 r7 
       goto  :glp 
       halt        

new topic     » goto parent     » topic index » view message » categorize

25. Re: Contest #2... Example Programs

Hi

There are two assemblers for a certain computer?

Clearly, you boys have too much time on your hands!

Chris

new topic     » goto parent     » topic index » view message » categorize

26. Re: Contest #2... Example Programs

ChrisB said...

Hi

There are two assemblers for a certain computer?

Clearly, you boys have too much time on your hands!

Chris

Some like to watch TV, some like to play video games, and some like programming... And BTW it was rainy all weekend. And if I had more time, I have many ideas to improve my hcasm.ex: macros for logical operators et comparisons, support for subroutine call with parameters passing reserving R9 as a stack pointer.

I already figured out how to do that but don't have the time... have to go to work...

Jacques

new topic     » goto parent     » topic index » view message » categorize

27. Re: Contest #2... Example Programs

-)

new topic     » goto parent     » topic index » view message » categorize

28. Re: Contest #2... Example Programs

Hi

Just found another error in my vm - running bouncing 1s on yours will look much nicer now!

Chris

new topic     » goto parent     » topic index » view message » categorize

29. Re: Contest #2... Example Programs

coconut said...

I do the label fixup very differently. each time my assembler hit a forward reference to a label it reserve a fixed number of code instructions. Derek and Matt assembler use addition of power of 2, mine use power of tens. I reserve a register to hold number 10 and multiply the targer register with that number. I grow the address by a serie of "addi Rt n" and "mult Rt Rm". It doesn't need a second pass to fix the labels. When a label is met in the code the assembler immediatly lookup the pending fix and resolve them. There is 2 limitations to my system: to space allocated is always the same so it is oversized for small address. Secondly It limit the program address space to 0 - 9999. I could increase it but it would means more space lost.

Very interesting, Jacques. I took another different approach to resolving labels in my (unreleased) cpu assembler. Instead of powers of 2 or 10, I wrote a general purpose function to generate instructions to load an arbitrary integer into a register using add and mul operations. To generate a jump offset, it loads the address of the label into the register using that function. For example, to load 999 into a register, the instructions emitted are:

289 r8=9 484 r8*=4 (36) 381 r8+=1 (37) 483 r8*=3 (111) 483 r8*=3 (333) 483 r8*=3 (999)

There's an obvious optimization missed there: it should use a *=9 instead of two *=3. There's also a problem when there's a backward reference and forward reference that overlap: the size of the label loads may shift the label address up and down, and the assembler doesn't terminate until the label addresses stop fluctuating. One solution is to manually put nops into the code in random places to try to get it to converge, but requires luck. I ended up making the assembler insert nops for me to keep a label address fixed when it takes too many tries to get them to settle.

It was rainy here too in Oregon this past weekend. I initially wasn't going to write my own assembler for a cpu that won't be used after a week, but it turns out I couldn't resist. I'll post the code later tonight.

Edit: and here it is. I also solved that number optimization bug.

-- User: PeteE 
-- Contest 2 virtual machine assembler 
-- Usage: vmasm.ex prog.src > prog.cpu 
 
include std/io.e 
include std/text.e 
include std/cmdline.e 
include std/convert.e 
include std/map.e as map 
include std/regex.e as re 
 
re:regex 
  set_val = re:new(`^r([0-9])=(-?[0-9]+)`), 
  set_reg = re:new(`^r([0-9])=r([0-9])`), 
  add     = re:new(`^r([0-9])\+=([0-9])`), 
  add_reg = re:new(`^r([0-9])\+=r([0-9])`), 
  mul     = re:new(`^r([0-9])\*=([0-9])`), 
  mul_reg = re:new(`^r([0-9])\*=r([0-9])`), 
  load    = re:new(`^r([0-9])=\[r([0-9])\]`), 
  store   = re:new(`^\[r([0-9])\]=r([0-9])`), 
  set_lbl = re:new(`^r([0-9])=@([A-Za-z0-9_]+)`), 
  if_reg  = re:new(`^if r([0-9]) ([A-Za-z0-9_]+)`), 
  a_label = re:new(`^([A-Za-z0-9_]+):`), 
  halt    = re:new(`^halt`), 
  nop     = re:new(`^nop`) 
 
map:map nums = map:new() -- memoized num() 
 
-- return a sequence of instructions which load the value n into a register r 
function num(integer r, integer n, integer limit) 
  sequence 
    result, 
    tmp 
  if n < 0 then 
    result = {sprintf("2%s0 r%s=0",{r,r}), 
              sprintf("8%s%s r%s=[r%s] (-1)",{r,r,r,r})} 
    if n != -1 then 
      result &= num(r, -n, 0) 
      result[3][1] = '4'  -- convert first set op to a mul 
      result[3] = insert(result[3], '*', 7) 
    end if 
    return result 
  end if 
  result = map:get(nums, n, {}) 
  if length(result) then  -- we've seen n before 
    for i = 1 to length(result) do 
      result[i][2] = r  -- rewrite the dest register 
      result[i][6] = r 
    end for 
    return result 
  elsif n >= 0 and n <= 9 then 
    result = {sprintf("2%s%d r%s=%d",{r,n,r,n})} 
  elsif limit = 0 or limit > 2 then 
    if limit != 0 then 
      limit -= 1 
    end if 
    for i = 2 to 9 do  -- factors 
      if i*floor(n/i) = n then 
        tmp = num(r, floor(n/i), limit) 
        if length(tmp) then 
          tmp &= {sprintf("4%s%d r%s*=%d   (%d)", {r,i,r,i,n})} 
          if limit = 0 or length(tmp) < limit then 
            result = tmp 
  	    limit = length(tmp) 
          end if 
        end if 
      end if 
    end for   
    for i = 1 to 9 do  -- sums 
      tmp = num(r, n-i, limit) 
      if length(tmp) then 
        tmp &= {sprintf("3%s%d r%s+=%d   (%d)", {r,i,r,i,n})} 
        if limit = 0 or length(tmp) < limit then 
          result = tmp 
          limit = length(tmp) 
        end if 
      end if 
    end for 
  end if 
  map:put(nums, n, result) -- memoize this result 
  return result 
end function 
 
 
function assemble(sequence prog) 
  sequence s 
  object ref 
  integer 
    n = 0, 
    done = 0, 
    tries = 0 
  map:map labels = map:new() 
 
  for i = 1 to length(prog) do 
    prog[i] = trim(prog[i]) 
  end for 
 
  -- first pass: assemble instructions and remove blank lines 
  n = 1 
  while n <= length(prog) do 
    s = prog[n] 
    if length(s) = 0 then 
      prog = remove(prog, n) 
      continue 
    end if 
     
    ref = re:find(if_reg, s) 
    if sequence(ref) then 
      s = {"r9=@" & s[ref[3][1]..ref[3][2]], 
           "09" & s[ref[2][1]] & " " & s} 
      prog = replace(prog, s, n) 
      n += 2 
      continue 
    end if 
 
    ref = re:find(set_val, s) 
    if sequence(ref) then 
      s = num(s[ref[2][1]], to_integer(s[ref[3][1]..ref[3][2]]), 0) 
      s[1] &= prog[n][ref[1][2]+1..$] 
      prog = replace(prog, s, n) 
      n += length(s) 
      continue 
    end if 
 
    s = re:find_replace(add,     s, `3\1\2 r\1+=\2`) 
    s = re:find_replace(mul,     s, `4\1\2 r\1*=\2`) 
    s = re:find_replace(set_reg, s, `5\1\2 r\1=r\2`) 
    s = re:find_replace(add_reg, s, `6\1\2 r\1+=r\2`) 
    s = re:find_replace(mul_reg, s, `7\1\2 r\1*=r\2`) 
    s = re:find_replace(load,    s, `8\1\2 r\1=[r\2]`) 
    s = re:find_replace(store,   s, `9\2\1 [r\1]=r\2`) 
    s = re:find_replace(halt,    s, `100 halt`) 
    s = re:find_replace(nop,     s, `300 nop`) 
    prog[n] = s 
    n += 1 
  end while 
 
  -- middle pass: presize label loads and check each label address 
  while not done do 
    done = 1 
    tries += 1 
    n = 0 
    for i = 1 to length(prog) do 
      ref = re:find(a_label, prog[i]) 
      if sequence(ref) then 
        s = prog[i][ref[2][1]..ref[2][2]] 
        if map:get(labels, s, -1) != n then 
	  -- recalculate label 
	  if tries > 20 and map:get(labels, s) = n + 1 then 
	    n = map:get(labels, s) + 1  -- give up and pad later with nops 
	  elsif tries > 30 and map:get(labels, s) > n then 
	    n = map:get(labels, s) + 1  -- give up and pad later with nops 
	  else 
	    done = 0 
	    --if length(num('0', n, 0)) > length(num('0', n+1, 0)) and tries < 10 then 
	    --  n += 1 
	    --end if 
	    map:put(labels, s, n) 
	  end if 
	  --printf(2, "%s is %d\n", {s, n}) 
	end if 
	continue 
      end if 
       
      ref = re:find(set_lbl, prog[i]) 
      if sequence(ref) then 
        s = prog[i][ref[3][1]..ref[3][2]] 
        n += length(num('0', map:get(labels, s), 0)) 
	continue 
      end if 
       
      n += 1 
    end for 
  end while 
  --printf(2, "tries=%d\n", tries) 
   
  -- final pass: assemble label loads and remove labels 
  n = 1 
  while n <= length(prog) do 
    ref = re:find(set_lbl, prog[n]) 
    if sequence(ref) then 
      s = prog[n][ref[3][1]..ref[3][2]] 
      if not map:has(labels, s) then 
	printf(2, "undefined label: %s\n", {s}) 
	abort(1) 
      end if 
      s = num(prog[n][ref[2][1]], map:get(labels, s), 0) 
      s[1] &= prog[n][ref[1][2]+1..$] 
      prog = replace(prog, s, n) 
      n += length(s) 
      continue 
    end if 
    ref = re:find(a_label, prog[n]) 
    if sequence(ref) then 
      s = prog[n][ref[2][1]..ref[2][2]] 
      --printf(2,"label %s is at %d  n is %d\n", {s, map:get(labels, s), n}) 
      s = repeat("300 nop", map:get(labels, s) - n + 1) -- nop padding 
      prog = replace(prog, s, n) 
      n += length(s) 
      continue 
    end if 
    n += 1 
  end while 
 
  return prog 
end function 
 
 
constant cmd_line = command_line() 
write_lines(1, assemble(read_lines(cmd_line[3]))) 

new topic     » goto parent     » topic index » view message » categorize

30. Re: Contest #2... Example Programs

PeteE said...

There's also a problem when there's a backward reference and forward reference that overlap: the size of the label loads may shift the label address up and down, and the assembler doesn't terminate until the label addresses stop fluctuating.

Yeah, that's why I went with the powers of two. It was easy to calculate. Also, I was more interested in inefficient code, in order to get longer benchmarks for interpreters. smile

Matt

new topic     » goto parent     » topic index » view message » categorize

31. Re: Contest #2... Example Programs

This crippled cpu triggered a lot of thinking ascribed to its own nature. I guess everyone was wondering how to code real programs witch such a poor cpu.

No status register
logical operations reduce to a single jnz
RISC takes a new meaning with that cpu.

Anyway as I was arriving from work I found in my mailbox "Operating systems design and implementation" by Tanembaum and Woodhull.
Thanks to Amazon used books, I got it for cheap. So my curiosity will follow another path for a while.

Jacques

new topic     » goto parent     » topic index » view message » categorize

32. Re: Contest #2... Example Programs

coconut said...

This crippled cpu triggered a lot of thinking ascribed to its own nature. I guess everyone was wondering how to code real programs witch such a poor cpu.

  • No status register
  • logical operations reduce to a single jnz

RISC takes a new meaning with that cpu

Jacques

shocked

This really is a RISC chip ... so risky I'd never buy one.

new topic     » goto parent     » topic index » view message » categorize

33. Re: Contest #2... Example Programs

Generates a grid like this.

1 0 0 0 0 
0 1 0 0 0 
0 0 1 0 0 
0 0 0 1 0 
0 0 0 0 1 
800 ; r[0] = -1 
292 ; \ (2*3-1) 
493 ;  > Tinker with these lines to change the size 
690 ; / -- Subtract 1 
519 ; loop 1 
529 ; loop 2 
620 
237 ; jump point (this_line # - 1) 
553 
359 
352 
260 
540 
742 
641 
640 
054 ; skip if r[4] != 0 
261 
620 
??6 
032 ; end loop 2 
610 
630 
630 
355 
359 
260 
540 
742 
641 
054 ; skip if r[4] != 0 
261 
?6 
031 ; end loop 1 
100 ; Halt 
new topic     » goto parent     » topic index » view message » categorize

34. Re: Contest #2... Example Programs

Can you read the message? This program has a few extra goodies in it. It is guaranteed to test every function and is usable as a bench mark if you change line 425 to 100, A HALT I will post a follow-up message creator program with some instructions on how to use it.

399 ; Goto line 32 to control the Delay speed 
395 ; 
099 ;  
511 ; This CPU program created by: 
511 ;   Lucius L. Hilley III 
511 ; 	aka: Unkmar 
511 ; http://www.hilleyonline.com/ 
511 ; http://www.unkmar.com/ 
511 ;  
511 ; [ 2010-12-18 22:52:15 EST ] 
511 ;  
511 ;  
511 ;  
511 ;  
399 ; --=<{([ Push Message ]})>=- 
398 ; IP will be stored at r[9] 
099 ; IP = Instruction Pointer 
511 ; Maintain the IP and usually 
511 ; Things work. 
511 ; ------------------------------ 
511 ; Message encoding font is 1-based 
511 ; Character set is: 
511 ; "ABCDEFGHIJKLMNOPQRSTUVWXYZ " 
511 ; A = 1, Z = 26, ' ' = 27 
511 ; 0 = End of Message 
511 ; Max length = 980 
511 ; ------------------------------ 
511 ; mem[1..9] Reserved for 
511 ;   Function Pointers 
511 ; mem[10] = Delay Count 
511 ; ------------------------------ 
399 ; -- First CODE 
399 ; Set Delay Count 
215 ; x = 5 
711 ; ((x^2)^2)^2 
711 
711 
411 
411 
411 
411 
200 ; POP -1 
800 ;  
710 ; r[1] *= -1 (Negate r[1]) 
205 ; 
305 ; 
910 ; [PUSH] Delay Count 
200 ; Reset used registers 
210 ; ------------------------------ 
393 
229 ; MP = 11 --Prime Message Pointer 
322 ; 
391 ; ------------------------------ 
396 ;       --==[ Letter START ]==- 
321 ; MP += 1 
219 ; W (Letter goes here) 
319 
315 
912 ; [PUSH] --==[ Letter END ]==- 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
215 ; E (Letter) 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; L (Letter) 
313 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
213 ; C (Letter) 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; O (Letter) 
316 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; M (Letter) 
314 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
215 ; E (Letter) 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; T (Letter) 
319 
312 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; O (Letter) 
316 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; T (Letter) 
319 
312 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
218 ; H (Letter) 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
215 ; E (Letter) 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
213 ; C (Letter) 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; P (Letter) 
317 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; U (Letter) 
319 
313 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; T (Letter) 
319 
312 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
218 ; H (Letter) 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
211 ; A (Letter) 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; T (Letter) 
319 
312 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
215 ; E (Letter) 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; U (Letter) 
319 
313 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; P (Letter) 
317 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
218 ; H (Letter) 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; O (Letter) 
316 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; R (Letter) 
319 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; I (Letter) 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
211 ; A (Letter) 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
212 ; B (Letter) 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; U (Letter) 
319 
313 
912 ; [PUSH] 
394 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; I (Letter) 
912 ; [PUSH] 
395 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; L (Letter) 
313 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ; T (Letter) 
319 
312 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
396 ; --==[ Letter START ]==- 
321 ; MP += 1 
219 ;   (Letter) 
319 
319 
912 ; [PUSH] 
519 ; IP will be stored at r[9] 
318 ; Skip (21) -------------------- 
201 ; r[0] will enum functions 
910 ; 
393 ; 
399 ; -=[ Using 39x's to maintain IP ]=- 
399 ;    -=[ 20 = 392 + 399 + 399 ]=- 
099 ; Display Registers 
??0 ; 0--------- > r[0] = -1 
??1 ; -1-------- > r[1] = PUSH/POP Message 
??2 ; --2------- > r[2] = Message Pointer 
??3 ; ---3------ > r[3] = POP Message (Copy) 
??4 ; ----4----- > r[4] = Loop IP 
??5 ; -----5---- > r[5] = Offset to Characters 
??6 ; ------6--- > r[6] = Character Size 
??7 ; -------7-- > r[7] = Foregrond (Text) 
??8 ; --------8- > r[8] = Background 
?9  ; ---------9 > r[9] = IP - instruction pointer 
200 ; (393 399 ??0 ??1 ??2 ??3 ??4 ??5 ??6 ??7 ??8 ?9)-:s:\s:\r:g 
800 ; 
099 ; RETURN - {1}Display Registers (11 of 21) 
519 ; Skip (32) -------------------- 
318 ; 
301 ; enum 
910 ; 
218 ; 
414 ; 
691 ; 
099 ; 
202 ; [POP] Registers 
309 ; -=( Uses r[0] as mem[r[0]..r[0]+7])=- 
402 ; 
409 ; 
405 ; 
511 ; Padding for Choosing other locations.  Needs to match POP 
810 ; POP r[1] 
301 ; 
820 ; POP r[2] 
301 ; 
830 ; POP r[3] 
301 ; 
840 ; POP r[4] 
301 ; 
850 ; POP r[5] 
301 ; 
860 ; POP r[6] 
301 ; 
870 ; POP r[7] 
301 ; 
880 ; POP r[8] 
200 ; 
800 ; -=( Restores r[0] from mem[0] )=- 
099 ; RETURN - {2}POP (25 of 32) 
519 ; Skip (32) -------------------- 
318 ; 
301 ; enum 
910 ; 
218 ; 
414 ; 
691 ; 
099 ; ------------------------------ 
202 ; [PUSH] Registers 
309 ; -=( Uses r[0] as mem[r[0]..r[0]+7])=- 
402 ; 
409 ; 
405 ; 
511 ; Padding for Choosing other locations.  Needs to match POP 
910 ; PUSH r[1] 
301 ; 
920 ; PUSH r[2] 
301 ; 
930 ; PUSH r[3] 
301 ; 
940 ; PUSH r[4] 
301 ; 
950 ; PUSH r[5] 
301 ; 
960 ; PUSH r[6] 
301 ; 
970 ; PUSH r[7] 
301 ; 
980 ; PUSH r[8] 
200 ; 
800 ; -=( Restores r[0] from mem[0] )=- 
099 ; RETURN - {3}PUSH (25 of 32) 
519 ; Skip (12) -------------------- 
317 ; 
301 ; enum 
910 ; 
393 ; 
399 ; 
099 ; ------------------------------ 
311 ; Count += 1 
001 ; Goto Count += 1 until Count = 0 
200 ; 
800 ; 
099 ; RETURN - {4}Delay(r[1]) 
394 ; 
210 ; Cleanup r[0..1] = 0 
200 ; 
099 ; 
399 ; --=<{([ Start Program ]})>=- 
397 ; Plus (17) 
800 ; -=( POP -1 into r[0] )=- 
277 ; Set Foreground 
288 ; Set Background 
259 ; { Character 
352 ;   width = 11 } 
269 ; { Character 
364 ;   height 13 } 
765 ; Combine Character size 
361 ; Add RETURN Instruction 
250 ; Clean-up 
099 ; ------------------------------ 
511 ; Now using r[0,2] and r[6..9] 
511 ; ------------------------------ 
511 ;   SKIP mem[0..9] (MP = 9) 
399 ; ------------------------------ 
394 ; ------------------------------ 
321 ; MP += 1 
210 ; Force a NULL 
912 ; [PUSH] 
229 ; MP = 11  --Reset Message Pointer 
322 ; -=<({[ Last SAFE Command ]})>=- 
511 ; -=<({[ Crazy Loops and Jumps Below ]})>=- 
511 ; -=<({[ 3 values Must be Maintained ]})>=- 
511 ; *** WARNING *** Do not edit below this point 
549 ; Set r[4] = r[9] as (Loop IP)  -->\ 
399 ; ------------------------------    | 
393 ;                                  / 
321 ; MP += 1  (r[4] Points here) <---/ 
812 ; Grab Char of Message 
832 ; Copy to r[3] 
610 ; Subtract 1 to convert to 0-index 
716 ; Multiply Character size 
554 ; Grab IP of r[4] 
359 ; Add Offset to Characters 
359 ; 
359 ; 
359 ; (Skips HALT) 
615 ; Add Offset 
013 ; Gosub Character(r[3]) 
399 ; ------------------------------ 
219 ; Get Delay Counter 
311 ; r[1] = 10 
811 ; POP mem[10] 
511 ; Not safe for me to remove 
511 ; 2 nop's :( Crazy jumps down here ): 
204 ; Select Delay(r[1]) 
800 
000 
409 ; -- (r[9] Points here) 
690 
200 
800 
043 
290 100 ; -=[HALT]=- 
280 
270 
260 
250 
240 
230 
220 
210 
010 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??8 
?8 
??8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??8 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??7 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??7 
??7 
??7 
?8 
??8 
??8 
??7 
??7 
??7 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??7 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
??7 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
??8 
?8 
099 
100 ; -=[HALT]=- 

new topic     » goto parent     » topic index » view message » categorize

35. Re: Contest #2... Example Programs

unkmar said...

Can you read the message?

Yes! Very nicely done.

new topic     » goto parent     » topic index » view message » categorize

36. Re: Contest #2... Example Programs

The font set was hand crafted as a grid in vim and then I used vim's regex to produce the print statements. The choice of using registers 7 and 8 for foreground were actually accidental. I felt those numbers provided a high contrast display. Afterwards I was getting blank squares because I had not set those registers to a value.

The approximate 400 lines of code were hand written. I did not use any assembler or translator to manage the jump points. At this point I have committed the instruction set to memory. I can read and write the codes without having to reference the guide. or look at the comments.

I setup a handful of conceptual ideas that made it easier for me to manage the code. I reserved r[9] as an Instruction Pointer (IP), I would maintain the pointer throughout the code. It made functions such as each character in the font a very easy task. Like others I had reserved r[0] for -1. At some point I started running out of registers. I wasn't storing much of anything in RAM yet. And so I was having trouble finding a register to use for manipulating numbers or jumping into functions, mainly my delay function. Then I realized that r[0] could easily pull double duty if I restore it before return from the function. That requires just 2 instructions. 200, 800.

As I was adding functions I was having to go back and update the sections of code that would jump into the function. The addresses would move around a little as I was altering functionality. So, I decided to do 2 things. Store the addresses to the functions in RAM, (At early points, mem[1..9]), And to use an enum to automatically append the function at the next address. The code became much easier to maintain and... The functions now had a LOT more overhead. Before, I could put 7 instructions in a 9 instruction block. Only 2 instructions for overhead. One for maintaining the IP and one for the return instruction. Afterwards, 9 instructions make up an empty function with 0 instruction space to actually do anything. So, that is minimum of 10, NOT 9 instructions of overhead. Remember, I am maintaining an IP using only addition for offsets. 399 just to have an empty function, Meaning I can't just increase that last digit. I have to use another instruction just to give me some room for code. So the smallest function has room for 8 instructions. 399 is one instruction leaving you the remaining 8.

I found it easiest to maintain the IP's if I coded in sections that were multiples of 10. (Reminds me of the old BASIC programming days. 10 print "Hello "; 20 goto 10). A section of 10 has 8 usable instructions with 2 for overhead 391 399. A section of 20 allows for 1 more instruction, 17 instead of 16. (Instead of 391 399 391 399, you have 392 399 399.) The size starts to get easy to spot if you use the convention of using the smaller number first. 391 399 = 10. Notice the 1=10. And 392 399 399 = 20.

The IP points that double as jump points are easy to spot when at 10 base boundaries. 1, 11, 21, 31. Just look for that last digit. After a bit I was able to use multiples of 5 easily enough, 1, 11, 26, 36, 51. The last digit is a 1 or 6.

Maintaining an IP at r[9] works great for commenting code. I can start a comment section of 10 lines with 391 399 099, Those 3 instructions are the only ones that will be executed. The 099 Jumps past the other 7. Thus allowing you to have sections of code for comments without a major slow down. I could have a really large section with 393 399 399 399 099. That is 5 lines of execution followed by 25 lines of any valid code that will be completely ignored or skipped. HINT: repeated codes are more visible, ignored or not.

There are plenty of NOP's from which to choose. such as, 3x0 4x1 5xx, where x is any digit. I decided to go with 511 in most cases because the 11's are skinny and easy spot. In areas where I may be tweaking the code I might use a 4x1 or 3x0. I might change the 3x0 to a 3x3 or the 4x1 to a 4x2 or 4x4. Interpreter wise, I'm not sure which opcode would be faster and that may depend on which one of the many interpreters you choose to use.

new topic     » goto parent     » topic index » view message » categorize

37. Re: Contest #2... Example Programs

File: message.ex

#!/usr/bin/eui 
include std/text.e 
include get.e 
 
with trace 
constant VALIDS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " 
 
function purify(sequence msg) 
	integer rp, vcp 
	sequence temp, result 
 
	temp = upper(msg) 
	result = temp 
	rp = 1 -- Result Pointer 
 
	for A = 1 to length(temp) do 
		vcp = find(temp[A], VALIDS) 
		if vcp then 
			result[rp] = temp[A] 
			rp += 1 
		end if 
	end for 
 
	return result[1..rp-1] 
end function 
 
function convert(sequence msg) 
	integer rp, vcp 
	sequence result 
 
	result = msg 
	rp = 1 -- Result Pointer 
 
	for A = 1 to length(result) do 
		vcp = find(result[A], VALIDS) 
		if vcp then 
			result[rp] = {} 
			while (vcp > 9) do 
				result[rp] &= 9 
				vcp -= 9 
			end while 
			result[rp] &= vcp 
			rp += 1 
		end if 
	end for 
 
	return result[1..rp-1] 
end function 
 
integer fp 
integer comments 
sequence YesNo, msg, cmsg 
 
fp = open("message.txt", "w") 
comments = 0 
YesNo = "YyNn"  
 
puts(1, "\tYour message code will be output to message.txt\n") 
puts(1, "\tMax Message length is 989\n\n") 
puts(1, "\t  Longer codes can be generated\n") 
puts(1, "\t  And will crash the cpu program\n") 
puts(1, "\tDo you want to output code Comments? [Y/n]") 
while (0 = find(comments, YesNo)) do 
	comments = wait_key() 
	if find(comments, "\r\n") then 
		comments = 'Y' 
	end if 
end while 
if comments = 'Y'  or comments = 'y' then 
	puts(1, " Yes\n") 
else 
	puts(1, " No\n") 
end if 
puts(1, "\n") 
puts(1, "Message: ") 
msg = gets(0) 
msg = purify(msg) 
cmsg = convert(msg) 
puts(1, "\n") 
 
if comments = 'Y' then 
	if (40 > length(msg)) then 
		printf (fp, "391 ; %s\n", {34 & msg & 34}) 
	end if 
	printf(fp, "39%d ;       --==[ Letter START ]==-\n", length(cmsg[1]) + 3) 
	puts(fp, "321 ; MP += 1\n") 
	printf(fp, "21%d ; %s (Letter goes here)\n", {cmsg[1][1], msg[1]}) 
	for B = 2 to length(cmsg[1]) do 
		printf(fp, "31%d\n", cmsg[1][B]) 
	end for 
	puts(fp, "912 ; [PUSH] --==[ Letter END ]==-\n") 
else 
	printf(fp, "39%d\n", length(cmsg) + 3) 
	puts(fp, "321\n") 
	printf(fp, "215\n", cmsg[1][1]) 
	for B = 2 to length(cmsg[1]) do 
		printf(fp, "31%d\n", cmsg[1][B]) 
	end for 
	puts(fp, "912\n") 
end if 
for A = 2 to length(msg) do 
	if comments = 'Y' then 
		printf(fp, "39%d ; --==[ Letter START ]==-\n", length(cmsg[A]) + 3) 
		puts(fp, "321 ; MP += 1\n") 
		printf(fp, "21%d ; %s (Letter)\n", {cmsg[A][1], msg[A]}) 
		for B = 2 to length(cmsg[A]) do 
			printf(fp, "31%d\n", cmsg[A][B]) 
		end for 
		puts(fp, "912 ; [PUSH]\n") 
	else 
		printf(fp, "39%d\n", length(cmsg) + 3) 
		puts(fp, "321\n") 
		printf(fp, "215\n", cmsg[A][1]) 
		for B = 2 to length(cmsg[A]) do 
			printf(fp, "31%d\n", cmsg[A][B]) 
		end for 
		puts(fp, "912\n") 
	end if 
end for 
close(fp) 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu