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.

README.md 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. # User applications
  2. This folder contains code designed to be "userspace" application. Unlike the
  3. kernel, which always stay in memory. Those apps here will more likely be loaded
  4. in RAM from storage, ran, then discarded so that another userspace program can
  5. be run.
  6. That doesn't mean that you can't include that code in your kernel though, but
  7. you will typically not want to do that.
  8. ## Userspace convention
  9. We execute a userspace application by calling the address it's loaded into.
  10. This means that userspace applications must be assembled with a proper `.org`,
  11. otherwise labels in its code will be wrong.
  12. The `.org`, it is not specified by glue code of the apps themselves. It is
  13. expected to be set either in the `user.h` file to through `zasm` 3rd argument.
  14. That a userspace is called also means that an application, when finished
  15. running, is expected to return with a regular `ret` and a clean stack.
  16. Whatever calls the userspace app (usually, it will be the shell), should set
  17. HL to a pointer to unparsed arguments in string form, null terminated.
  18. The userspace application is expected to set A on return. 0 means success,
  19. non-zero means error.
  20. A userspace application can expect the `SP` pointer to be properly set. If it
  21. moves it, it should take care of returning it where it was before returning
  22. because otherwise, it will break the kernel.
  23. ## Memory management
  24. Apps in Collapse OS are design to be ROM-compatible, that is, they don't write
  25. to addresses that are part of the code's address space.
  26. By default, apps set their RAM to begin at the end of the binary because in
  27. most cases, these apps will be ran from RAM. If they're ran from ROM, make sure
  28. to set `USER_RAMSTART` properly in your `user.h` to ensure that the RAM is
  29. placed properly.
  30. Applications that are ran as a shell (the "shell" app, of course, but also,
  31. possibly, "basic" and others to come) need a manual override to their main
  32. `RAMSTART` constant: You don't want them to run in the same RAM region as your
  33. other userspace apps because if you do, as soon as you launch an app with your
  34. shell, its memory is going to be overwritten!
  35. What you'll do then is that you'll reserve some space in your memory layout for
  36. the shell and add a special constant in your `user.h`, which will override the
  37. basic one (remember, in zasm, the first `.equ` for a given constant takes
  38. precedence).
  39. For example, if you want a "basic" shell and that you reserve space right
  40. after your kernel RAM for it, then your `user.h` would contain
  41. `.equ BAS_RAMSTART KERNEL_RAMEND`.
  42. You can also include your shell's code directly in the kernel by copying
  43. relevant parts of the app's glue unit in your kernel's glue unit. This is often
  44. simpler and more efficient. However, if your shell is a big program, it might
  45. run into zasm's limits. In that case, you'd have to assemble your shell
  46. separately.
  47. ## Common features
  48. The folder `lib/` contains code shared in more than one apps and this has the
  49. effect that some concepts are exactly the same in many application. They are
  50. therefore sharing documentation, here.
  51. ### Number literals
  52. There are decimal, hexadecimal and binary literals. A "straight" number is
  53. parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
  54. Binary must be prefixed with `0b` (`0b01100110`).
  55. Decimals and hexadecimal are "flexible". Whether they're written in a byte or
  56. a word, you don't need to prefix them with zeroes. Watch out for overflow,
  57. however.
  58. Binary literals are also "flexible" (`0b110` is fine), but can't go over a byte.
  59. There is also the char literal (`'X'`), that is, two quotes with a character in
  60. the middle. The value of that character is interpreted as-is, without any
  61. encoding involved. That is, whatever binary code is written in between those
  62. two quotes, it's what is evaluated. Only a single byte at once can be evaluated
  63. thus. There is no escaping. `'''` results in `0x27`. You can't express a newline
  64. this way, it's going to mess with the parser.
  65. ### Expressions
  66. An expression is a bunch of literals or symbols assembled by operators.
  67. Supported operators are `+`, `-`, `*`, `/`, `%` (modulo), `&` (bitwise and),
  68. `|` (bitwise or), `^` (bitwise xor), `{` (shift left), `}` (shift right).
  69. Bitwise operator always operate on the whole 16-bits.
  70. Shift operators break from the `<<` and `>>` tradition because the complexity
  71. if two-sized operator is significant and deemed not worth it. The shift
  72. operator shift the left operand X times, X being the right operand.
  73. There is no parenthesis support yet.
  74. Symbols have a different meaning depending on the application. In zasm, it's
  75. labels and constants. In basic, it's variables.
  76. Expressions can't contain spaces.
  77. Expressions can have an empty left operand. It will then be considered as 0.
  78. This allows signed integers, for example, `-42` to be expressed as expected.
  79. That form doesn't work well everywhere and is mostly supported for BASIC. In
  80. zasm, you're safer with `0-42`.