Alternative library and kernel for add-in development on fx-9860G and fx-CG50 under Linux.
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.

136 lines

  1. //---
  2. // gint - An alternative runtime environment for fx9860g and fxcg50
  3. //---
  4. #ifndef GINT_GINT
  5. #define GINT_GINT
  6. #include <gint/defs/types.h>
  7. /* GINT_VERSION - the library version number
  8. gint is versioned from its repository commits on the master branch. The
  9. GINT_VERSION integer contains the short commit hash.
  10. For instance, 0x03f7c0a0 means commit 3f7c0a0. */
  11. extern char GINT_VERSION;
  12. #define GINT_VERSION ((uint32_t)&GINT_VERSION)
  13. //---
  14. // Library management
  15. //---
  16. /* gint_install() - install and start gint
  17. This function installs event handlers, masks interrupts and switches VBR.
  18. Unless you are doing experimental runtime switching and you know how this
  19. function is implemented, you should not call it. */
  20. void gint_install(void);
  21. /* gint_unload() - unload gint and give back control to the system
  22. This function restores the runtime environment saved by gint_install(). It
  23. is only called when the add-in terminates. To temporarily leave gint during
  24. execution, use gint_switch(). When possible, use syscalls without leaving
  25. gint for better performance. */
  26. void gint_unload(void);
  27. /* gint_switch() - temporarily switch out of gint
  28. This function can be used to leave gint, restore the system's driver
  29. context, and execute code there before returning to gint. By doing this one
  30. can effectively interleave gint with the standard OS execution. The
  31. limitations are quite extreme though, so unless you know precisely why
  32. you're calling this function, you're likely doing it wrong.
  33. This switch is used to get back to the main menu and to answer TLB misses.
  34. To go back to the menu, use getkey(), or getkey_opt() with the GETKEY_MENU
  35. flag set, or call gint_osmenu() for an immediate return.
  36. @function Function to call in OS mode */
  37. void gint_switch(void (*function)(void));
  38. /* gint_osmenu() - switch out of gint and call the calculator's main menu
  39. This function safely invokes the calculator's main menu by unloading gint.
  40. If the user selects the gint application again in the menu, this function
  41. reloads gint and returns. Otherwise, the add-in is fully unloaded by the
  42. system and the application terminates.
  43. This function is typically called when the [MENU] key is pressed during a
  44. getkey() call. */
  45. void gint_osmenu(void);
  46. //---
  47. // Public functions
  48. //---
  49. /* gint_intlevel() - configure the level of interrupts
  50. This function changes the interrupt level of the requested interrupt. Make
  51. sure you are aware of interrupt assignments to avoid breaking other code.
  52. This function is mainly used by drivers to enable the interrupts that they
  53. support.
  54. The first parameter 'intid' identifies an interrupt by its position in the
  55. sequence:
  56. IPRA & 0xf000 ; IPRA & 0x0f00 .. IPRA & 0x000f ; IPRB & 0xf000 ..
  57. For instance ID 7 refers to the low nibble of IPRB. These IDs and the range
  58. for which there are valid is heavily platform-dependent and any call to this
  59. function should be wrapped inside an MPU type check. This function will
  60. crash if the provided interrupt ID is invalid.
  61. The interrupt level should be in the range 0 (disabled) .. 15 (highest
  62. priority).
  63. @intid Interrupt ID of the targeted interrupt
  64. @level Requested interrupt level
  65. Returns the interrupt level that was assigned before the call. */
  66. int gint_intlevel(int intid, int level);
  67. /* gint_inthandler() - configure interrupt handlers
  68. This function installs (copies) interrupt handlers in the VBR space of the
  69. application. Each handler is a 32-byte block aligned on a 32-byte boundary.
  70. When an interrupt request is accepted, the hardware jumps to a specific
  71. interrupt handler at an address that depends on the interrupt source.
  72. For safety, interrupt handlers should avoid referring to data from other
  73. blocks because the arrangement of blocks at runtime depends on event codes.
  74. The assembler program will assume that consecutive blocks in the source code
  75. will be consecutive in memory, which is not always true. Avoiding cross-
  76. references is a practical rule to avoid problems. (gint breaks this rule
  77. very often but does it carefully... I guess?)
  78. This function allows anyone to replace any interrupt handler so make sure
  79. you're not interfering with usual interrupt assignments.
  80. The first parameter event_code represents the event code associated with the
  81. interrupt. If it's not a multiple of 0x20 then you're doing something wrong.
  82. The codes are normally platform-dependent, but gint always uses SH7305
  83. codes: SH3 platforms have a translation table. See the documentation for a
  84. list of event codes and their associated interrupts.
  85. The handler function must be an interrupt handler: it must not raise
  86. exceptions, must end with 'rts', and it will use the kernel register bank.
  87. You read that right, it must end with rts because gint's main handler saves
  88. registers besides the automated r0..r7. Do *not* use 'rte' in the handler.
  89. For convenience I allow any block size to be loaded as an interrupt handler,
  90. but it should really be a multiple of 0x20 bytes and not override other
  91. handlers. If it's not written in assembler, then you're likely doing
  92. something wrong, especially with __attribute__((interrupt_handler)) which
  93. uses rte.
  94. It is common for interrupt handlers to have a few bytes of data, such as the
  95. address of a callback function. gint often stores this data in the last
  96. bytes of the block. This function returns the VBR address of the block which
  97. has just been installed, to allow the caller to edit the parameters later.
  98. @event_code Identifier of the interrupt block
  99. @handler Address of handler function
  100. @size How many bytes to copy
  101. Returns the VBR address where the handlers was installed. */
  102. void *gint_inthandler(int event_code, void const *handler, size_t size);
  103. #endif /* GINT_GINT */