mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-17 22:38:05 +11:00
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
|
||||
|
||||
To program AVR chips, you need a device that provides the SPI protocol. The
|
||||
device built in the rc2014/sdcard recipe fits the bill. Make sure you can
|
||||
override the SPI clock because the system clock will be too fast for most AVR
|
||||
chips, which are usually running at 1MHz. Because the SPI clock needs to be a
|
||||
4th of that, a safe frequency for SPI communication would be 250kHz.
|
||||
To program AVR chips, you need a device that provides the SPI
|
||||
protocol. The device built in the rc2014/sdcard recipe fits the
|
||||
bill. Make sure you can override the SPI clock because the sys-
|
||||
tem clock will be too fast for most AVR chips, which are usually
|
||||
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
|
||||
SPI_DELAY in your xcomp unit: the default value for this is 2 NOP, which only
|
||||
works when you use the system clock.
|
||||
|
||||
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 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.
|
||||
|
||||
The AVR programming code is at B690.
|
||||
|
||||
Before you begin programming the chip, the device must be deselected. Ensure
|
||||
with "(spid)".
|
||||
Before you begin programming the chip, the device must be desel-
|
||||
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
|
||||
echoes the byte that was sent in the 2nd exchange. If it doesn't, the command
|
||||
aborts with "AVR err".
|
||||
Each command will verify that it's in sync, that is, that its
|
||||
3rd exchange echoes the byte that was sent in the 2nd exchange.
|
||||
If it doesn't, the command aborts with "AVR err".
|
||||
|
||||
# Access fuses
|
||||
|
||||
You get/set they values with "aspfx@/aspfx!", x being one of "l" (low fuse),
|
||||
"h" (high fuse), "e" (extended fuse).
|
||||
You get/set they values with "aspfx@/aspfx!", x being one of "l"
|
||||
(low fuse), "h" (high fuse), "e" (extended fuse).
|
||||
|
||||
# Access flash
|
||||
|
||||
Writing to AVR's flash is done in batch mode, page by page. To this end, the
|
||||
chip has a buffer which is writable byte-by-byte.
|
||||
Writing to AVR's flash is done in batch mode, page by page. To
|
||||
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
|
||||
chip. It seems possible to erase flash page-by-page through parallel
|
||||
programming, but the SPI protocol doesn't expose it, we have to erase the whole
|
||||
chip. Then, you write to the buffer using aspfb! and then write to a page using
|
||||
aspfp!. Example to write 0x1234 to the first byte of the first page:
|
||||
Writing to the flash begins with a call to asperase, which
|
||||
erases the whole chip. It seems possible to erase flash page-by-
|
||||
page through parallel programming, but the SPI protocol doesn't
|
||||
expose it, we have to erase the whole chip. Then, you write to
|
||||
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!
|
||||
|
||||
Please note that aspfb! deals with *words*, not bytes. If, for example, you want
|
||||
to hook it to A!*, make sure you use AMOVEW instead of AMOVE. You will need to
|
||||
create a wrapper word around aspfb! that divides dst addr by 2 because AMOVEW
|
||||
use byte-based addresses but aspfb! uses word-based ones. You also have to make
|
||||
sure that A@* points to @ (or another word-based fetcher) instead of its default
|
||||
value of C@.
|
||||
Please note that aspfb! deals with *words*, not bytes. If, for
|
||||
example, you want to hook it to A!*, make sure you use AMOVEW
|
||||
instead of AMOVE. You will need to create a wrapper word around
|
||||
aspfb! that divides dst addr by 2 because AMOVEW use byte-based
|
||||
addresses but aspfb! uses word-based ones. You also have to make
|
||||
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
|
||||
itself to a Forth interpreter. In most cases, that Forth
|
||||
interpreter will have some access to a mass storage device,
|
||||
which allows it to access Collapse OS' disk blocks and come
|
||||
to this block to bootstrap itself some more.
|
||||
which allows it to access Collapse OS' disk blocks and bootstrap
|
||||
itself some more.
|
||||
|
||||
This binary can be separated in 5 distinct layers:
|
||||
|
||||
1. Boot code (B280)
|
||||
2. Boot words (B305)
|
||||
3. Core words (low) (B350)
|
||||
4. Drivers
|
||||
5. Core words (high)
|
||||
1. Arch-specific boot code (B280 for Z80)
|
||||
2. Arch-specific boot words (B305 for Z80)
|
||||
3. Arch-independant core words (low) (B350)
|
||||
4. Drivers, might contain arch-specific code
|
||||
5. Arch-independant core words (high) (B380)
|
||||
|
||||
# Boot code (B280)
|
||||
# Boot code
|
||||
|
||||
This part contains core routines that underpins Forth fundamen-
|
||||
tal structures: dict navigation and search, PSP/RSP bounds
|
||||
checks, word types.
|
||||
tal structures: dict navigation and FIND, PSP/RSP bounds checks,
|
||||
word types.
|
||||
|
||||
It also of course does core initialization: set RSP/PSP, HERE
|
||||
CURRENT, then call BOOT.
|
||||
|
||||
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
|
||||
stable ABI.
|
||||
|
||||
# Boot words (B305)
|
||||
# Boot words
|
||||
|
||||
Then come the implementation of core Forth words in native
|
||||
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
|
||||
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.
|
||||
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-
|
||||
tunity to provide (emit) and (key).
|
||||
|
||||
# Core words (high) (B350)
|
||||
# Core words (high)
|
||||
|
||||
Then come EMIT, KEY and everything that depend on it, until
|
||||
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-
|
||||
specific, but some of them are always there. SYSVARS is the
|
||||
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
|
||||
"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.
|
||||
|
||||
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
|
||||
empty word with a single letter name) which doesn't cost us
|
||||
much and can be very useful if we need to augment the binary
|
||||
with more words, and at that point we have our future boot
|
||||
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.
|
||||
the "wrapping up" part. We add what we call a "hook word", an
|
||||
empty word with a single letter name. This allows us to boot
|
||||
with CURRENT pointing to "source init" content rather than being
|
||||
an actual wordref.
|
||||
|
||||
After the last word of the dictionary comes the "source init"
|
||||
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
|
||||
|
||||
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
|
||||
automatically: Whenever you load a new block, the old block, if
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -68,8 +71,7 @@ P xxx: put typed IBUF on selected line.
|
||||
U xxx: insert typed IBUF on selected line.
|
||||
F xxx: find typed FBUF in block, starting from current
|
||||
position+1. If not found, don't move.
|
||||
i xxx: insert typed IBUF at cursor. "i" is to avoid shadowing
|
||||
core word "I".
|
||||
i xxx: insert typed IBUF at cursor.
|
||||
Y: Copy n characters after cursor into IBUF, n being length of
|
||||
FBUF.
|
||||
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 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.
|
||||
|
||||
|
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
|
||||
very few things.
|
||||
|
||||
1. Set SP to PS_ADDR and IX to RS_ADDR
|
||||
2. Sets HERE to SYSVARS+0x80.
|
||||
3. Sets CURRENT to value of LATEST field in stable ABI.
|
||||
1. Set SP to PS_ADDR and IX to RS_ADDR.
|
||||
2. Set 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.
|
||||
|
||||
In a normal system, BOOT is in core words at B396 and does a
|
||||
few things:
|
||||
|
||||
1. Initialize all overrides to 0.
|
||||
2. Write LATEST in BOOT C< PTR ( see below )
|
||||
3. Set "C<*", the word that C< calls to (boot<).
|
||||
2. Write LATEST in BOOT C< PTR ( see below ).
|
||||
3. Set "C<*", the word that C< calls, to (boot<).
|
||||
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
|
||||
"CollapseOS" and then calls (main).
|
||||
6. (main) interprets from rdln input (usually from KEY) until
|
||||
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
|
||||
|
||||
Across all architectures, some offset are referred to by off-
|
||||
sets that don't change (well, not without some binary manipu-
|
||||
lation). Here's the complete list of these references:
|
||||
The Stable ABI lives at the beginning of the binary and prov-
|
||||
ides a way for Collapse OS code to access values that would
|
||||
otherwise be difficult to access. Here's the complete list of
|
||||
these references:
|
||||
|
||||
04 BOOT addr 06 (uflw) addr 08 LATEST
|
||||
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.
|
||||
|
||||
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
|
||||
towards simplicity.
|
||||
|
||||
@ -41,9 +41,9 @@ from KEY, puts it in a buffer, then yields the buffered line,
|
||||
one character at a time.
|
||||
|
||||
Both C< and KEY can be overridden by setting an alternate
|
||||
routine at the proper RAM offset (see B80). For example, C<
|
||||
overrides are used during LOAD so that input comes from
|
||||
disk blocks instead of keyboard.
|
||||
routine at the proper RAM offset (see impl.txt). For example,
|
||||
C< overrides are used during LOAD so that input comes from disk
|
||||
blocks instead of keyboard.
|
||||
|
||||
KEY overrides can be used to, for example, temporarily give
|
||||
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
|
||||
uninitiated.
|
||||
2. First section (up to B100) is usage documentation.
|
||||
3. B100-B200 are for runtime usage utilities
|
||||
4. B200-B500 are for bootstrapping
|
||||
2. B1-B4 are for a master index of blocks.
|
||||
3. B5-B199 are for runtime usage utilities
|
||||
4. B200-B599 are for bootstrapping
|
||||
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