|
72 | 72 | set mark_ram_id 0 |
73 | 73 | draw clear 0 0 0 |
74 | 74 |
|
| 75 | + read MEMORY_X CPU "MEMORY_X" |
| 76 | + read MEMORY_Y CPU "MEMORY_Y" |
| 77 | + read MEMORY_WIDTH CPU "MEMORY_WIDTH" |
| 78 | + |
| 79 | + read ROM_SIZE CPU "ROM_SIZE" |
| 80 | + read ROM_START CPU "ROM_START" |
| 81 | + read ROM_END CPU "ROM_END" |
| 82 | + |
| 83 | + read RAM_START CPU "RAM_START" |
| 84 | + read RAM_END CPU "RAM_END" |
| 85 | + |
| 86 | + read MEMORY_END CPU "MEMORY_END" |
| 87 | + |
| 88 | + op mul ICACHE_SIZE ROM_SIZE 4 |
| 89 | + set ICACHE_START RAM_END |
| 90 | + op add ICACHE_END ICACHE_START ICACHE_SIZE |
| 91 | + |
75 | 92 | read x0_zero REGISTERS 0 |
76 | 93 | read x1_ra REGISTERS 1 |
77 | 94 | read x2_sp REGISTERS 2 |
@@ -128,26 +145,16 @@ loop: |
128 | 145 | read arg2 CPU "arg2" |
129 | 146 | read arg3 CPU "arg3" |
130 | 147 |
|
| 148 | + set address pc |
| 149 | + op add ret @counter 1 |
| 150 | + jump load_word always |
| 151 | + set instruction result |
| 152 | + |
131 | 153 | read __etext CPU "__etext" |
132 | 154 | read decode_time CPU "decode_duration" |
133 | 155 | op floor decode_time decode_time |
134 | 156 | read reservation_set CPU "reservation_set" |
135 | 157 |
|
136 | | - read MEMORY_X CPU "MEMORY_X" |
137 | | - read MEMORY_Y CPU "MEMORY_Y" |
138 | | - read MEMORY_WIDTH CPU "MEMORY_WIDTH" |
139 | | - |
140 | | - read ROM_SIZE CPU "ROM_SIZE" |
141 | | - read ROM_START CPU "ROM_START" |
142 | | - read ROM_END CPU "ROM_END" |
143 | | - |
144 | | - read RAM_START CPU "RAM_START" |
145 | | - read RAM_END CPU "RAM_END" |
146 | | - |
147 | | - op mul ICACHE_SIZE ROM_SIZE 4 |
148 | | - set ICACHE_START RAM_END |
149 | | - op add ICACHE_END ICACHE_START ICACHE_SIZE |
150 | | - |
151 | 158 | print "ROM_START\n{0}" |
152 | 159 | set address ROM_START |
153 | 160 | op add ret @counter 1 |
@@ -347,9 +354,14 @@ loop: |
347 | 354 | print "time = {0}\n" |
348 | 355 | format time |
349 | 356 |
|
350 | | - print "instret = {0}\n" |
| 357 | + print "instret = {0}\n\n" |
351 | 358 | format instret |
352 | 359 |
|
| 360 | + print "instruction = {0}\n" |
| 361 | + set n instruction |
| 362 | + op add ret @counter 1 |
| 363 | + jump format_bin always |
| 364 | + |
353 | 365 | draw print 7 300 topLeft |
354 | 366 | drawflush DISPLAY |
355 | 367 |
|
@@ -395,7 +407,7 @@ loop: |
395 | 407 | draw print 256 508 topLeft |
396 | 408 | drawflush DISPLAY |
397 | 409 |
|
398 | | - wait 0.025 |
| 410 | + wait 0.03 |
399 | 411 | jump loop always |
400 | 412 |
|
401 | 413 | format_hex: |
@@ -583,3 +595,83 @@ mark_ram: |
583 | 595 |
|
584 | 596 | op add mark_ram_id mark_ram_id 1 |
585 | 597 | set @counter mark_ram__ret |
| 598 | + |
| 599 | +# helper function to find the ram proc and variable for a given address |
| 600 | +# address -> ram, variable |
| 601 | +access_ram: |
| 602 | + # we store 4 bytes in each value |
| 603 | + op idiv _address address 4 |
| 604 | + |
| 605 | +# access_ram_raw: |
| 606 | + # get the ram proc containing this address |
| 607 | + op idiv _ram_index _address MEMORY_PROC_SIZE |
| 608 | + |
| 609 | + op mod _ram_x _ram_index MEMORY_WIDTH |
| 610 | + op add _ram_x _ram_x MEMORY_X |
| 611 | + |
| 612 | + op idiv _ram_y _ram_index MEMORY_WIDTH |
| 613 | + op add _ram_y _ram_y MEMORY_Y |
| 614 | + |
| 615 | + getblock building ram _ram_x _ram_y |
| 616 | + |
| 617 | + # get the variable within the ram proc containing this address |
| 618 | + op mod _address _address MEMORY_PROC_SIZE |
| 619 | + set lookup_variable__ret access_ram__ret |
| 620 | + |
| 621 | +# given a value 0 <= _address < MEMORY_PROC_SIZE, resolve that variable in the lookup table |
| 622 | +# this must stay directly after access_ram |
| 623 | +# _address -> variable |
| 624 | +# lookup_variable: |
| 625 | + op idiv _lookup _address LOOKUP_PROC_SIZE |
| 626 | + op add _lookup _lookup LOOKUP_START |
| 627 | + getlink _lookup _lookup |
| 628 | + |
| 629 | + op mod variable _address LOOKUP_PROC_SIZE |
| 630 | + lookup block variable variable |
| 631 | + sensor variable variable @name |
| 632 | + read variable _lookup variable |
| 633 | + |
| 634 | + set @counter lookup_variable__ret |
| 635 | + |
| 636 | +# loads the word from memory that contains the specified address |
| 637 | +# address -> result |
| 638 | +load_word: |
| 639 | + jump inaccessible_load greaterThanEq address MEMORY_END |
| 640 | + |
| 641 | + # locate and read value from ram |
| 642 | + op add access_ram__ret @counter 1 |
| 643 | + jump access_ram always |
| 644 | + read value ram variable |
| 645 | + # null is coerced to 0 by swap_endianness |
| 646 | + |
| 647 | + # tail call, swap_endianness will jump to the ret value of load_word's caller |
| 648 | + |
| 649 | +# converts a little endian 32-bit number to big endian, or vice versa |
| 650 | +# https://stackoverflow.com/a/2182184 |
| 651 | +# this MUST stay directly after load_word |
| 652 | +# value -> result |
| 653 | +# swap_endianness: |
| 654 | + # byte 3 -> byte 0 |
| 655 | + op shr result value 24 |
| 656 | + op and result result 0xff |
| 657 | + |
| 658 | + # byte 1 -> byte 2 |
| 659 | + op shl _tmp value 8 |
| 660 | + op and _tmp _tmp 0xff0000 |
| 661 | + op or result result _tmp |
| 662 | + |
| 663 | + # byte 2 -> byte 1 |
| 664 | + op shr _tmp value 8 |
| 665 | + op and _tmp _tmp 0xff00 |
| 666 | + op or result result _tmp |
| 667 | + |
| 668 | + # byte 0 -> byte 3 |
| 669 | + op shl _tmp value 24 |
| 670 | + op and _tmp _tmp 0xff000000 |
| 671 | + op or result result _tmp |
| 672 | + |
| 673 | + set @counter ret |
| 674 | + |
| 675 | +inaccessible_load: |
| 676 | + set result null |
| 677 | + set @counter ret |
0 commit comments