sys.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /**
  2. * Contains system functions for user programs
  3. * Contains code for system calls and interrupt handling
  4. */
  5. // Interrupt IDs for interrupt handler
  6. #define INTID_TIMER1 0x1
  7. #define INTID_TIMER2 0x2
  8. #define INTID_UART0 0x3
  9. #define INTID_GPU 0x4
  10. #define INTID_TIMER3 0x5
  11. #define INTID_PS2 0x6
  12. #define INTID_UART1 0x7
  13. #define INTID_UART2 0x8
  14. #define SYSCALL_RETVAL_ADDR 0x200000
  15. // System call IDs
  16. #define SYS_HID_CHECKFIFO 1
  17. #define SYS_HID_READFIFO 2
  18. #define SYS_BDOS_PRINTC 3
  19. #define SYS_BDOS_PRINT 4
  20. #define SYS_FS_OPEN 5
  21. #define SYS_FS_CLOSE 6
  22. #define SYS_FS_READ 7
  23. #define SYS_FS_WRITE 8
  24. #define SYS_FS_SETCURSOR 9
  25. #define SYS_FS_GETCURSOR 10
  26. #define SYS_FS_DELETE 11
  27. #define SYS_FS_MKDIR 12
  28. #define SYS_FS_MKFILE 13
  29. #define SYS_FS_STAT 14
  30. #define SYS_FS_READDIR 15
  31. #define SYS_FS_GETCWD 16
  32. #define SYS_FS_SYNCFLASH 17
  33. // Syscalls 18-19 are reserved for future use
  34. #define SYS_SHELL_ARGC 20
  35. #define SYS_SHELL_ARGV 21
  36. #define SYS_USB_KB_BUF 99
  37. /**
  38. * Returns the interrupt ID
  39. */
  40. word get_int_id()
  41. {
  42. word retval = 0;
  43. asm(
  44. "readintid r2 ;reads interrupt id to r2\n"
  45. "write -4 r14 r2 ;write to stack to return\n"
  46. );
  47. return retval;
  48. }
  49. /**
  50. * Executes system call to BDOS
  51. * Argument specifies the system call ID
  52. * Returns the address of the return value
  53. */
  54. word* syscall(word ID)
  55. {
  56. word* p = (word*) SYSCALL_RETVAL_ADDR;
  57. *p = ID;
  58. asm("push r1\n"
  59. "push r2\n"
  60. "push r3\n"
  61. "push r4\n"
  62. "push r5\n"
  63. "push r6\n"
  64. "push r7\n"
  65. "push r8\n"
  66. "push r9\n"
  67. "push r10\n"
  68. "push r11\n"
  69. "push r12\n"
  70. "push r13\n"
  71. "push r14\n"
  72. "push r15\n"
  73. "savpc r1\n"
  74. "push r1\n"
  75. "jump 4\n"
  76. "pop r15\n"
  77. "pop r14\n"
  78. "pop r13\n"
  79. "pop r12\n"
  80. "pop r11\n"
  81. "pop r10\n"
  82. "pop r9\n"
  83. "pop r8\n"
  84. "pop r7\n"
  85. "pop r6\n"
  86. "pop r5\n"
  87. "pop r4\n"
  88. "pop r3\n"
  89. "pop r2\n"
  90. "pop r1\n");
  91. return p;
  92. }
  93. /**
  94. * Exits the user program and returns to BDOS in a somewhat controlled way
  95. */
  96. void exit(word n)
  97. {
  98. asm("ccache\n");
  99. asm("jump Return_BDOS\n");
  100. }
  101. /**
  102. * Returns 1 if the HID buffer is not empty
  103. */
  104. word hid_checkfifo()
  105. {
  106. char* p = (char*) SYSCALL_RETVAL_ADDR;
  107. syscall(SYS_HID_CHECKFIFO);
  108. return p[0];
  109. }
  110. /**
  111. * Reads a character from the HID buffer
  112. */
  113. word hid_fiforead()
  114. {
  115. char* p = (char*) SYSCALL_RETVAL_ADDR;
  116. syscall(SYS_HID_READFIFO);
  117. return p[0];
  118. }
  119. /**
  120. * Prints a character on the BDOS console
  121. */
  122. void bdos_printc(char c)
  123. {
  124. char* p = (char*) SYSCALL_RETVAL_ADDR;
  125. p[1] = c;
  126. syscall(SYS_BDOS_PRINTC);
  127. }
  128. /**
  129. * Prints a string on the BDOS console
  130. */
  131. void bdos_print(char* c)
  132. {
  133. char* p = (char*) SYSCALL_RETVAL_ADDR;
  134. p[1] = (char)c;
  135. syscall(SYS_BDOS_PRINT);
  136. }
  137. /**
  138. * Prints a string with newline on the BDOS console
  139. */
  140. void bdos_println(char* str)
  141. {
  142. bdos_print(str);
  143. bdos_printc('\n');
  144. }
  145. /**
  146. * Prints a decimal on the BDOS console
  147. */
  148. void bdos_printdec(word i)
  149. {
  150. char buffer[12];
  151. if (i < 0)
  152. {
  153. buffer[0] = '-';
  154. itoa(MATH_abs(i), &buffer[1]);
  155. }
  156. else
  157. {
  158. itoa(i, buffer);
  159. }
  160. bdos_print(buffer);
  161. }
  162. /**
  163. * Prints a decimal with newline on the BDOS console
  164. */
  165. void bdos_printdecln(word i)
  166. {
  167. bdos_printdec(i);
  168. bdos_printc('\n');
  169. }
  170. /**
  171. * Prints a hexadecimal on the BDOS console
  172. */
  173. void bdos_printhex(word i)
  174. {
  175. char buffer[11];
  176. itoah(i, buffer);
  177. bdos_print(buffer);
  178. }
  179. /**
  180. * Opens a file in the filesystem
  181. */
  182. word fs_open(char* filename)
  183. {
  184. char* p = (char*) SYSCALL_RETVAL_ADDR;
  185. p[1] = (char) filename;
  186. syscall(SYS_FS_OPEN);
  187. return p[0];
  188. }
  189. /**
  190. * Closes a file in the filesystem
  191. */
  192. word fs_close(word fp)
  193. {
  194. char* p = (char*) SYSCALL_RETVAL_ADDR;
  195. p[1] = fp;
  196. syscall(SYS_FS_CLOSE);
  197. return p[0];
  198. }
  199. /**
  200. * Reads from a file in the filesystem
  201. */
  202. word fs_read(word fp, char* buffer, word len)
  203. {
  204. char* p = (char*) SYSCALL_RETVAL_ADDR;
  205. p[1] = fp;
  206. p[2] = (char) buffer;
  207. p[3] = len;
  208. syscall(SYS_FS_READ);
  209. return p[0];
  210. }
  211. /**
  212. * Writes to a file in the filesystem
  213. */
  214. word fs_write(word fp, char* buffer, word len)
  215. {
  216. char* p = (char*) SYSCALL_RETVAL_ADDR;
  217. p[1] = fp;
  218. p[2] = (char) buffer;
  219. p[3] = len;
  220. syscall(SYS_FS_WRITE);
  221. return p[0];
  222. }
  223. /**
  224. * Sets the cursor position in the filesystem
  225. */
  226. word fs_setcursor(word fp, word pos)
  227. {
  228. char* p = (char*) SYSCALL_RETVAL_ADDR;
  229. p[1] = fp;
  230. p[2] = pos;
  231. syscall(SYS_FS_SETCURSOR);
  232. return p[0];
  233. }
  234. /**
  235. * Gets the cursor position in the filesystem
  236. */
  237. word fs_getcursor(word fp)
  238. {
  239. char* p = (char*) SYSCALL_RETVAL_ADDR;
  240. p[1] = fp;
  241. syscall(SYS_FS_GETCURSOR);
  242. return p[0];
  243. }
  244. /**
  245. * Deletes a file in the filesystem
  246. */
  247. word fs_delete(char* filename)
  248. {
  249. char* p = (char*) SYSCALL_RETVAL_ADDR;
  250. p[1] = (char) filename;
  251. syscall(SYS_FS_DELETE);
  252. return p[0];
  253. }
  254. /**
  255. * Creates a directory in the filesystem
  256. */
  257. word fs_mkdir(char* dirname)
  258. {
  259. char* p = (char*) SYSCALL_RETVAL_ADDR;
  260. p[1] = (char) dirname;
  261. syscall(SYS_FS_MKDIR);
  262. return p[0];
  263. }
  264. /**
  265. * Creates a file in the filesystem
  266. */
  267. word fs_mkfile(char* filename)
  268. {
  269. char* p = (char*) SYSCALL_RETVAL_ADDR;
  270. p[1] = (char) filename;
  271. syscall(SYS_FS_MKFILE);
  272. return p[0];
  273. }
  274. /**
  275. * Gets the status of a file in the filesystem
  276. */
  277. word fs_stat(char* filename)
  278. {
  279. char* p = (char*) SYSCALL_RETVAL_ADDR;
  280. p[1] = (char) filename;
  281. syscall(SYS_FS_STAT);
  282. return p[0];
  283. }
  284. /**
  285. * Lists the contents of a directory in the filesystem
  286. * Returns the number of entries in the directory
  287. */
  288. word fs_readdir(char* dirname, char* buffer)
  289. {
  290. char* p = (char*) SYSCALL_RETVAL_ADDR;
  291. p[1] = (char) dirname;
  292. p[2] = (char) buffer;
  293. syscall(SYS_FS_READDIR);
  294. return p[0];
  295. }
  296. /**
  297. * Gets the current working directory in the filesystem
  298. * Note: The pointer returned is only valid until the next syscall
  299. */
  300. char* fs_getcwd()
  301. {
  302. char* p = (char*) SYSCALL_RETVAL_ADDR;
  303. syscall(SYS_FS_GETCWD);
  304. return p;
  305. }
  306. /**
  307. * Synchronizes the filesystem with the flash memory
  308. */
  309. word fs_syncflash()
  310. {
  311. char* p = (char*) SYSCALL_RETVAL_ADDR;
  312. syscall(SYS_FS_SYNCFLASH);
  313. return p[0];
  314. }
  315. /**
  316. * Returns the number of command line arguments
  317. */
  318. word shell_argc()
  319. {
  320. char* p = (char*) SYSCALL_RETVAL_ADDR;
  321. syscall(SYS_SHELL_ARGC);
  322. return p[0];
  323. }
  324. /**
  325. * Returns the command line arguments
  326. * Note: The pointer returned is only valid until the next syscall
  327. */
  328. char* shell_argv()
  329. {
  330. char* p = (char*) SYSCALL_RETVAL_ADDR;
  331. syscall(SYS_SHELL_ARGV);
  332. return p;
  333. }
  334. /**
  335. * Returns 1 if key is being held on USB keyboard
  336. */
  337. word bdos_usbkey_held(word c)
  338. {
  339. char* p = (char*) SYSCALL_RETVAL_ADDR;
  340. syscall(SYS_USB_KB_BUF);
  341. word* usbKeyBuffer = (char*) p[0];
  342. word i;
  343. for (i = 0; i < 8; i++)
  344. {
  345. if (usbKeyBuffer[i] == c)
  346. {
  347. return 1;
  348. }
  349. }
  350. return 0;
  351. }