doc: fix typos and inaccuracies

This commit is contained in:
Virgil Dupras 2020-09-19 09:04:18 -04:00
parent 4b1a49c8cc
commit 6d180f737a
5 changed files with 84 additions and 88 deletions

View File

@ -6,60 +6,53 @@ TODO
# Programming AVR chips # Programming AVR chips
To program AVR chips, you need a device that provides the SPI protocol. The To program AVR chips, you need a device that provides the SPI
device built in the rc2014/sdcard recipe fits the bill. Make sure you can protocol. The device built in the rc2014/sdcard recipe fits the
override the SPI clock because the system clock will be too fast for most AVR bill. Make sure you can override the SPI clock because the sys-
chips, which are usually running at 1MHz. Because the SPI clock needs to be a tem clock will be too fast for most AVR chips, which are usually
4th of that, a safe frequency for SPI communication would be 250kHz. running at 1MHz. Because the SPI clock needs to be a 4th of
that, a safe frequency for SPI communication would be 250kHz.
Because you will not be using your system clock, you'll also need to override The AVR programmer device is really simple: Wire SPI connections
SPI_DELAY in your xcomp unit: the default value for this is 2 NOP, which only to proper AVR pins as described in the MCU's datasheet. Note
works when you use the system clock. that this device will be the same as the one you'll use for any
modern SPI-based AVR programmer, with RESET replacing SS.
Alternatively, you could run your whole system at 250kHz, but that's going to be
really slow.
The AVR programmer device is really simple: Wire SPI connections to proper AVR
pins as described in the MCU's datasheet. Note that this device will be the same
as the one you'll use for any modern SPI-based AVR programmer, with RESET
replacing SS.
(TODO: design a SPI relay that supports more than one device. At the time of
this writing, one has to disconnect the SD card reader before enabling the AVR
programmer)
The AVR programming code is at B690. The AVR programming code is at B690.
Before you begin programming the chip, the device must be deselected. Ensure Before you begin programming the chip, the device must be desel-
with "(spid)". ected. Ensure with "0 (spie)".
Then, you initiate programming mode with "asp$", and then issue your commands. Then, you initiate programming mode with "asp$", and then issue
your commands.
Each command will verify that it's in sync, that is, that its 3rd exchange Each command will verify that it's in sync, that is, that its
echoes the byte that was sent in the 2nd exchange. If it doesn't, the command 3rd exchange echoes the byte that was sent in the 2nd exchange.
aborts with "AVR err". If it doesn't, the command aborts with "AVR err".
# Access fuses # Access fuses
You get/set they values with "aspfx@/aspfx!", x being one of "l" (low fuse), You get/set they values with "aspfx@/aspfx!", x being one of "l"
"h" (high fuse), "e" (extended fuse). (low fuse), "h" (high fuse), "e" (extended fuse).
# Access flash # Access flash
Writing to AVR's flash is done in batch mode, page by page. To this end, the Writing to AVR's flash is done in batch mode, page by page. To
chip has a buffer which is writable byte-by-byte. this end, the chip has a buffer which is writable byte-by-byte.
Writing to the flash begins with a call to asperase, which erases the whole Writing to the flash begins with a call to asperase, which
chip. It seems possible to erase flash page-by-page through parallel erases the whole chip. It seems possible to erase flash page-by-
programming, but the SPI protocol doesn't expose it, we have to erase the whole page through parallel programming, but the SPI protocol doesn't
chip. Then, you write to the buffer using aspfb! and then write to a page using expose it, we have to erase the whole chip. Then, you write to
aspfp!. Example to write 0x1234 to the first byte of the first page: the buffer using aspfb! and then write to a page using aspfp!.
Example to write 0x1234 to the first byte of the first page:
asperase 0x1234 0 aspfb! 0 aspfp! asperase 0x1234 0 aspfb! 0 aspfp!
Please note that aspfb! deals with *words*, not bytes. If, for example, you want Please note that aspfb! deals with *words*, not bytes. If, for
to hook it to A!*, make sure you use AMOVEW instead of AMOVE. You will need to example, you want to hook it to A!*, make sure you use AMOVEW
create a wrapper word around aspfb! that divides dst addr by 2 because AMOVEW instead of AMOVE. You will need to create a wrapper word around
use byte-based addresses but aspfb! uses word-based ones. You also have to make aspfb! that divides dst addr by 2 because AMOVEW use byte-based
sure that A@* points to @ (or another word-based fetcher) instead of its default addresses but aspfb! uses word-based ones. You also have to make
value of C@. sure that A@* points to @ (or another word-based fetcher)
instead of its default value of C@.

View File

@ -7,32 +7,32 @@ What is Collapse OS? It is a binary placed either in ROM on
in RAM by a bootloader. That binary, when executed, initializes in RAM by a bootloader. That binary, when executed, initializes
itself to a Forth interpreter. In most cases, that Forth itself to a Forth interpreter. In most cases, that Forth
interpreter will have some access to a mass storage device, interpreter will have some access to a mass storage device,
which allows it to access Collapse OS' disk blocks and come which allows it to access Collapse OS' disk blocks and bootstrap
to this block to bootstrap itself some more. itself some more.
This binary can be separated in 5 distinct layers: This binary can be separated in 5 distinct layers:
1. Boot code (B280) 1. Arch-specific boot code (B280 for Z80)
2. Boot words (B305) 2. Arch-specific boot words (B305 for Z80)
3. Core words (low) (B350) 3. Arch-independant core words (low) (B350)
4. Drivers 4. Drivers, might contain arch-specific code
5. Core words (high) 5. Arch-independant core words (high) (B380)
# Boot code (B280) # Boot code
This part contains core routines that underpins Forth fundamen- This part contains core routines that underpins Forth fundamen-
tal structures: dict navigation and search, PSP/RSP bounds tal structures: dict navigation and FIND, PSP/RSP bounds checks,
checks, word types. word types.
It also of course does core initialization: set RSP/PSP, HERE It also of course does core initialization: set RSP/PSP, HERE
CURRENT, then call BOOT. CURRENT, then call BOOT.
It also contains what we call the "stable ABI" in its first It also contains what we call the "stable ABI" in its first
0x100 bytes. The beginning og the dict is intertwined in this 0x100 bytes. The beginning of the dict is intertwined in this
layer because EXIT, (br), (?br) and (loop) are part of the layer because EXIT, (br), (?br) and (loop) are part of the
stable ABI. stable ABI.
# Boot words (B305) # Boot words
Then come the implementation of core Forth words in native Then come the implementation of core Forth words in native
assembly. Performance is not Collapse OS' primary design goal, assembly. Performance is not Collapse OS' primary design goal,
@ -42,7 +42,7 @@ to implement our words in Forth.
However, some words are in this section for performance However, some words are in this section for performance
reasons. Sometimes, the gain is too great to pass up. reasons. Sometimes, the gain is too great to pass up.
# Core words (low) (B350) # Core words (low)
Then comes the part where we begin defining words in Forth. Then comes the part where we begin defining words in Forth.
Core words are designed to be cross-compiled (B260), from a Core words are designed to be cross-compiled (B260), from a
@ -63,7 +63,7 @@ precisely to fit drivers in there. This way, they have access
to a pretty good vocabulary and they're also give the oppor- to a pretty good vocabulary and they're also give the oppor-
tunity to provide (emit) and (key). tunity to provide (emit) and (key).
# Core words (high) (B350) # Core words (high)
Then come EMIT, KEY and everything that depend on it, until Then come EMIT, KEY and everything that depend on it, until
we have a full Forth interpreter. At the very end, we define we have a full Forth interpreter. At the very end, we define
@ -82,7 +82,7 @@ new xcomp (cross compilation) unit. Let's look at its
anatomy. First, we have constants. Some of them are device- anatomy. First, we have constants. Some of them are device-
specific, but some of them are always there. SYSVARS is the specific, but some of them are always there. SYSVARS is the
address at which the RAM starts on the system. System variables address at which the RAM starts on the system. System variables
will go there and use 0x80 bytes. See B80. will go there and use 0x80 bytes. See impl.txt.
HERESTART determines where... HERE is at startup. 0 means HERESTART determines where... HERE is at startup. 0 means
"same as CURRENT". "same as CURRENT".
@ -100,13 +100,10 @@ same way. Drivers are a bit tricker and machine specific. I
can't help you there, you'll have to use your wits. can't help you there, you'll have to use your wits.
After we've loaded the high part of the core words, we're at After we've loaded the high part of the core words, we're at
the "wrapping up" part. We add what we call a "hook word" (an the "wrapping up" part. We add what we call a "hook word", an
empty word with a single letter name) which doesn't cost us empty word with a single letter name. This allows us to boot
much and can be very useful if we need to augment the binary with CURRENT pointing to "source init" content rather than being
with more words, and at that point we have our future boot an actual wordref.
CURRENT, which PC yields. That is why we write it to the
LATEST field of the stable ABI: This value will be used at
boot.
After the last word of the dictionary comes the "source init" After the last word of the dictionary comes the "source init"
part. The boot sequence is designed to interpret whatever comes part. The boot sequence is designed to interpret whatever comes

View File

@ -19,7 +19,7 @@ ample, a machine with only a serial console can't.
# Block editor # Block editor
The Block editor augments the built-in work LIST with words to The Block editor augments the built-in word LIST with words to
modify the block currently being loaded. Block saving happens modify the block currently being loaded. Block saving happens
automatically: Whenever you load a new block, the old block, if automatically: Whenever you load a new block, the old block, if
changed, is saved to disk first. You can force that with FLUSH. changed, is saved to disk first. You can force that with FLUSH.
@ -37,6 +37,9 @@ You can insert text at the current position with "i". For exam-
ple, "i foo" inserts "foo" at cursor. Text to the right of it ple, "i foo" inserts "foo" at cursor. Text to the right of it
is shifted right. Any content above 64 chars is lost. is shifted right. Any content above 64 chars is lost.
Why "i" and not "I"? Because "I" is already used and we don't
want to overshadow it.
You can "put" a new line with "P". "P foo" will insert a new You can "put" a new line with "P". "P foo" will insert a new
line under the cursor and place "foo" on it. The last line of line under the cursor and place "foo" on it. The last line of
the block is lost. "U" does the same thing, but on the line the block is lost. "U" does the same thing, but on the line
@ -68,8 +71,7 @@ P xxx: put typed IBUF on selected line.
U xxx: insert typed IBUF on selected line. U xxx: insert typed IBUF on selected line.
F xxx: find typed FBUF in block, starting from current F xxx: find typed FBUF in block, starting from current
position+1. If not found, don't move. position+1. If not found, don't move.
i xxx: insert typed IBUF at cursor. "i" is to avoid shadowing i xxx: insert typed IBUF at cursor.
core word "I".
Y: Copy n characters after cursor into IBUF, n being length of Y: Copy n characters after cursor into IBUF, n being length of
FBUF. FBUF.
X ( n -- ): Delete X chars after cursor and place in IBUF. X ( n -- ): Delete X chars after cursor and place in IBUF.
@ -118,7 +120,8 @@ the previously opened block.
'w' moves forward by "modifier" words. 'b' moves backward. 'w' moves forward by "modifier" words. 'b' moves backward.
'W' moves to end-of-word. 'B', backwards. 'W' moves to end-of-word. 'B', backwards.
'I', 'F', 'Y', 'X' and 'E' invoke the corresponding command 'I', 'F', 'Y', 'X' and 'E' invoke the corresponding command from
command-based editor.
'o' inserts a blank line after the cursor. 'O', before. 'o' inserts a blank line after the cursor. 'O', before.

View File

@ -168,33 +168,31 @@ territory, identical)
On boot, we jump to the "main" routine in B289 which does On boot, we jump to the "main" routine in B289 which does
very few things. very few things.
1. Set SP to PS_ADDR and IX to RS_ADDR 1. Set SP to PS_ADDR and IX to RS_ADDR.
2. Sets HERE to SYSVARS+0x80. 2. Set CURRENT to value of LATEST field in stable ABI.
3. Sets CURRENT to value of LATEST field in stable ABI. 3. Set HERE to HERESTART const if defined, to CURRENT other-
wise.
4. Execute the word referred to by 0x04 (BOOT) in stable ABI. 4. Execute the word referred to by 0x04 (BOOT) in stable ABI.
In a normal system, BOOT is in core words at B396 and does a In a normal system, BOOT is in core words at B396 and does a
few things: few things:
1. Initialize all overrides to 0. 1. Initialize all overrides to 0.
2. Write LATEST in BOOT C< PTR ( see below ) 2. Write LATEST in BOOT C< PTR ( see below ).
3. Set "C<*", the word that C< calls to (boot<). 3. Set "C<*", the word that C< calls, to (boot<).
4. Call INTERPRET which interprets boot source code until 4. Call INTERPRET which interprets boot source code until
ASCII EOT (4) is met. This usually init drivers. ASCII EOT (4) is met. This usually initializes drivers.
5. Initialize rdln buffer, _sys entry (for EMPTY), prints 5. Initialize rdln buffer, _sys entry (for EMPTY), prints
"CollapseOS" and then calls (main). "CollapseOS" and then calls (main).
6. (main) interprets from rdln input (usually from KEY) until 6. (main) interprets from rdln input (usually from KEY) until
EOT is met, then calls BYE. EOT is met, then calls BYE.
In RAM-only environment, we will typically have a
"CURRENT @ HERE !" line during init to have HERE begin at the
end of the binary instead of RAMEND.
# Stable ABI # Stable ABI
Across all architectures, some offset are referred to by off- The Stable ABI lives at the beginning of the binary and prov-
sets that don't change (well, not without some binary manipu- ides a way for Collapse OS code to access values that would
lation). Here's the complete list of these references: otherwise be difficult to access. Here's the complete list of
these references:
04 BOOT addr 06 (uflw) addr 08 LATEST 04 BOOT addr 06 (uflw) addr 08 LATEST
13 (oflw) addr 2b (s) wordref 33 2>R wordref 13 (oflw) addr 2b (s) wordref 33 2>R wordref

View File

@ -24,7 +24,7 @@ a bit tight at first, having this limit saves us a non-
negligible amount of resource usage. negligible amount of resource usage.
The reasoning behind this intentional limit is that huge The reasoning behind this intentional limit is that huge
branches are generally a indicator that a logic ought to be branches are generally an indicator that a logic ought to be
simplified. So here's one more constraint for you to help you simplified. So here's one more constraint for you to help you
towards simplicity. towards simplicity.
@ -41,9 +41,9 @@ from KEY, puts it in a buffer, then yields the buffered line,
one character at a time. one character at a time.
Both C< and KEY can be overridden by setting an alternate Both C< and KEY can be overridden by setting an alternate
routine at the proper RAM offset (see B80). For example, C< routine at the proper RAM offset (see impl.txt). For example,
overrides are used during LOAD so that input comes from C< overrides are used during LOAD so that input comes from disk
disk blocks instead of keyboard. blocks instead of keyboard.
KEY overrides can be used to, for example, temporarily give KEY overrides can be used to, for example, temporarily give
prompt control to a RS-232 device instead of the keyboard. prompt control to a RS-232 device instead of the keyboard.
@ -108,8 +108,13 @@ try to strive towards a few goals:
1. Block 0 contains documentation discovery core keys to the 1. Block 0 contains documentation discovery core keys to the
uninitiated. uninitiated.
2. First section (up to B100) is usage documentation. 2. B1-B4 are for a master index of blocks.
3. B100-B200 are for runtime usage utilities 3. B5-B199 are for runtime usage utilities
4. B200-B500 are for bootstrapping 4. B200-B599 are for bootstrapping
5. The rest is for recipes. 5. The rest is for recipes.
6. I'm not sure yet how I'll organize multiple arches.
Blocks are currently not organized neatly. I'm planning the
extraction of recipes into some kind of block "overlays" that
would live in the recipes subfolder so each recipe would build
its own specific blkfs which would contain only its recipe code,
starting at B600.