Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
2.1KB

  1. #include <stdint.h>
  2. #include <stdbool.h>
  3. #define SP_ADDR 0xffff
  4. #define RS_ADDR 0xff00
  5. #define SYSVARS RS_ADDR-0xb0
  6. #define MEMSIZE 0x10000
  7. typedef uint8_t byte;
  8. typedef uint16_t word;
  9. // Native words in this C Forth VMs are indexed in an array. The word in memory
  10. // is the typical 0x00 to indicate native, followed by an index byte. The
  11. // Execute routine will then know which native word to execute.
  12. typedef void (*NativeWord) ();
  13. typedef byte (*IORD) ();
  14. typedef void (*IOWR) (byte data);
  15. typedef struct {
  16. byte mem[MEMSIZE];
  17. word SP; // parameter Stack Pointer
  18. word RS; // Return Stack pointer
  19. word IP; // Interpreter Pointer
  20. // A list of native words' code. This is filled in VM_init() by calls to
  21. // native(). The order is very important because we refer to these elements
  22. // by index. For example, "0x42 CODE FOO" in Forth creates the native word
  23. // FOO which, when executed, will call the code at index 0x42 in this array.
  24. NativeWord nativew[0x100];
  25. byte nativew_count;
  26. // Array of 0x100 function pointers to IO read and write routines. Leave to
  27. // NULL when IO port is unhandled.
  28. IORD iord[0x100];
  29. IOWR iowr[0x100];
  30. // Used for keeping track of max RS and min SP during the lifetime of the
  31. // program. Useful for debugging.
  32. word maxRS;
  33. word minSP;
  34. bool running;
  35. // Whether we're in stack underflow situation. Alters the behavior of some
  36. // core action, notably popping. Doesn't stay set for more than a single
  37. // execute cycle. The goal is to avoid over-popping in native words that
  38. // pop more than once and thus corrupt memory.
  39. bool uflw;
  40. // Same as uflw, but for stack overflow. However, we behave differently with
  41. // oflw than with uflw. We can't prevent push() and pushRS() because it
  42. // would prevent us from calling (oflw). Instead, we clear both stacks on
  43. // oflw conditions, which gives us the room to maneuver.
  44. bool oflw;
  45. } VM;
  46. VM* VM_init(char *bin_path, char *blkfs_path);
  47. void VM_deinit();
  48. bool VM_steps(int n);
  49. void VM_memdump();
  50. void VM_debugstr(char *s);
  51. void VM_printdbg();