@@ -14,11 +14,14 @@ interfere with developing a native 6502 OS.
1414
1515The OS loosely follows POSIX with an Application Binary
1616Interface (ABI) similar to `cc65's fastcall
17- <https://cc65.github.io/doc/cc65-intern.html> `__. It provides stdio.h and
18- unistd.h services to both `cc65 <https://cc65.github.io >`__ and `llvm-mos
17+ <https://cc65.github.io/doc/cc65-intern.html> `__. It provides `` stdio.h `` and
18+ `` unistd.h `` services to both `cc65 <https://cc65.github.io >`__ and `llvm-mos
1919<https://llvm-mos.org/> `_ compilers. There are also calls to access RP6502
20- features and manage FAT32 filesystems. ExFAT is ready to go and will be
21- enabled when the patents expire.
20+ features and manage FAT32 filesystems.
21+
22+ .. note ::
23+
24+ ExFAT is ready to go and will be enabled when the patents expire.
2225
2326
2427Memory Map
@@ -56,6 +59,10 @@ VIA1 at $FFC0, SID0 at $FF00, and SID1 at $FF20.
5659Application Binary Interface
5760============================
5861
62+ .. seealso ::
63+
64+ :doc: `ria ` — the hardware register map referenced throughout this section.
65+
5966The ABI for calling the operating system is based on fastcall from the
6067`cc65 internals <https://cc65.github.io/doc/cc65-intern.html >`__. The
6168OS does not use or require anything from cc65 and is easy for
@@ -73,21 +80,21 @@ as a C declaration like so:
7380
7481.. c :function :: int doit (int arg0, int arg1);
7582
76- The RIA has registers called RIA_A, RIA_X, and RIA_SREG. An int is 16 bits,
77- so we set the RIA_A and RIA_X registers with arg1. I'll use "A" for the 6502
83+ The RIA has registers called `` RIA_A ``, `` RIA_X `` , and `` RIA_SREG `` . An int is 16 bits,
84+ so we set the `` RIA_A `` and `` RIA_X `` registers with arg1. I'll use "A" for the 6502
7885register and "RIA_A" for the RIA register in this explanation.
7986
80- We use the XSTACK for arg0. Reading RIA_XSTACK pops bytes; writing
87+ We use the XSTACK for arg0. Reading `` RIA_XSTACK `` pops bytes; writing
8188pushes bytes. It's a top-down stack, so push each argument left to
8289right and maintain little-endian byte order.
8390
84- To execute the call, store the operation ID in RIA_OP. The operation begins
91+ To execute the call, store the operation ID in `` RIA_OP `` . The operation begins
8592immediately. You can keep doing 6502 things, like running a loading animation, by
86- polling RIA_BUSY. Alternatively, JSR to RIA_SPIN to block.
93+ polling `` RIA_BUSY `` . Alternatively, JSR to `` RIA_SPIN `` to block.
8794
88- JSR RIA_SPIN can unblock within 3 clock cycles and immediately loads A
89- and X. Sequential operations run fastest with this technique. Under the hood, you're jumping into a self-modifying program that
90- runs on the RIA registers.
95+ `` JSR RIA_SPIN `` can unblock within 3 clock cycles and immediately loads A
96+ and X. Sequential operations run fastest with this technique. Under the hood,
97+ you're jumping into a self-modifying program that runs on the RIA registers.
9198
9299.. code-block :: asm
93100
@@ -96,10 +103,10 @@ runs on the RIA registers.
96103 LDX #$?? ; RIA_X
97104 RTS
98105
99- Polling is simply snooping on the above program. The RIA_BUSY register is
106+ Polling is simply snooping on the above program. The `` RIA_BUSY `` register is
100107the -2 or 0 in the BRA above. The RIA datasheet specifies bit 7 indicates
101108busy, which the 6502 can check quickly by using the BIT operator to set
102- flag N. Once clear, we read RIA_A and RIA_X with absolute instructions.
109+ flag N. Once clear, we read `` RIA_A `` and `` RIA_X `` with absolute instructions.
103110
104111.. code-block :: asm
105112
@@ -109,13 +116,13 @@ flag N. Once clear, we read RIA_A and RIA_X with absolute instructions.
109116 LDA RIA_A
110117 LDX RIA_X
111118
112- All operations returning RIA_A will also return RIA_X to assist with C
113- integer promotion. RIA_SREG is only updated for 32-bit returns. RIA_ERRNO
119+ All operations returning `` RIA_A `` will also return `` RIA_X `` to assist with C
120+ integer promotion. `` RIA_SREG `` is only updated for 32-bit returns. `` RIA_ERRNO ``
114121is only updated if there is an error.
115122
116123Some operations return strings or structures on the stack. You must pull the
117124entire stack before the next call. However, tail call optimizations are
118- possible. For example, you can chain read_xstack() and write_xstack() to
125+ possible. For example, you can chain `` read_xstack() `` and `` write_xstack() `` to
119126copy a file without using any RAM or XRAM.
120127
121128Short Stacking
@@ -160,7 +167,7 @@ the type and direction (to or from the OS) of this data. Let's look at some exam
160167
161168 int open(const char *path, int oflag);
162169
163- Send `oflag ` in RIA_A. RIA_X doesn't need to be set according to the
170+ Send `` oflag `` in `` RIA_A ``. `` RIA_X `` doesn't need to be set according to the
164171docs below. Send the path on XSTACK by pushing the string starting with the last
165172character. You may omit pushing the terminating zero, but strings are
166173limited to a length of 255. Calling this from the C SDK will "just work"
@@ -170,7 +177,7 @@ because there's an implementation that pushes the string for you.
170177
171178 int read_xstack(void *buf, unsigned count, int fildes)
172179
173- Send `count ` as a short stack and `fildes ` in RIA_A. RIA_X doesn't
180+ Send `` count `` as a short stack and `` fildes `` in `` RIA_A ``. `` RIA_X `` doesn't
174181need to be set according to the docs below. The returned value in AX indicates how
175182many values must be pulled from the stack. If you call this from the C SDK
176183then it will copy XSTACK to buf[] for you.
@@ -179,8 +186,8 @@ then it will copy XSTACK to buf[] for you.
179186
180187 int write_xstack(const void *buf, unsigned count, int fildes)
181188
182- Send `fildes ` in RIA_A. RIA_X doesn't need to be set according to the
183- docs below. Push the buf data to XSTACK. Do not send `count `, the OS knows this
189+ Send `` fildes `` in `` RIA_A ``. `` RIA_X `` doesn't need to be set according to the
190+ docs below. Push the buf data to XSTACK. Do not send `` count ` `, the OS knows this
184191from its internal stack pointer. If you call this from the C SDK then it
185192will copy count bytes of buf[] to XSTACK for you.
186193
@@ -199,9 +206,9 @@ going through 6502 RAM or capture a screenshot with ease.
199206 int read_xram(xram_addr buf, unsigned count, int fildes)
200207 int write_xram(xram_addr buf, unsigned count, int fildes)
201208
202- The OS expects `buf ` and `count ` on the XSTACK as integers with `filedes ` in
203- RIA_A. The OS has direct access to XRAM so internally it will use
204- something like &XRAM[buf]. You will need to use RIA_RW0 or RIA_RW1 to access
209+ The OS expects `` buf `` and `` count `` on the XSTACK as integers with `` fildes ` ` in
210+ `` RIA_A `` . The OS has direct access to XRAM so internally it will use
211+ something like `` &XRAM[buf] `` . You will need to use `` RIA_RW0 `` or `` RIA_RW1 `` to access
205212this memory from the 6502.
206213
207214These operations stand out for their high performance and ability to
@@ -216,25 +223,30 @@ paged memory.
216223Application Programmer Interface
217224================================
218225
226+ .. seealso ::
227+
228+ `FatFs documentation <https://elm-chan.org/fsw/ff/ >`__ —
229+ many of the filesystem functions below are thin wrappers around FatFs.
230+
219231Much of this API is based on POSIX and FatFs. In particular, filesystem and
220232console access should feel extremely familiar. However, some operations will
221233have a different argument order or data structures than what you're used to.
222234The reason for this becomes apparent when you start to work in assembly and
223235fine tune short stacking and integer demotions. You might not notice the
224236differences if you only work in C because the standard library has wrapper
225- functions and familiar prototypes. For example, the f_lseek() described
237+ functions and familiar prototypes. For example, the `` f_lseek() `` described
226238below has reordered arguments that are optimized for short stacking the long
227- argument. But you don't have to call f_lseek() from C, you can call the
228- usual lseek() which has the traditional argument order.
239+ argument. But you don't have to call `` f_lseek() `` from C, you can call the
240+ usual `` lseek() `` which has the traditional argument order.
229241
230242The OS is built around FAT filesystems, the de facto standard for
231243unsecured USB storage devices. POSIX filesystems are not fully
232244compatible with FAT but there is a solid intersection of basic IO that is
233- 100% compatible. You will see some familiar POSIX functions like open() and
234- others like f_stat() which are similar to the POSIX function but tailored to
235- FAT. Should it ever become necessary to have a POSIX stat(), it can be
245+ 100% compatible. You will see some familiar POSIX functions like `` open() `` and
246+ others like `` f_stat() `` which are similar to the POSIX function but tailored to
247+ FAT. Should it ever become necessary to have a POSIX `` stat() `` , it can be
236248implemented in the C standard library or in an application by translating
237- f_stat() data.
249+ `` f_stat() `` data.
238250
239251ZXSTACK
240252-------
@@ -298,7 +310,10 @@ ARGV
298310 Because this can use up to 512 bytes of RAM you must opt-in by providing storage
299311 for the argv data. You may use static memory, or dynamically allocated memory which
300312 can be freed after use. You may also reject an oversized argv by returning NULL.
301- `void *argv_mem(size_t size) { return malloc(size); } `
313+
314+ .. code-block :: c
315+
316+ void *argv_mem(size_t size) { return malloc(size); }
302317
303318 :Op code: RIA_OP_ARGV 0x08
304319 :C proto: (none)
@@ -320,14 +335,14 @@ EXEC
320335 launched ROM will see argv[0] as the filename.
321336
322337 The data sent by _exec() will be checked for pointer safety and sanity, but
323- will assume the path points to a loadable ROM file. If API_EINVAL is returned,
338+ will assume the path points to a loadable ROM file. If EINVAL is returned,
324339 the argv buffer is cleared so further attempts to _argv() will return an empty set.
325- Is the ROM is invalid, the user will be left on the console with an error message.
340+ If the ROM is invalid, the user will be left on the console with an error message.
326341
327- :Op code: RIA_OP_ARGV 0x09
342+ :Op code: RIA_OP_EXEC 0x09
328343 :C proto: rp6502.h
329- :returns: Size of argv data
330- :errno: API_EINVAL
344+ :returns: Does not return on success — the new ROM begins executing. -1 on error.
345+ :errno: EINVAL
331346
332347
333348ATTR_GET
@@ -410,7 +425,7 @@ CLOCK_GETRES
410425TZSET
411426-----
412427
413- .. c :function :: int void tzset (void);
428+ .. c :function :: void tzset (void);
414429 .. c :function :: int _tzset (struct _tzset *tz)
415430
416431 .. code-block :: c
@@ -834,11 +849,12 @@ READDIR
834849
835850 |
836851
837- Returns file or directory info for directory descriptor.
852+ Returns directory entry info for the current read position of a directory descriptor,
853+ then advances the read position.
838854
839855 :Op code: RIA_OP_READDIR 0x21
840856 :C proto: rp6502.h
841- :param path: Pathname to a directory entry .
857+ :param dirdes: Directory descriptor from f_opendir() .
842858 :param dirent: Returned f_stat_t data.
843859 :returns: 0 on success. -1 on error.
844860 :a regs: return, dirent
@@ -1049,12 +1065,12 @@ CHDRIVE
10491065
10501066 |
10511067
1052- Change current drive.
1053- "USB7:" with shortcuts "0:" to "7:" .
1068+ Change the current drive.
1069+ Valid names are ``USB0:``–``USB9:`` with shortcuts ``0:``–``9:`` .
10541070
10551071 :Op code: RIA_OP_CHDRIVE 0x2A
10561072 :C proto: rp6502.h
1057- :param name: Pathname of the directory to make .
1073+ :param name: Drive name to change to.
10581074 :returns: 0 on success. -1 on error.
10591075 :a regs: return
10601076 :errno: FR_INVALID_DRIVE
0 commit comments