📄 pygmy.txt
字号:
If it is not clear from the instruction whether the operand is a byte
or a word, a byte is assumed. E.g. 0 [BX] PUSH, would push only a single
byte. To override this, use W-PTR e.g.
0 [BX] W-PTR PUSH,
For the shifts & rotates, if an immediate operand precedes it, it
shifts a single bit, e.g.
1 #, AX SHR, ( shift AX one bit right)
or even
300 #, AX SHR, ( shift AX one bit, not 300 bits, right)
If you want it to shift based on the contents of CL, omit the
immediate operand, e.g.
4 #, CX MOV, AX SHR,
examples to shift right 1 bit:
1 #, SI SHR,
1 #, W-PTR 17 [BX] SHR,
1 #, AL SHR,
examples to shift right the # of bits in CL
SI SHR,
AL SHR,
1300 ) SHR,
3752 W-PTR ) SHR,
IN, & OUT, (reading & writing I/O ports)
use
port #, AL IN,
or
port #, AX IN,
for 8 bit ports
or
AX IN, if the port number is the DX register.
Do not use AL DX IN, as the DX is implied.
JMP, & CALL,
Long JMPs & long CALLs are "not supported at this time."
The instruction that does a bit by bit complement is called NOT by
Intel, but in THIS assembler it is called COM,. This assembler uses NOT,
to invert the test at the beginning of an IF, e.g.
CS, IF, ( do if carry set) THEN,
or
CS, NOT, IF, ( do if carry not set) THEN,
The full source code for the assembler is present in the file
PYGMY.SCR. Some examples are included along with the source code. In
addition, you can browse the code for Pygmy's primitives for examples of
how to use the assembler. The general rule is that the operand(s) come
first followed by the opcode mnemonic (which ends in a comma). With two
operands, the source comes first and the destination second, like god meant
it to be. BX AX MOV, lays down a move instruction to copy the contents of
register BX into register AX.
Chapter 13 The Editor
Editor commands:
To enter the editor, type n EDIT. To get out of the editor, press the
ESC key. When you are in the editor you can make changes by using the
arrow keys to position the cursor and then just typing. Press the INS key
to switch between the insert and the overwrite modes. The backspace key
will delete characters to the left of the cursor and the Del key will
delete the character the cursor is on. Inserts and deletes only occur on
the current line.
The PgUp & PgDn keys are used to move to the previous or next screen.
This is delightfully fast compared to the editor in F83. If the cursor is
at the beginning of the line already, Home moves to top of screen;
otherwise, Home moves to beginning of current line. End moves past last
character on current line.
The very top line of the screen is a status line that shows the screen
number and the file name and a brief reminder of some of the function keys'
functions. It also shows an "i" if in the insert mode. It also shows a
count of the lines in the cut buffer.
F1 repeats a search.
F2 repeats a replace.
F3 sets up a search string and then searches.
F4 sets up a replace string and immediately replaces with it. ( To
repeatedly change CAT to DOG, use F3 to set up CAT ) ( & F4 to set up DOG
and then press F1 F2 F1 F2 etc ).
F5 deletes the current line.
F6 joins the line below to the current line at the cursor.
F7 "cuts" the current line to the cut buffer. This does not alter the
current line. (See the "c= " on status line).
F8 "pastes" the oldest line in the cut buffer to the current line on the
screen, overlaying the current line. The cut buffer is almost unlimited in
size. It can be used to copy and move lines on the same screen or to
different screens (even screens in different files). Notice that the count
of lines cut (on the status line) changes as you press F7 & F8.
F9 inserts blank screens after the current screen.
F10 does a search like F1, but across multiple screens.
Esc exits from the editor. If you want to cancel the most recent
changes, after pressing Esc, type EMPTY-BUFFERS. If you want your most
recent changes to be applied to the disk immediately, after pressing Esc,
type FLUSH.
CR ends the current line, pushing anything to the right onto the
following line and pushing the lines below it down.
Home moves the cursor to the beginning of the current line. If already
at the beginning, it moves the cursor to top left corner.
End moves the cursor just past the end of text on the current line
(which may be at the 1st position of the following line).
Bksp If not at the far left of a line, it deletes the character to the
left of the cursor.
Del deletes the character the cursor is on.
Ins toggles insert vs overwrite modes (see the "i" on status line).
Note, the deletions and insertions only affect the current line.
Oooops
How do you exit from the editor without making any changes? (cancel
your changes, that is)? Press Esc key to get out of the editor and then
type
EMPTY-BUFFERS
F9 is good for opening up a file in the middle or for extending a file
at the end. As you move screens around and delete them from where they
used to be, you may accumulate a number of blank screens. SETTLE (used
outside of the editor) is used to let the heavy screens sink to the bottom
and let the light screens float to the top. It only affects the range of
screens that you specify, e.g.
315 345 SETTLE
will re-arrange those screens so that any completely blank screens are at
the highest numbers and the non-blank screens are at the lowest numbers.
This compresses out blank screens. A related word CHOP will truncate a
file by chopping off all trailing blank screens, e.g.
3 CHOP
will chop the blank screens off the end of the file whose unit# is 3.
Chapter 14 The Meta Compiler
Pygmy includes a meta-compiler. It is easy to use. To regenerate the
kernel of Pygmy, edit the source code in the file PYGMY.SCR to include your
changes. Then type
1 LOAD
This will create a new version of the Pygmy kernel and save it to
disk. Be sure to edit the file name you want it saved as on scr #1. Exit
to DOS with
BYE
and bring up the new version you just created. It is the kernel only,
without the editor or assembler or other extensions. However, it will have
the file PYGMY.SCR already set up in unit# 0, and opened automatically. To
extend it, just load the proper load screen. This screen number is usually
noted on screen #1 to make it easy to find, e.g.
83 LOAD
Look at screen 83 to see how this works. Note that this is simpler than in
previous (to version 1.3) versions. Having all the source code in a single
file makes this easier. Be sure to edit screen 83 (or whatever your load
screen is) so it will include just what you want and so it will save the
newly created Forth to the proper file name.
Meta-compiling Pygmy is very easy, so don't put off trying it. It
lets you fix all the aspects of Pygmy that you disagree with me about! Your
first attempt should be to generate a version of Pygmy with no changes
whatsoever, except possibly the file name you save the new versions under.
Once you've done this once or twice you can begin changing the kernel, or
extending it differently.
Here is how the meta-compiler works. First the load screen (#1) loads
the meta-compiler (on screens 3 through 13). This renames some of the
current Forth's words (so they can still be found) and then redefines the
defining words needed for the new Forth. Note a number of variables such
as TLIT and TVAR etc. These will hold the addresses of the target's
runtime routines (for LITERAL and VARIABLE etc.) as soon as those runtime
routines have been defined in the target. The meta-compiler will use those
values to compile the proper code in the target.
Then, starting at screen 17, the target's code begins. The target is
compiled starting at address $8000.
H' holds the target's dictionary pointer (H holds the host's).
Following H' is the relocation factor used for the target code. The curly
braces switch between the target & host spaces, so that the regular host
facilities, such as , HERE -FIND etc can be used for both purposes. The
host does need some special meta-compiler words. When we are redefining a
host word that we might need the original of, the original is renamed, so
we will still have access to it under the synonym ( e.g. : :' : ; ).
There are two ghost vocabularies used for the target. After our
redefinitions, FORTH & COMPILER refer to the target and FORTH' & COMPILER'
refer to the host. This is the secret that keeps everything straight.
When interpreting, words are looked up and executed (as is normal)
from the FORTH' (host) vocabulary. When compiling a colon definition,
COMPILER' (host) is searched first. If found the word is executed
immediately. If not found, FORTH (target) is searched. If found, the word
is compiled into the new definition. If not found, it is converted to a
number (or an error) and compiled as a literal into the new definition. So,
when meta-compiling, target COMPILER words are never executed, leaving the
host's free to operate. When not compiling, target FORTH words are never
executed, leaving our regular host system free to operate. \ is redefined
so when meta-compiling, the word is looked up in the target's COMPILER
vocabulary and compiled into the new definition.
All of this means that you do not have to "forget" any of the target
words. (There may one or two that need to be forget'd. I can't remember
at the moment, ha ha.)
So what changes might you make? Changing the constant TMAX-FILES will
let you specify just how many files to allow open at the same time.
Changing TNB lets you change the number of file buffers that will be used.
Currently TNB is 1, which allows 2 buffers. Note that the number of buffers
must be a power of two (and greater than 1), so acceptable values for TNB
are 1, 3, 7, 15, etc. (TNB and thus NB are set to 1 less than the number
of buffers.) Suit yourself. So far I haven't had any trouble using just
two. You can eliminate the excess and useless words that I've included
which you see no need for. (Just don't eliminate any that are used in the
definitions of other words that you do want to include!)
For target applications, you can let the metacompiler do all of your
CODE (assembly language) words so that you do not need to include the
assembler in the final target application. (You might also eliminate the
editor from the final application if it isn't needed, but, since it is
loaded after the kernel has been created, that's not affected by the
meta-compiler.)
Currently the meta-compiler does not allow headless code. If you want to
streamline the dictionary, you can unlink the auxiliary words that won't
need to be looked up in the final application by using HIDE (see its
definition in PYGMY.SCR). The heads won't show with WORDS and they won't
be in the links to slow down the dictionary searches, but they'll still be
taking up space.
If you change the boot code, you may need to change the patch on screen
68 where the address of reset is patched into boot.
If you are target compiling an application and want it to execute your
code automatically (rather than coming up in Forth) just point the word
BOOT at your application. Suppose you have named it YOUR-APPLICATION.
Type
' YOUR-APPLICATION IS BOOT
and then save it to disk with something like
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -