Improve runtime
authorbylex <mbilek06@gmail.com>
Wed, 26 Mar 2025 07:26:04 +0000 (08:26 +0100)
committerbylex <mbilek06@gmail.com>
Wed, 26 Mar 2025 07:26:04 +0000 (08:26 +0100)
new instruction - force draw to screen
update test program for new instruction
split runtime into 3 modes
add live interactive debugger/disassembler

interpreter.c
opcodes.c
opcodes.h
test_gfx.s
test_pic.s

index 531d0b2cde5413d716e25e358b0b9b1f2bbd52c0..bfa72972dfd7c6bf6dbc7c49c991951ef95ad394 100644 (file)
@@ -1,10 +1,11 @@
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdint.h>
 #include <unistd.h>
 
-#include "tigr.h"
+#include "/home/bylex/software/tigr/tigr.h"
 
 #include "common.h"
 #include "opcodes.h"
@@ -130,17 +131,161 @@ void load_mem(char* file_name)
        fclose(input_file);
 }
 
+void quit()
+{
+    __fpurge(stdin);
+       printf("\nExecution halted: cause %d\n", halted_reason);
+       tigrUpdate(screen);
+       printf("Press any key to exit...\n");
+       getc(stdin);
+    exit(0);
+}
 
+void run_fast()
+{
+       while(!halted)
+       {
+               uint8_t instruction = (uint8_t)mem[current_instruction];
+               uint8_t arg1 = (uint8_t)(mem[current_instruction] >> 8);
+               uint8_t arg2 = (uint8_t)mem[current_instruction + 1];
+               uint8_t arg3 = (uint8_t)(mem[current_instruction + 1] >> 8);
+               (*opcodes[instruction]) (arg1, arg2, arg3);
+               instruction_counter++;
+               if(force_draw)
+               {
+                       tigrUpdate(screen);
+            force_draw = false;
+               }
+       }
+    quit();
+}
 
-int main(int argc, char *argv[])
+
+void run_debug()
 {
-       screen = tigrWindow(256,256, "Interpreter display", 0);
-       if(argc == 1)
+    bool run = false;
+       while(!halted)
        {
-               fprintf(stderr, "No memory file!\n");
-               exit(1);
+               uint8_t instruction = (uint8_t)mem[current_instruction];
+               uint8_t arg1 = (uint8_t)(mem[current_instruction] >> 8);
+               uint8_t arg2 = (uint8_t)mem[current_instruction + 1];
+               uint8_t arg3 = (uint8_t)(mem[current_instruction + 1] >> 8);
+        bool next = false;
+        while(!next)
+        {
+            if(breakpoints_size == 0 && run)
+            {
+                run_fast();
+            }
+            else
+            {
+                if(get_breakpoint(current_instruction))
+                {
+                    printf("Break at 0x%04x\n", current_instruction);
+                    run = false;
+                }
+                else if(run)
+                {
+                    break;
+                }
+            }
+            printf("Executing at 0x%04x; Instruction number %ld\n", current_instruction, instruction_counter);
+            printf("[S]tep | [D]isassemble | [M]odify register | Set [B]reakpoint | [U]nset breakpoint | [R]un | [Q]uit\n");
+            int reg = -1;
+            int addr = -1;
+            char c;
+            c = getc(stdin);
+            while(c == '\n')
+            {
+                c = getc(stdin);
+            }
+            switch(c)
+            {
+                case 'd':
+                case 'D':
+                    int i = max(current_instruction - 10, 0);
+                    int upperbound = min(current_instruction + 10, 65534);
+                    while(i < upperbound)
+                    {
+                        if(i == current_instruction)
+                        {
+                            printf("\x1b[1;31m");
+                            print_instruction(i, (uint8_t)mem[i], (uint8_t)(mem[i] >> 8), (uint8_t)mem[i + 1], (uint8_t)(mem[i + 1] >> 8));
+                            printf("\x1b[0;0m");
+                        }
+                        else if(i == current_instruction + 2)
+                        {
+                            printf("\x1b[1;32m");
+                            print_instruction(i, (uint8_t)mem[i], (uint8_t)(mem[i] >> 8), (uint8_t)mem[i + 1], (uint8_t)(mem[i + 1] >> 8));
+                            printf("\x1b[0;0m");
+
+                        }
+                        else
+                        {
+                            print_instruction(i, (uint8_t)mem[i], (uint8_t)(mem[i] >> 8), (uint8_t)mem[i + 1], (uint8_t)(mem[i + 1] >> 8));
+                        }
+                        i += 2;
+                    }
+                    break;
+                case 'm':
+                case 'M':
+                    printf("Which register? ");
+                    fflush(stdout);
+                    scanf("%d", &reg);
+                    if (reg >= 0 && reg <= 255)
+                    {
+                        printf("Value to set(current value: %d)? ", regs[reg]);
+                        fflush(stdout);
+                        uint16_t val = 0;
+                        scanf("%d", &val);
+                        regs[reg] = val;
+                        printf("OK regs[%d] = %d\n", reg, val);
+
+                    }
+                    else
+                    {
+                        printf("Invalid register\n");
+                    }
+                    break;
+                case 'q':
+                case 'Q':
+                    halted_reason = 255;
+                    quit();
+                    break;
+                case 's':
+                case 'S':
+                    next = true;
+                    break;
+                case 'b':
+                case 'B':
+                    printf("What address? ");
+                    fflush(stdout);
+                    scanf("%d", &addr);
+                    set_breakpoint(addr);
+                    break;
+                case 'u':
+                case 'U':
+                    printf("What address? ");
+                    fflush(stdout);
+                    scanf("%d", &addr);
+                    del_breakpoint(addr);
+                    break;
+                case 'r':
+                case 'R':
+                    run = true;
+                    break;
+            }
+        }
+               (*opcodes[instruction]) (arg1, arg2, arg3);
+               instruction_counter++;
+               tigrUpdate(screen);
+
        }
-       load_mem(argv[1]);
+    quit();
+}
+
+void run_info()
+{
        while(!halted)
        {
                uint8_t instruction = (uint8_t)mem[current_instruction];
@@ -151,19 +296,38 @@ int main(int argc, char *argv[])
                fflush(stdout);
                (*opcodes[instruction]) (arg1, arg2, arg3);
                instruction_counter++;
-#ifndef DEBUG
-               if(instruction_counter % 1024 == 0)
+               if(force_draw)
                {
                        tigrUpdate(screen);
+            force_draw = false;
                }
-#else
-               tigrUpdate(screen);
-#endif
+    }
+    quit();
+}
 
+int main(int argc, char *argv[])
+{
+       screen = tigrWindow(256,256, "Interpreter display", 0);
+       if(argc == 1)
+       {
+               fprintf(stderr, "No memory file!\n");
+               exit(1);
        }
-       printf("\nExecution halted: cause %d\n", halted_reason);
-       tigrUpdate(screen);
-       printf("Press any key to exit...");
-       getc(stdin);
-
+       load_mem(argv[1]);
+    if(argc == 2)
+    {
+        run_fast();
+    }
+    else if(strcmp(argv[2], "--debug") == 0)
+    {
+        run_debug();
+    }
+    else if(strcmp(argv[2], "--info") == 0)
+    {
+        run_info();
+    }
+    else
+    {
+        run_info();
+    }
 }
index e957bb5662a9a947f5e3ab6f72ec3ff847bc128e..988fc9e7ff2af0abe2c57324ad84094d92ac6d56 100644 (file)
--- a/opcodes.c
+++ b/opcodes.c
@@ -14,6 +14,7 @@ extern bool halted;                // is the execution halted?
 extern uint8_t halted_reason;
 
 extern Tigr* screen;
+extern bool force_draw;
 
 void nop(uint8_t unused_1, uint8_t unused_2, uint8_t unused_3)
 {
@@ -151,3 +152,11 @@ void lor(uint8_t dest_reg, uint8_t unused_1, uint8_t mem_addr_reg)
        return;
 }
 
+void fdr(uint8_t unused_1, uint8_t unused_2, uint8_t unused_3)
+{
+       force_draw = true;
+    current_instruction += 2;
+       return;
+}
+
+void (*opcodes[N_INSTRUCTIONS]) (uint8_t, uint8_t, uint8_t) = {nop, inc, dec, lod, ldl, sav, swp, jmp, jez, hlt, pts, pfs, dpx, lor, fdr};
index 4f636aef331cb3b865e4bc9fbe862160a3283996..9560d810d82bb8e261049c2ecb7aaa156b2d5235 100644 (file)
--- a/opcodes.h
+++ b/opcodes.h
@@ -29,6 +29,7 @@
  * dpx, 4 byte length - instruction + register with pixel location + register with R and G + register with B and A(R and B are first 8 bits, G and A are second 8 bits)
  *
  * lor, 3 byte length - instruction + dest register + register containing address where to load from
+ * fdr, 1 byte length - flush output to screen
  *
  * all instructions are padded to 4 bytes
  */
index 061d654b033be81b1c2dc35ba22658a22881a419..d199951d3c6da2a4f213c92a9ad23408947df24d 100644 (file)
@@ -1,4 +1,4 @@
-ldl 0 0
+ldl 0 65535
 ldl 1 1
 ldl 2 0
 ldl 3 255
@@ -7,5 +7,9 @@ $LOOP_INF
 dpx 0 2 3
 inc 2 4
 inc 3 1
-inc 0 1
+dec 0 1
+jez 0 $END
 jmp $LOOP_INF
+$END
+fdr
+hlt
index 2c8b147c2684e95a06f6c20907daa812e9a44211..038a5fb30c60b4209ec9657c7100d9672cf53c06 100644 (file)
@@ -14,4 +14,5 @@ dec 0 2
 jez 0 $END
 jmp $LOOP
 $END
+fdr
 hlt