doc: fix typos and inaccuracies
This commit is contained in:
parent
4b1a49c8cc
commit
6d180f737a
75
doc/avr.txt
75
doc/avr.txt
@ -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@.
|
||||||
|
@ -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
|
||||||
|
11
doc/ed.txt
11
doc/ed.txt
@ -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.
|
||||||
|
|
||||||
|
24
doc/impl.txt
24
doc/impl.txt
@ -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
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user