-
Notifications
You must be signed in to change notification settings - Fork 1
/
pygmy.txt
executable file
·1877 lines (1465 loc) · 75.1 KB
/
pygmy.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Pygmy Forth version 1.7 MANUAL
Copyright 1989-2007 Frank C. Sergeant
http://pygmy.utoh.org
Pygmy Forth version 1.7 is a fast direct-threaded Forth for
reasonably compatible MS-DOS and PC-DOS machines. This the DOS box in
all versions of Microsoft Windows, FreeDOS, and the DOS emulator in
Linux.
It includes an editor, assembler, and metacompiler (so it can
recompile itself) in only 16K to 18K. Up to 15 files can be open
simultaneously. It includes a multi-tasker and the ability to execute
C library routines. It comes with full source code and documentation.
It is based loosely on Charles Moore's cmFORTH.
TABLE of CONTENTS
Chapter 1 Terms of use and distribution
Chapter 2 Pygmy Forth T-shirts
Chapter 3 Credit Where Credit is Due
Chapter 4 Why I Wrote Pygmy
Chapter 5 What Is Pygmy?
Chapter 6 How To Run The Program
Chapter 7 If You Are New to Forth
Chapter 8 What Was New With Version 1.2
Chapter 9 What Was New With Version 1.3
Chapter 10 What Was New With Version 1.4
Chapter 11 What Was New With Version 1.5
Chapter 12 No Version 1.6
Chapter 13 What Is New With Version 1.7
Chapter 14 Tips
Chapter 15 How Files Work
Chapter 16 The Assembler
Chapter 17 The Editor
Chapter 18 The Metacompiler
Chapter 19 Vocabularies
Chapter 20 Additional Information
Chapter 21 How to Reach Me
Chapter 22 The Glossary and Index
Chapter 23 Memory Map
Chapter 24 Files
Chapter 25 Direct Threaded
Chapter 26 History and Philosophy
Chapter 27 How to Print the Source Code
Chapter 28 _Starting Forth_ Notes
Chapter 29 Multi-tasker
Chapter 30 C Library Routines, etc.
Chapter 31 The Kermit File Transfer Protocol
Chapter 1 Terms of use and distribution
It is freely available for use and redistribution under a liberal
BSD/MIT/X-style license. See http://pygmy.utoh.org/license.html or
the file license20040130.txt.
Chapter 2 Pygmy Forth T-shirts
There are no more Pygmy Forth T-shirts. When my girl friend was
a child, she published a family newsletter_. Her grandfather was in
the sign and printing business and produced a cartoon that she put in
one of the issues. The cartoon shows her in a cannibal's stew pot
saying "You can't do this to me, I'm the editor ...!" and the
cannibal, holding a shield and spear, replies "Don't worry missy, soon
you be Editor in Chief."
At one time, she extracted the image of the cannibal to use as
the logo for Pygmy Forth and had a few T-shirts made that say "Pygmy
Forth" and show the Pygmy caricature from the cartoon in black, green,
and brown. Perhaps one day I will get that image as a png file and
post it on the web site. Don't hold your breath.
Chapter 3 Credit Where Credit is Due
Pygmy Forth was inspired by cmFORTH for the NOVIX, a
public domain Forth written by Charles Moore. Much of the
overall structure and specific high level code reflect this
influence. Some of the machine code, especially flag
producing words, is tighter due to ideas suggested by Robert
Berkey. Wil Baden provided OF THENS. The initial approach
to handling files was suggested by Dennis Ruffer by his
description of files in Forth Inc's polyFORTH. Rob Chapman
contributed the idea of (and how obvious when you think
about it) having FOR NEXT do the loop <n> times instead of
<n+1> times. He also contributed a slogan that I've
adopted: "It's so simple - it HAS to work." Many other
people, especially Ian Watters, Greg Lisle, Brad Rodriguez,
J.E. Thomas, and David Zethmayr have offered suggestions and
encouragement (and prodding) that have helped make Pygmy as
pretty as it is today. Thank you.
Chapter 4 Why I Wrote Pygmy
Pygmy Forth's goals:
1. Fast, comfortable editor.
2. Reduced sized and complexity.
3. Inclusion of certain cmFORTH ideas:
a. PUSH POP (instead of >R R>)
b. FOR NEXT
c. no IMMEDIATE word
(but it does have words that are immediate)
d. simple Metacompilation
Pygmy includes
1. a fast screen oriented block editor
2. an 8088/8086 assembler
3. full source code
4. full metacompiler, easy to use
5. up to 15 files open and accessible at one time
6. default set of files opened automatically
7. FOR/NEXT, PUSH, POP, \, COMPILER vocabulary, and
other cmFORTH improvements
8. BIOS video calls for the best mix of speed
and compatibility.
9. optional direct video for fastest speed
10. vectored I/O ( EMIT, KEY, KEY?, CR )
11. documentation (this file)
12. _Starting Forth_ compatibility hints for people new
to Forth
13. an experimental beginner's tutorial
14. VIEW for rapidly locating the source code for
a particular word
15. a relocatable dictionary
16. ability to make individual words or groups of
words headerless
17. ability to load from text files with FLOAD
and to mix and nest between LOAD and FLOAD
as deeply as you like
18. multi-tasker
19. PC serial port routines
20. Kermit file transfer protocol written in Forth
21. embeddable in C wrapper to allow Forth to use C
library routines and to allow C to call Forth
22. it runs on everything from a PC XT or palmtop
(HP95LX, HP100LX, HP200LX, Atari Portfolio,
etc.) to a DOS box any version of Microsoft Windows
to DOS emulator in Linux.
Chapter 5 What Is Pygmy?
Pygmy is one step on my path toward a "perfect" Forth.
It runs on IBM PC/XT/AT and compatibles on DOS or a DOS box in
either Linux or Microsoft Windows. It is based (more and more
loosely) on Charles Moore's cmFORTH for the NOVIX Forth chip,
with many changes to allow it to run on a PC, and other
changes as well.
cmFORTH was designed to run on a NOVIX connected by a
serial line to a host terminal or computer that supplies
editing and file storage services. Therefore, cmFORTH does
not include an editor. Also, no assembler is needed
because the NOVIX's assembly language is Forth (more or
less).
Pygmy Forth includes an editor and assembler and still
only takes up about 18K bytes fully loaded. The kernel
(without editor and assembler) is less than 10K. Actually,
you have quite a lot of control on just how big it is
because you can customize the system just the way you like
it. It comes with complete source code, including the
metacompiler, so it can recompile itself. The metacompiler
can also be used for compiling custom applications. In this
case you can eliminate the parts (such as the editor and
assembler and various utilities) that the final application
will not need. And you can make words headerless to reduce
the size of your final applications. Regenerating the
kernel (with 1 LOAD) takes about a second on an old Pentium
90 MHz PC. Then, extending it with the editor, assembler,
multi-tasker, etc. with 5 LOAD takes about a second.
Pygmy is direct threaded with top of stack kept in a
register. It has a comfortable screen oriented block
editor. You can move quickly from block to block with the
PgDn and PgUp keys, search across blocks, insert blank blocks,
and compress out blank blocks, and switch between related
blocks (for shadows or for comparing different versions of
an application).
Pygmy allows 15 files open at one time. These are all
accessible "simultaneously" at different block numbers. Your
default files are opened automatically and the defaults can be
changed, of course, and additional files can be opened. .FILES
shows the file names and status. The documentation shows
examples of how to reset them. If you need more than 15 files
open at one time, there is supplemental code that shows how to
have over 200 files open at one time.
Chapter 6 How To Run The Program
Make a backup copy of the distribution disk, if you got
it on a disk. If Pygmy is distributed in a ZIP file, unzip
the files into the directory of your choice. For example,
create a directory named "pyg" and unzip the files there, as
in the following example:
C:\>md pyg ( create a directory named "pyg")
C:\>cd pyg ( change to that directory )
C:\PYG>copy c:\temp\pygmy17.zip . ( copy the zip file to "pyg")
C:\PYG>unzip pygmy17.zip
(use your favorite unzip program -- I use the InfoZIP version)
Then bring up Pygmy by typing
C:\PYG\>pygmy
All of the source code for the system, both the kernel
and the extensions, is in the block file PYGMY.SCR. The
manual is a regular text file, PYGMY.TXT (the file you are
currently reading), which is readable with LIST or nearly
any text editor. Another block file, YOURFILE.SCR, is
provided for the source code you write. It starts out with
8 blank blocks and can be enlarged as much as you like with
the Editor's F9 key. Of course, you are free to create and
use additional block files, but you do not have to do so in
order to use Pygmy.
To read the source code, bring up Pygmy and then use
Pygmy's editor to browse through the block file PYGMY.SCR.
To start at the beginning, make sure Caps Lock is on, then
type
0 EDIT
(end all commands by pressing <Enter>). Then just start
browsing with the PgDn and PgUp keys. If you have the shadow
blocks available, press Ctrl-A to switch between a source
code block and its shadow. To get out of the editor press
Esc. To get back in where you left off, type
ED
To skip to a particular block, press Esc to get out of the
editor and then type n EDIT where n is the block you want to
jump to. To see what files are open, get out of the editor
and type
.FILES
To see the source code for a particular word, type VIEW
followed by the word's name, e.g. VIEW EXPECT or you can
use the shorthand V .
If you get error messages when you try to open files, it
probably means that your CONFIG.SYS file is not allowing
enough files. Change or add a "FILES=" statement to
CONFIG.SYS so it says FILES=20 or higher, then reboot and
try again. (As shipped PYGMY.COM tries to open only a few
files automatically, so this should rarely be a problem.)
If your monitor works with DOS it should work with Pygmy.
It accesses the video through BIOS calls. However, the direct
writes to video memory is much faster on old, slow computers.
So, you can re-vector EMIT to use the direct writes instead of
the BIOS if you wish.
Chapter 7 If You Are New to Forth
The purpose of this manual is not primarily to teach
Forth. To learn Forth, work your way through the book
_Starting Forth_ by Leo Brodie. It may still be available
from the Forth Interest Group or may be posted or the web
somewhere. Pygmy does not try to be compatible with _Starting
Forth_ but there are a few notes in a later chapter about
converting the _Starting Forth_ examples to Pygmy that may
help.
Jump in and try to write some simple code. See my
experimental Tutorial article to see if it helps get you
oriented. Spend some time browsing the source code in
PYGMY.SCR with the built-in editor.
As a Forth to learn with, Pygmy may have some
advantages:
(1) it doesn't cost much (it is free),
(2) the entire source code is included,
(3) it is small enough and non-intimidating enough that
you have a chance to grasp it,
(4) metacompiling, using Pygmy, is easy,
(5) I am usually available to answer questions via
comp.lang.forth or email.
If you want to try it without a book, then read all of
the documentation and read the source code as well. Try out
simple examples. Browse the web for further examples.
Previously, I recommended joining FIG and reading _Forth
Dimensions_ but there are still the Internet, comp.lang.forth,
various mailing lists, and local FIGs. There is no substitute
for doing your own experimenting. The word VIEW is a great
help. To examine the internals of a word or data structure,
use DUMP or DU. Make heavy use of the source code and
shadows. The stack comments are most helpful, showing what
goes into a word and what comes out. You could even try the
experimental tutorial I have included. Print it out so you
can work from a hard copy.
Chapter 8 What Was New With Version 1.2
Just the highlights:
/ does a signed division, truncating toward zero
( e.g. -3 2 / returns -1 ) rather than flooring.
U/ does an unsigned divide.
BOOT is DEFER'd to make it easy to customize
( e.g. ' MYAPP IS BOOT ).
Fast DO LOOP are now available (courtesy of Robert
Berkey). [no longer included as of version 1.5]
TYPE ( a # -) replaces the cmFORTH TYPE ( a - a'). I
have also added COUNT and -TRAILING to support it. I
like the cmFORTH TYPE ( a - a') but the ending address was
only used in one or two places so I've changed this to TYPE$
( a -).
NUMBER now understands hexadecimal literals such as $8000
and $FF and ascii character literals such as 'A 'B 'z.
.S
" has been added for in-line string literals. At
compile time it compiles the following text up to the ending
quote mark as a counted string. It then commas in a zero
byte, which is not included in the count. The purpose of
this is to make it easy to setup "asciiz" strings for DOS.
E.g. : TST " this is a string " TYPE$ ;
Chapter 9 What Was New With Version 1.3
File handling has been overhauled. Everything is now
done relative to the unit# of the file. See UNIT, SETTLE,
CHOP, OPEN, ?CLOSE, etc. (but see additional changes in
version 1.4, where the handle is used even more often).
ABORT is now a DEFER'd word, to make customizing
applications easier.
For Leonard Morgenstern, NUMBER and LITERAL are now
DEFER'd. (This also makes adding the double and quad number
extensions easier.)
(ONEKEY is the default for KEY. It returns a single
value no matter what key is pressed, rather than a single
value for some keys and two values for other keys, as DOS
does. I prefer the consistency of a single value. You
can still say ' (KEY IS KEY if you prefer the double code
for special keys. [in version 1.5, (KEY is the current
name for what used to be (ONEKEY]
All the source code is now in a single (block) file.
All the documentation is now in a single (text) file.
Metacompiling is even easier.
FILES now keeps track of the highest block # in the
file. Neither the editor nor BLOCK will go outside actual
file bounds.
HOLES was added to editor (F9). SETTLE and CHOP make
managing block files more convenient.
Search across now always goes to end of file, no need
to set the ending block number. (But Esc key will abort
the search.)
THRU no longer uses the data stack, so multi-block
definitions which pass arguments on the stack during
compilation can now be loaded with THRU.
Added N! ( n a - n) to store n into a, keeping a copy
of n
Changed FOR/NEXT so 0 FOR ... NEXT goes through the
loop zero times and u FOR ... NEXT goes through the loop u times.
ABORT" now includes the IF.
Added +UNDER ( a b c - a+c b).
Added NIP ( a b c - a c).
Straightened out the redundant EXIT.
Chapter 10 What Was New With Version 1.4
Some of the following words are optional extensions and
are not in PYGMY.COM until you LOAD them. See blocks 139-141
[in version 1.7 see blocks 140-142] for information on loading
these extensions.
" can now be used outside definitions as well as
within.
FILE handling has changed and/or improved in several
directions. Check _all_ your code for compatibility with
the new file handling words. We can now open a file inside
or outside of definitions with a string literal (or a named
string as before) " FILE17.SCR" 4 OPEN which beats the
cumbersome process of v1.3. Files are now opened by
specifying the name and the unit number. The number of the
first block of each file is the unit number times one
thousand, e.g. 0, 1000, 2000, 3000, etc.
The following words now take a handle instead of a unit#:
LBLK >EOF >BOF FCLOSE POSITION@ >POSITION +POSITION
FILE-READ FILE-WRITE MORE FILE-SIZE SET-FILE-SIZE
FOPEN and FMAKE take an asciiz counted string and return a
handle and flag, e.g. " T1.TXT" FOPEN from inside or
outside of a colon definition.
The following words still take unit#:
?CLOSE ?OPEN OPEN? EXISTS? MAKE ?MAKE
Thus there is no longer a need for HANDLE-WRITE, etc. I
think this factoring is more flexible and will let us do
anything we want to do with DOS files. The above form the
basis for a text file loading facility, which is optionally
loaded, or not, at metacompile time. I'd like to please
those who really want to be able to load source code from
text files while not penalizing those who only want to load
from blocks. The main words are
READ-LINE ( - a #)
FLOAD ( name -) e.g. " FILE3.TXT" FLOAD
INCLUDE ( <file-name> ( -) e.g. INCLUDE FILE3.TXT
they use various auxiliary words such as
FIB ( holds addr of file input buffer)
#FIB ( holds length of text string in file input buffer)
>FIN ( holds offset from start of text file)
FBLK ( holds handle number for active text file)
FIBH ( holds handle number that matches contents of FIB)
This system allows virtually unlimited nesting in any
combination of block and text file LOAD and FLOAD and
INCLUDE.
Restrictions on contents of text files: They are expected to
contain lines of no more than 132 characters [as of version
1.5, this can be changed -- see block 2], which end in CRLF
($0D $0A). Single words may not cross line boundaries.
Paren type comments ( such as this) would be fine as long as
the parens are paired on the same line. However I am adding
a slightly different definition of left paren (as an
extension) which will allow multi-line comments, such as
( This is a multi-line
comment because the ending paren
is not on the same line as
the beginning paren.)
All control characters in the file buffer (after
partitioning it by CRLF pairs) are converted to spaces.
Thus, there is no special requirement as to whether the file
ends in Ctrl-Z, etc. Even though lines are expected to end
in CRLF pairs, there is no problem if the CRLF is missing
from the final line of the file.
There is now a #TIB which is analogous to #FIB. QUERY can
be used to gather text to be WORD'd (a simple #TIB OFF at
the end will keep INTERPRET happy; no more having to fool
with SPAN and >IN) and now EXPECT can be used without
disturbing INTERPRET since the #TIB function has been
separated from SPAN, thus no need for $INPUT, but I have
added #INPUT as an extension.
Text file loading does not involve the unit# table and
neither does SAVEM or SAVE, so the need for UN-UNIT (or its
newer name RELEASE) goes away as well (or so I think).
I have improved TXT>BLK which _creates_ a block file from a
text file, and BLK>TXT which _appends_ a range of blocks to
the end of an already existing text file. (I think only one
of the words was in version 1.3, and that it was much
slower.)
Conditional compilation:
I have added .IF ... .ELSE ... .THEN and ?LOAD to
the metacompiler for conditional compilation (e.g. to allow
the constant TFILES to control whether to load the text file
words or just the plain block words). Don't nest the .IF
etc.
-1 CONSTANT TFILES ( true if text files are desired)
TFILES .IF 73 75 THRU .ELSE 76 LOAD .THEN
View Fields and Headerless Words
I've been going up and down and back and forth on this. At
first I made view fields a metacompile-time option; once set
the system always had view fields or never had view fields.
I also allowed headerless words with Ian's suggested |
symbol preceding the word to be made headerless, but only
during metacompilation. I didn't want users burdened with
view fields if they didn't want them, or if space was too
tight. However, I decided if I was going to have headerless
words at all then I hated not to be able to behead the
various editor support words. So, I decided to allow
headerless at anytime. That eases the burden that view
fields might cause, as space can now be saved, if necessary,
by making certain words headerless. I was torn over whether
to use | which is compact but has to be used for every word
you want headerless, or to use HEADERS OFF ... HEADERS ON
to bracket an entire section that is to be made headerless.
I finally compromised by allowing both. And, they can
co-exist without trouble. If either HEADERS are OFF or if a
word is preceded by | then the word will be headerless,
otherwise headerful.
This means we need PRUNE and { and } in the kernel, not just
in the metacompiler. The two versions do different things.
The alternate dictionary must be established before using
headerless. Currently the word SET-EDGE sets up H' and
remembers its initial value. EDGE refers to the edge of the
world that the headerless words' headers fall off of. I'm
open to suggestions for better names. Care to suggest a
decent name for this? PRUNE resets H' from EDGE, and is
included in SAVE, because an unpruned dictionary with
headers over the EDGE would be useless if reloaded. Note:
as shipped, EDGE is set to $C000. Be sure not to let the
dictionary grow above this value if you have any unPRUNE'd
headers present. (If you define any headerless words, PRUNE
before HERE gets to $C000, or do SET-EDGE to set the EDGE to
a higher value.)
Using this headerless feature has allowed most of the editor
and assembler support words' headers to vanish.
EMIT and video words
v1.3 did direct video writes for speed. On occasion this
caused problems on slightly non-IBM-compatible computers
(such as the AT&T 6300 (or whatever number it was). v1.4
has changed to doing EMIT and related words with BIOS Int
$10 calls. This should greatly increase compatibility and
should still be fast (providing no TSRs such as NEWKEY get
in the way and slow things down). [Note, June '97, the BIOS
EMIT is not fast enough on XTs, so you probably will want to
revector EMIT to a direct write version.]
As before, most of the I/O words are vectored, so you
still can replace any routines with ones of your own. The
need for system variables CUR, VID, and CRTC goes away.
[well, see the direct EMIT code in the extensions]
Also, these low level words such as (EMIT, (CR, (KEY
now have any ending parenthesis removed, so as not to
accidentally end comments.
ATTR is still used, but with a difference. In v1.3,
this value was merged with every character written to the
screen. Also, the attribute byte was kept in the most
significant byte of the variable ATTR (to make the merging
simpler). Now ATTR holds the attribute in the least
significant byte. So, if you had used $7100 ATTR ! to make
a pretty dark blue on light blue screen, you will need to do
$71 ATTR ! 2000 .ATTR or $71 ATTR ! CLS instead, with
v1.4. Now the attribute is only combined with characters by
the word .ATTR. See .ATTR below.
Summary of video words:
(AT ( row col -) positions the cursor.
It is usually what AT uses.
(CUR@ ( - row col) fetches current cursor position
(so you can save it and later
restore it). It is usually
what CUR@ uses.
(EMIT ( c -) Writes a byte to the screen at the
current cursor position and advances
the cursor, using a BIOS Int$10
teletype style video write. Scrolling
is done automatically at bottom of
the screen.
AT@ ( - aacc) Reads the character and attribute
byte of the character on screen at
the current cursor location. The
most significant byte is the
attribute and the least significant
is the character. Use 255 AND to
isolate the character, or use 256 U/
to isolate the attribute.
.ATTR ( # -) Writes the specified number of blanks
to the screen, applying the value in
ATTR to each one. This starts at the
current cursor location but does
not change the position of the
cursor. For example, this is used by
(CLS to clear the screen and set the
attributes of all the screen
positions at once. These attributes
will remain in effect until changed
again by .ATTR (or some word that
uses it, such as (CLS ). So, if you
want to write a field with a
different attribute (e.g. blinking,
or a different color), you first need
to set ATTR to the new attribute
value (e.g. $BBFF ATTR !) and then
write the text of the field, e.g.
ATTR @ ( optionally save current attribute)
$71 ATTR ! ( dark blue on light blue background)
25 .ATTR ( clear a field 25 characters wide)
." This is the new text"
ATTR ! ( optionally restore previous attribute)
(CLS ( -) Clears the screen by writing 2000
spaces, using the current attribute
(in ATTR). Note, this could be
changed if you have a larger or
smaller screen than 80 x 25. It is
usually what CLS uses.
This set of BIOS video words is more than the bare
minimum we might get by with. For example, CLS could be
done with 25 carriage returns. Then we would not need .ATTR
or AT@. (AT@ is used in (BOOT to set ATTR to whatever
attribute is currently in use at position 0 0 when the v1.4
is invoked.) But, then, you could not change attributes and
so could not underline or reverse fields, or change colors,
etc. Also, AT is now in the kernel in v1.4 but was not in
v1.3.
In addition to these words, two more BIOS video words
are included in the unloaded (extension) section:
SCROLL-UP ( row col row col #lines attr -)
SCROLL-DOWN ( row col row col #lines attr -)
These scroll the text the specified number
of lines, and blank the new lines at either
the top or bottom. All of this is done
only in the window specified by the upper
left row and col and the lower right row
and column.
I have added various additional words in the extension
section, including COLORS. Load it, if it is not already in
the PYGMY.COM, and try it out. You can set the color by
storing the correct numbers into ATTR, but you might want to
use words such as BLUE ON-BLUE or RED ON-YELLOW or BLINK or
UNDERLINE or REVERSE, etc.
QUIT restores EMIT to whatever is in DEFAULT-EMIT.
Pygmy no longer tries to guess what type of video
display is present. When it wakes up, it sets the cursor to
top left, fetches whatever attribute byte is already there,
and uses it thereafter unless you change it. So, if you
have a color screen at the DOS prompt, and like those colors
(or don't like them), they should be the same colors in
Pygmy. If you don't like those colors, say $1F ATTR ! CLS
or $71 ATTR ! CLS and see if you like those colors better.
Also try the word COLORS that lets you step through various
possibilities of foreground and background colors by
pressing the F1 and F2 keys, as mentioned above.
Miscellaneous
CONDENSED (for use in printing blocks 6 per page in
SHOW2) is currently set for a HP Laser Jet. See the load
blocks if you want to change this for other printers. To
check its setting, just type SEE CONDENSED (as SEE now
handles DEFER'd words).
DUMP and DU save the base, display in HEX, then restore
the base. As DU does multiple DUMPs, and I can give it a
huge count and interrupt it with a keypress, I rarely need
to follow DU with another DU or DUMP. So, DU no longer
leaves the next address on the stack.
BYE now does FLUSH before exiting.
Constants set the data and return stack initial
addresses, so if you want to change the sizes you only need
to make the change in a single location. In addition, there
is a constant STACKSEG which should ordinarily be set to
either 0 or to 1. If STACKSEG is 0 then the data and return
stacks will be in the same 64K segment that contains the
rest of Pygmy. If STACKSEG is 1 then the data and return
stacks will be in the 64K segment above the 64K segment
which contains the rest of Pygmy. I've added the constant
TOP so the location of the disk buffers and input buffers can
be customized (for those attempting to minimize the RAM
Pygmy occupies when running). Note that I have set up the
data and return stacks to use their own segment and each has
about 32K of room. If you switch back to using stacks in
the same segment as the rest of Pygmy be sure to alter the
stack offsets accordingly! All of this is now done easily
by setting options at the beginning of PYGMY.SCR; see the
load blocks. [version 1.5 has returned to putting the
stacks in same segment containing the rest of the code]
SEE now shows what DEFER'd words are deferred to, very
handy! Now that we allow headerless words and are using
RECOVER and have view fields (and if all else fails we have
the search across blocks facility) the former SEE has been
discontinued and the new SEE's only function is to show
where a DEFER'd word is pointing.
The Editor
v1.3's editor on pretty-thoroughly-IBM-compatible
computers has been a joy for me to use. However, it has not
been very easy to convert to other (dare I say "weird")
hardware. So, I have re-written the editor slightly so it
keeps its hands off the video except through properly
DEFER'd words, rather than trying to write to the video
memory directly. So, if you can make versions of CLS, AT,
CUR@, and EMIT that work on your machine, and if your screen
has enough rows and columns, you should be able to get the
full screen editor working on your machine. ED and PgDn and
PgUp no longer restore ins/overwrite to overwrite, thus the
setting stays the way you left it, unless you say EDIT.
The system variable CURSOR has been renamed to EBLK.
It is used by the editor to keep track of the beginning
address of the block buffer that holds the block being
edited.
I have added a shadow facility to the editor. Ctrl-A
switches between related blocks. Alt-A sets the current
block as one of the two base blocks. The default, if you do
not set any base blocks with Alt-A (or if you set them both
to the same block), is to consider that alternate thousands
are related (0 and 1000, 1 and 1001, etc. or 2001 and 3001,
2002 and 3002). That's why I have moved YOURFILE.SCR to
2000, to leave room at 1000 for the Pygmy shadow blocks (see
Bonus Disk) that match PYGMY.SCR at 0000. Do Alt-A on the
two blocks you want to compare and then hold down Ctrl-A to
see the difference ("flickering" as described by Dick
Miller).
NUMBER
I want NUMBER ( a - n), which takes a counted string,
to become NUMBER ( a # - n), which takes an address and
count. I have compromised. I added (SNUMBER ( a # - n) and
left SNUMBER and NUMBER as ( a - n).
Text Files
They are nestable to any level and in any combination
with LOAD. Use " <filename>" FLOAD for postfix or use
INCLUDE <filename> for prefix. At the moment the length of
any one text file is limited to 64K. Setting a single
constant in the metacompiler to true or false determines
whether the text file code will be included in the kernel.
That way, non-users of text files do not have to suffer the
extra overhead.
EXPECT
I fixed a bug in EXPECT that was pointed out by Steve
Birrell, whereby it wouldn't let you type the full length if
backspace-deleted characters took up some of the room.
EXPECT can now be used without concern for resetting SPAN or
>IN as it no longer disturbs the terminal input buffer. See
QUERY when you want to get some input and use WORD on it.
MS
v1.4 now has a (more or less) machine-independent
timing word, MS, in the extensions. This reads Timer 0 to
tell when it has killed approximately the requested number
of milliseconds. Since loop speeds will vary among
different speed machines, there will still be some slight
variation. Feel free to customize the count value to tune it
exactly for your specific machine if you wish.
>STD
>DOS
The BIOS video EMIT words cannot be redirected (via the
command line). Unloaded optional words culminating in >STD
and >DOS can be redirected, although they are slower for
screen use than (EMIT etc.
added FILE-SIZE ( unit# - ud)
I switched code for 0< to that suggested by Andrew McKewan
Fixed error pointed out by Greg Lisle in XREF (and made it
prettier?).
I put in a regular FORGET
I added text file INCLUDE (which uses text file FLOAD)
VIEW, HEADERS, and |
Basically, as Ian Watters suggested, I have added VIEW
fields and the capability of making headerless words. The
word | preceding a definition marks that one word as
headerless. Some posting on GEnie requested that words
reading the input stream be factored so a version is
available that takes a pfa (e.g : VIEW ( -) ' (VIEW ; ),
however I have not done it that way. Instead, I've provided
the word VFA so if a non-input stream version is needed,
just ( pfa) VFA @ and then do whatever you want with the
block number. If the view field is zero then the word was
compiled from the keyboard (or a text file). VIEW simply
terminates in this case. You can uncomment the code to have
it print an error message if you wish.
More details: HEAD is factored out of CREATE, the "pfa" of a
headerless word contains the magic byte $D6 [named NONESUCH in
version 1.7], which won't ever appear as a machine opcode,
followed by the value of the real pfa. cmForth set the msb of
the count byte. The magic byte method costs an extra byte for
every headerless header, but saves time in (-FIND on every
compare when traversing the dictionary). The headerless
headers don't disappear until the word PRUNE is executed. The
word | preceding a word's definition makes that one word
headerless. Pygmy has always had the ability to compile
utilities out of the way in higher memory and then use them to
compile words into the lower dictionary area. However, it
takes PRUNE to cut those high words out of the dictionary when
you are through with them. The PRUNE version of the
metacompiler will not work for this except when metacompiling,
hence a new version for regular use.
By the way, the $D6 magic byte comes from Ian as a byte that
does not appear as an opcode in the '386 or lower. Looking
in a '386 book it looks like we could also use $F1 or $82
for this purpose.
I tried out a high-level -FIND and it was about 8 times
slower than the code (-FIND. So, we'll stick with the code
version for now. Now (-FIND has become -FIND (ie no longer
DEFER'd); ditto for (WORD and WORD.
RESET and reset in version 1.3 have now been consolidated
into RESET.
A one byte INT3, has been added to the extensions (for Ian
Watters) [as of v1.5, it is in the assembler].
At Greg Lisle's suggestion I have changed OPEN so it takes a
unit number instead of a starting block number. Also, I
have renamed F# which converts a block number to its
corresponding unit# to >UNIT#.
SHELLing out to DOS and the ability to read command lines
passed from DOS have been included as extensions.
Chapter 11 What Was New With Version 1.5
Multi-tasking
Command line execution
Improved SHELL and EXEC documentation
RP! and SP! take values from stack now
Embeddable within a C wrapper
(see the article)
Kermit file transfer protocol
New serial port routines
Direct video EMIT available in the extensions. Use this
if the BIOS EMIT is too slow on your machine. To use it,
remove the appropriate left paren on block [or near] 141 so
that, when extending the kernel, 5 LOAD will load the direct
EMIT.
Chapter 12 No Version 1.6
Version 6 was used for some client work but was not
generally released.
Chapter 13 What Is New With Version 1.7
Various minor changes to the code.
New (even more liberal) license.
Shadow blocks included with the distribution (no more
"bonus" disk).
Chapter 14 Tips
Set Caps Lock on. Most words must be typed in UPPER
CASE.
To abandon changes you have just made in the editor,
use Esc to get out of the editor then type EMPTY-BUFFERS
?SCROLL is embedded in WORDS and DU to let you halt
the display by pressing any key (except Esc). Press any key
again to start it up again (except Esc). To bail out,
whether you are scrolling or paused, press Esc. You can also
put ?SCROLL into your own words. For my tastes, this is
very much better than the common practice of aborting when
you press the <Enter> key. However, with the much faster
computers of today, a theoretical ability to halt a listing of
the words by pressing a key is not as useful because the
listing may be finished before you can hit the key. One
possibility would be to put a delay into CR or ?SCROLL or
WORDS.
DUMP ( a - a') and DU ( a # -) allow you to inspect
memory. DUMP dumps one line and leaves the address of the
next line ready for typing DUMP once more. DU repeats DUMP
for a number of lines, dropping the final address. ?SCROLL
is built in, so feel free to type 0 2000 DU (you can get
out of it with Esc, or pause with any key).
.FILES ( -) shows the files that are currently open and
the block numbers associated with them. You can open ANY
type of file; you are not limited to Forth style BLOCK
files.
The word ." works either inside or outside of colon
definitions. There is no need for the abomination .(
(Actually there are two words named ." one is in FORTH and
the other is in COMPILER.) Similarly " can be used inside
or outside definitions for creating a string literal.
Pygmy recognizes $xxxx as a hex number (e.g. $2000
$FE $03F8) and it recognizes character literals as well
(e.g. 'A 'B 'C 'z). The hex literals are a great
convenience and allow us to stay in DECIMAL more of the
time. The character literals allow us to avoid the ugly
CHAR and [CHAR] or ASCII and [ASCII].
NOT inverts the truth value on the stack. It is
equivalent to 0=. If you want to invert each bit
individually, use -1 XOR
Do not blindly convert a block file to a text file
and expect to be able to load the text file. In
particular, LOAD resets the base to decimal, thus you can
change the base to HEX in a block and have that apply only
to the current block. When converting to a text file, you
will need to change the base back to DECIMAL explicitly, as
appropriate.
Chapter 15 How Files Work
Pygmy can access a number of files "simultaneously". As
shipped, it contains 15 slots or units for files, stored in
the FILES array. I often refer to this as the unit# table.
This can be changed to a smaller number if you wish. If you
must access more (perhaps over 200 files; but it probably does
not make sense to open more than 15 if you expect to access
them via BLOCK), that can be done also, and sample code is
included in PYGMY.SCR. 1000 blocks are reserved for each
unit#. The highest block number that can be used is 32766.
Block number 32767 is a dummy block number used when FLUSHing
blocks back to disk.
Before you can access a file (as a block file), it must
be installed into one of the slots. This is done by the
word OPEN or by the word UNIT. UNIT establishes the file's
name (as it is known to DOS) and starting block number.
This name can include the full path, including drive, for
those cases where the file is not in the current directory.
The parameters for OPEN or UNIT are the filename and the
unit#. The unit# will then determine the starting block
number. The starting block number will always be 1000 times
the unit#. Thus the file in unit# 0 starts at block 0, the
file in unit# 5 starts at block 5000, etc. The filename is
the address of a counted string that ends in a zero byte
(for the DOS "asciiz" format). There are several ways to