Contents of the POLYCOPY.DOC file
I have written this program for a friend who runs a PC
newsletter with public domain programs distribution. I felt it
could help many people in the same or similar situation. So I
decided to put it in the public domain. It can be distributed
freely if not altered and accompanied by its intact documentation
and national languages file(s).
If it proves useful to you, a donation will encourage me to
improve it or develop other programs. Please send Eurocheques or
international postal money orders, no cheques from foreign banks.
Endorsement fee is too high and I would't like banks to profit of
your generosity and my work.
You may also be interested to also share the joy of fast
programming with Comforth of which I am the author, with the help
of some friends. It is a development system designed to make the
tremendous power of the Forth language useful in a host operating
system environment and, unlike standalone implementations of
Forth, well suited to write PCDOS applications. It offers a high
degree of source compatibility across various machines. More
about it below.
POLYCOPY is a 360K 5"1/4 diskette copier on the IBM PC. Its
design focuses on fast repeated bulk copying of that particular
format of diskette. It will be useful for those involved in
software or data distribution. But even if you don't have that
particular need, it is worth trying for curiosity. It makes
diskettes copying the fun of a game.
The standard DISKCOPY was designed for generality, to
perform single copies of various formats with any drive/memory
configuration and take advantage of already formated diskettes.
However, if one uses the standard DISKCOPY to perform our goal, a
rough 100 seconds, plus diskettes mounting, is needed to complete
each copy. Furthermore, keeping up to this rate requires
permanent operator attention to minimize machine idle time during
diskettes swaps. This causes operator stress on the long range.
POLYCOPY attains an easy steady 48 seconds per copy with
plenty of noncritical time to mount the diskettes. That's 75
copies per hour, compared to 32 for DISKCOPY. This is in fact the
maximum reachable rate. A drive spins at 300 rpm, giving 0.2
second per revolution. Three of them are needed to format, write,
then verify. There are 40 tracks on each side. And 2x40x3x0.2=48.
This performance was made possible by:
- Of course, reading the source diskette only once.
- Alternating the copies between two drives.
- Careful optimization of disk parameters and operation.
- Clear operation status display whitout need for any keystroke.
The latest topic deserves some explanation. Twin drive
copying using the conventional prompts and answers is really mind
boggling to the operator. He is usually busy sticking labels and
write protection tabs, opening boxes and packing. His attention
is constantly shared between the machine and his side business.
Odds are simply too high not to do what he tells the machine he
is doing or not to tell it what he has done already. The net
result is blank diskettes being shipped and superfluous rewrites.
There is no need to key in POLYCOPY what one is doing. It
constantly senses diskettes insertions and removals and updates a
screen clear display giving a precise feedback of what is going
on, was done and remains to be done. All that with blinking
messages for action requests, boxes using meaningful colors and
calling whistles. You will like to sit a kid to do the job for
POLYCOPY will run on an IBM PC, XT or AT (*) with:
- Two 360K drives as A and B, preferrably A on top of B.
- 360K+ of free memory after loading a 7K POLYCOPY.
- A CGA or EGA is best. A color monitor/television is preferred.
(*) Or highly compatible with regard to diskette hardware & BIOS.
By AT, I mean 80286 and AT BIOS. The 1.2 Mb drive is NOT
suitable. Copy time is only 56" on the AT due its BIOS.
If you own a hard disk, copy POLYCOPY to it, empty both
drives A and B and type "C>polycopy", then fulfil action
If you only own the drives A and B, you are better off
inserting the diskette containing POLYCOPY in drive B and typing
"A>b:polycopy". Removing the diskette from drive B will however
make POLYCOPY react as if you inserted one. No panic, insert a
blank diskette as first asked for and this will put it in step.
This misunderstanding may occasionally also show up in other
occasions. When one removes/inserts a diskette too fast, or half
way then pushes/takes it back again. It may also rarely occur
during an I/O recovery, causing DISKCOPY to miss seeing you
insert/remove. This is not too severe, because the mismatch is
always evident. I've done my best with the hardware at hand and
feel the inconvenience is far outweighed by the comfort in
Another word of caution. POLYCOPY can only know when you
have inserted a diskette, not closed the door. So it starts off
before you close it. You have time, but do not delay. This is of
no consequence other than reporting a bad disk read or copy.
Again, this is evident to the computer fan, but should be told to
Si vous parlez Franais, la commande ci-dessus vous
suffira. If you didn't understand this sentence, you will
probably wish to have the messages displayed in your native
language. This is simply done by specifying, after the command
name, the name of a file containing default messages overrides.
One such file POLYCOPY.ENG is provided for English. You may
change its text for any other language (I'd be curious to start a
collection of these, if you write one, please send it back to
me). You may even tamper with screen colors to your own taste.
So, for an English speaking user, the best is to write a
small batch procedure POLYCOPY.BAT and put it in your program
search path and say: C:\MYLIB\POLYCOPY C:\MYLIB\POLYCOPY.ENG
To achieve maximal performance, POLYCOPY has to play a trick
to disk formating parameters, that is change the intersegment gap
length from 80 to 56. This is of no consequence in virtually all
cases (other systems go as low as 47), but some faulty drives
working beyond the rotational speed tolerance could damage
POLYCOPY diskettes should they write to them. But do not worry,
such drives would damage other diskettes anyway and their owners
must be accustomed to first copying everything they receive. And
who writes to software distribution diskettes anyway?
If however you insist on an 80 gap, look for the 20 FF 38 F6
sequence in the module and patch 38 back to 50. You will still
live with a flat 56 seconds copy. But in that case, keep the new
module for yourself.
It took me about 3 hours to write and fully test a first
version of the program (I reused the basic I/O functions from an
experimental format program). About the same time went into
experimenting and setting up the diskettes insertion/removal
scheme. Plus a couple of hours for a tidy screen. That's all. And
you can imagine that was a lot of experimenting. If I tell you I
am of the meticulous kind and do not program fast, it will give
you an idea of what Forth programming is. I can't think of ever
achieving this with any other language. But that's not counting
all that long time it took to write Comforth of course.
Look at the source code below. Start reading by the end.
Isn't it neater than a
820 GOSUB 1040: I=12: J=27: GOSUB 2030: IF A$="" THEN GOTO 980
It's even easier to test and runs such a lot faster.
Compare even to Pascal and C. Program clarity is comparable,
but Forth is an interpreter and code is tested times faster.
Of course, you will have to know that Forth passes
parameters on a stack (whose behaviour is noted by parm0 ... --
result0 ... for each function), that it uses reversed polish
notation (just like HP calculators 3 2 * give 6), that @ is put
on the stack the value whose address is taken from the stack,
that ! is store a value at an address etc... But that holds for
What is tremendous with Forth is that it is of the keep it
simple type. That there are no such things as "what is that
compiler not understanding". You may examine it down to the
lowest level. And you may change it too to make it do what you
like. You can even invent at the syntax level. Some say it's a
system to write a compiler. You never find the limits of your
Of course, nothing is perfect. The strongest restriction I
find to most Forth systems (including mine) is their inablity to
use more than 64K (for code anyway, tricks with data can put them
anywhere). But you go a long way with that (IBM PC BASIC does no
better after all). 80% of commonly written programs are below
that limit. And Forth produces tighter code. Other criticisms
towards commonly known Forth systems say they are closed systems,
akward editor, little source code available, useless to write DOS
applications. True, but that's just what I have been trying to
overcome. And I think I succeeded. That's why I called it
Comforth. Read a good book about Forth, then look at the
specifications below. You get an incredible amount at a giveaway
price. And what I wish most is to make people happy with Forth
programming. All of my Forth friends now are.
The source code
\ AMP 28mar1987 POLYCOPY a fast and friendly 360K diskettes copy program
\ programmed with DIALOGIC Comforth
CR .( Polycopy ) CR
FLOAD COMMON\EXTFORTH.F83 \ Comforth Forth extensions
FLOAD MSDOS\EXTMSDOS.F83 \ Comforth MSDOS extensions
FLOAD 8086\EXT8086.F83 \ Comforth 8086 extensions
FLOAD MSDOS\IBMPC.F83 \ Comforth IBMPC customization
DECIMAL 20 CONSTANT MSGMAX
FLOAD COMMON\MESSAGES.F83 \ Comforth "messages from a file"
HEXA 400 DATA.SIZE
\ I/O characteristics
2 CONSTANT SECTOR.SIZE
9 CONSTANT SECTORS
2 CONSTANT SIDES
40 CONSTANT TRACKS
20 CONSTANT READ.RETRIES
5 CONSTANT COPY.RETRIES
CODE 80862@ \ offs seg --- 16b1 16b0
DS , DX MOV BX POP
DX , 2 [BX] MOV DX PUSH
DX , 0 [BX] MOV
AX , CS MOV DS , AX MOV NEXT END-CODE
CODE 80862! \ 16b1 16b0 offs seg ---
DS , DX MOV BX POP
AX POP 0 [BX] , AX MOV
AX POP 2 [BX] , AX MOV
AX , CS MOV DS , AX MOV DX POP NEXT END-CODE
\ I/O parameters
VARIABLE SECTOR 1 SECTOR C! \ testing
VARIABLE SEGMENT \ paragraph of I/O buffer
\ format parameters
DF C, \ SRT / HD unload
02 C, \ HD load / mode=DMA
25 C, \ motor wait
SECTOR.SIZE C, \ 512 bps
SECTORS C, \ last sector
20 C, \ gap length for R/W
FF C, \ DTL
38 C, \ FORMAT gap length
F6 C, \ FORMAT fill byte
00 C, \ head settle
01 C, \ motor start time
CREATE SYSTEM.DISK.BASE 4 0-ALLOT \ where system pointer saved
FORTHSEG DISK.BASE 78 0 2DUP
80862@ SYSTEM.DISK.BASE 2! \ save system pointer
80862! ; \ set our own
SYSTEM.DISK.BASE 2@ 78 0 80862! ; \ restored as saved above
4 SECTORS * CONSTANT FORMAT.BUFFER.SIZE \ CHRN table size
0 CONSTANT FORMAT.BUFFER.SEGMENT \ and pointer
: INIT.FORMAT.BUFFER \ R and N only once
2 \ initial running offset
SECTORS 1+ 1 DO
I SECTOR.SIZE >< + \ combined NR
OVER FORMAT.BUFFER.SEGMENT 8086!
CODE FILL.FORMAT.TABLE \ done for each track, time critical
ES , 'B FORMAT.BUFFER.SEGMENT MOV
AH , HEAD MOV AL , TRACK MOV \ HC value to store
BX , # FORMAT.BUFFER.SIZE MOV \ to format buffer
BEGIN BX , # 4 SUB NB WHILE ES: [BX] , AX MOV REPEAT
DS PUSH ES POP NEXT END-CODE
20 CONSTANT BOX.WIDTH
04 CONSTANT BOX.LEFT
09 CONSTANT BOX.TOP
06 CONSTANT BOX.SPACING
: VIDEO.MODE \ mode -- : set IBM PC video mode
0 0 0 10 8086INT 2DROP 2DROP DROP CLS ;
1 VIDEO.MODE ;
2 VIDEO.MODE ;
: BELLS ( count -- ) 0 DO BELL LOOP ;
: BOX.START \ drive# -- col line : compute top left screen position
BOX.SPACING * BOX.TOP + BOX.LEFT SWAP ;
: STATUS.LINE \ msga msgl -- : display one line of status box
BOX.WIDTH MIN \ tsss tsss tsss ...
BOX.LEFT LINE# @ GOTOXY \ cursor to box left edge, current line
BOX.WIDTH OVER - \ surrounding spaces count
DUP 2/ DUP SPACES - >R \ half to the left
TYPE R> SPACES CR ; \ message and balance to the right
: STATUS.DISPLAY \ drive# msga msgl color -- : draw color box @ posistion
ROT BOX.START GOTOXY \ cursor to starting line
" " STATUS.LINE
" " STATUS.LINE
CREATE \ msg#
DOES> \ drive# --
@ MESSAGE DROP STATUS.DISPLAY ;
DEFINE.MESSAGE 00 007 0 "LECTEUR "
01 STATUS.MESSAGE HOW.TO.END.DISPLAY
DEFINE.MESSAGE 01 00F 0 "TAPEZ 'Esc' POUR TERMINER"
02 STATUS.MESSAGE PROGRAM.END.DISPLAY
DEFINE.MESSAGE 02 08F 0 "TERMINE - TAPEZ UNE TOUCHE"
03 STATUS.MESSAGE INSERT.ORIGINAL.DISPLAY
DEFINE.MESSAGE 03 09F 0 "INSERER DISQUETTE ORIGINALE"
04 STATUS.MESSAGE INSERT.DISPLAY
DEFINE.MESSAGE 04 09F 0 "INSERER DISQUETTE VIERGE"
05 STATUS.MESSAGE READY.DISPLAY
DEFINE.MESSAGE 05 02F 0 "DISQUETTE PRETE POUR COPIE"
06 STATUS.MESSAGE WORKING.DISPLAY
DEFINE.MESSAGE 06 04F 0 "COPIE EN COURS"
07 STATUS.MESSAGE GOOD.DISPLAY
DEFINE.MESSAGE 07 0AF 0 "BONNE COPIE A RETIRER"
08 STATUS.MESSAGE BAD.DISPLAY
DEFINE.MESSAGE 08 0CF 0 "MAUVAISE COPIE A RETIRER"
09 STATUS.MESSAGE ORIGINAL.ERROR.DISPLAY
DEFINE.MESSAGE 09 0CF 0 "DISQUETTE ORIGINALE ILLISIBLE"
0A STATUS.MESSAGE SHORT.MEMORY.DISPLAY
DEFINE.MESSAGE 0A 0CF 0 "PAS ASSEZ DE MEMOIRE"
0B STATUS.MESSAGE READING.ORIGINAL.DISPLAY
DEFINE.MESSAGE 0B 04F 0 "LECTURE DE L'ORIGINAL"
0C STATUS.MESSAGE REMOVE.ORIGINAL.DISPLAY
DEFINE.MESSAGE 0C 09F 0 "RETIRER DISQUETTE ORIGINALE"
: DRIVE.DISPLAY \ char drive# --
BOX.START 1- GOTOXY \ just above box,
0 MESSAGE DROP COLOR C!
TYPE EMIT LOLIGHT ; \ type 'drive' and drive letter
100 0 2000 0 10 8086INT 2DROP 2DROP DROP \ password to hide cursor
1 1 GOTOXY ." POLYCOPY 1.1 by A PIRARD and COMFORTH"
2 3 GOTOXY ." may be freely distributed, but only"
5 4 GOTOXY ." with its intact documentation"
ASCII A 0 DRIVE.DISPLAY 0 INSERT.ORIGINAL.DISPLAY
ASCII B 1 DRIVE.DISPLAY 1 INSERT.DISPLAY
2 HOW.TO.END.DISPLAY ;
\ drives mount monitoring
VARIABLE DRIVES.PROTECT.STATUS \ last sense of drives protect light
0 CONSTANT REMOVED
1 CONSTANT READY
2 CONSTANT DONE
: STATUS \ drive# -- addr
DRIVES.MOUNT.STATUS + ;
3F CONSTANT MOTOR.STATUS \ BIOS data in segment 40
03F2 CONSTANT FDC.CONTROL.PORT \ Floppy disk controller ports
03F4 CONSTANT FDC.STATUS.PORT
03F5 CONSTANT FDC.DATA.PORT
ROUTINE FDCWAIT \ wait until FDC ready for bus I/O
DX PUSH DX , # FDC.STATUS.PORT MOV
BEGIN AL , DX IN AX , # 80 TEST NZ UNTIL \ status port says so
DX POP RET END-CODE
CODE INSERTION.CHANGE? \ drive# -- ? : sense if drive inserted/removed
CLI BX , DX MOV \ disable motor stop, save drive #
AL , BL MOV AL , # 3C OR \ start both drives, select ours
DX , # FDC.CONTROL.PORT MOV DX , AL OUT
DX , # FDC.DATA.PORT MOV CX , FDCWAIT LEA
CX CALL@ AL , # 4 MOV DX , AL OUT \ sense drive status command
CX CALL@ AL , BL MOV DX , AL OUT \ specify drive #
CX CALL@ AL , DX IN AX , # 40 AND \ get drive status, isolate WP bit
DX , AX MOV AL , DRIVES.PROTECT.STATUS [BX] XCHG \ save & update
DL , AL XOR DL , AL AND \ true if different and old is 1
AX , # 40 MOV ES , AX MOV \ address BIOS segment
AL , ES: MOTOR.STATUS MOV AL , # 3 AND \ get BIOS current drive
AL , # 1 SAR AL , # 3C OR \ and re-select it, keep 2 motors on
DX , # FDC.CONTROL.PORT MOV DX , AL OUT
STI DS PUSH ES POP NEXT END-CODE
: DRIVE.MOUNT.TEST \ drive# -- : perform drives status changes, update messages
IF \ diskette was removed or inserted
DUP STATUS DUP C@ CASE
DONE OF OVER INSERT.DISPLAY REMOVED ENDOF \ after written
REMOVED OF OVER READY.DISPLAY READY ENDOF \ blank inserted
DUP ENDCASE \ no change, note: cannot remove blank disk
SWAP C! THEN \ update mount status
\ Drives switching
DRIVE 01 TOGGLE ;
: DRIVE.NAME \ num -- char
ASCII A + ;
: ACTIVE \ -- drive#
DRIVE C@ ;
: IDLE \ -- drive#
DRIVE C@ 01 XOR ;
\ disk I/O
CODE DISK.IO \ operation-type -- error-code
AH , DL MOV \ operation type
DL , DRIVE MOV
DH , HEAD MOV
CH , TRACK MOV
CL , SECTOR MOV
AL , SECTORS # MOV
ES , SEGMENT MOV \ buffer segment
BX , 0 # MOV \ buffer offset is always 0 in segment
13 # INT DL , AH MOV DH , DH XOR \ BIOS disk I/O, return code
DS PUSH ES POP CLD NEXT END-CODE \ restore vital Forth environment
0 DISK.IO DROP ;
CREATE , \ operation-type --
DOES> @ \ -- ? : true if OK
IF ( ." Disk error " DUP U. CR ) \ test error display code
2 DISK.OPERATION DISK.READ
3 DISK.OPERATION DISK.WRITE
4 DISK.OPERATION DISK.VERIFY
5 DISK.OPERATION DISK.FORMAT
: READ.TRACK \ of original
TRUE \ error assumed
READ.RETRIES 0 DO
DISK.READ IF NOT LEAVE THEN
IF ACTIVE ORIGINAL.ERROR.DISPLAY 5 BELLS ABORT THEN ;
: COPY.TRACK \ buffer-segment -- : format, write and verify
COPY.RETRIES 0 DO
FORMAT.BUFFER.SEGMENT SEGMENT ! DISK.FORMAT
IF DUP SEGMENT ! DISK.WRITE
IF IDLE DRIVE.MOUNT.TEST 0= LEAVE THEN THEN THEN
IF ABORT THEN ;
: WAIT.DRIVE.MOUNT \ poll both drives status until active is mounted
KEY? IF KEY 01B = IF ABORT THEN THEN
ACTIVE STATUS C@ READY =
ACTIVE WORKING.DISPLAY \ display ready disk as copying
DISK.RESET ; \ to perform recalibrate instead of seek
\ Read original disk
CREATE SEGMENTS TRACKS SIDES * 2* 2+ 0-ALLOT \ disk buffers segments table
80 SECTOR.SIZE SHIFT 10 / SECTORS * CONSTANT TRACK.SIZE \ in segments
: GET.BUFFER \ of track size, avoid crossing 64K boundaries
TRACK.SIZE GETBLOCK IF ACTIVE SHORT.MEMORY.DISPLAY 5 BELLS ABORT THEN
DUP SEGMENT !
NEGATE 0FFF AND \ distance to 64K boundary
TRACK.SIZE U< NOT
: FREE.BUFFERS \ for testing
SEGMENTS TRACKS SIDES * 2* 2+ BOUNDS DO
I @ ?DUP IF FREEBLOCK DROP THEN 2 +LOOP ;
ONERROR 2 PROGRAM.END.DISPLAY REPLY ABORT
SEGMENTS \ vector running address
TRACKS 0 DO I TRACK !
SIDES 0 DO I HEAD !
GET.BUFFER SEGMENT @ OVER ! 2+ \ keep segment address in table
DONE ACTIVE STATUS C!
\ Copy it to another diskette
ONERROR ACTIVE BAD.DISPLAY 5 BELLS
SEGMENTS \ vector running address
TRACKS 0 DO I TRACK !
SIDES 0 DO I HEAD !
DUP @ COPY.TRACK 2+
ACTIVE GOOD.DISPLAY BELL
DONE ACTIVE STATUS C! ;
\ Main logic
HEX "TOKEN DUP
IF READ.MESSAGES \ alternate messages from command line filename
ELSE 2DROP THEN
DRIVE OFF DRIVES.MOUNT.STATUS OFF
GET.BUFFER SEGMENT @ 'B FORMAT.BUFFER.SEGMENT ! INIT.FORMAT.BUFFER
ONERROR \ Insure screen restore
WAIT.DRIVE.MOUNT ACTIVE READING.ORIGINAL.DISPLAY READ.DISK
ONERROR \ Insure restoring disk parameters
BEGIN SWITCH.DRIVES WAIT.DRIVE.MOUNT COPY.DISK AGAIN
FREE.BUFFERS \ main use is when testing
: RUN POLYCOPY ;
Forth is a programming language that offers the advantages
of both interpreted and compiled languages. Its interactivity
makes it tremendous to experiment problems solutions and quickly
write many applications. Its compiled code gives very fast
execution. It is strongly structured.
Its usual implementations however do not implement
traditional access to the host system files. They are limited to
storing 1024 bytes blocks of data on either an unstructured disk
or its simulation on a single direct access file. Their ability
to generate small executable modules, use chaining etc... is
generally inexstant or limited. This simplifies portability, but
does not make it very useful in traditional operating systems
Comforth is a professionally designed Forth development
system. It is written to combine the powerful interactive
debugging facilities of Forth and the usefulness of traditional
languages. It fully uses the facilities of the host disk
operating system . It defines a very simple file handling
interface which is identical between a variety of common
operating systems on a wide range of machines. It makes possible
the easy generation of very small true modules directly
executable from the host system command level. It particularily
enhances user friendliness and the ease of development by
providing many debugging tools.
COMforth has been successfully used in economical,
scientifical and industrial applications such as accounting,
IBM 3270 terminal emulation and reliable data transfer protocol,
botanical data acquisition and analysis system, geological data
acquisition and analysis (Comforth found gold!), Eprom programmer
control, thermodynamics data acquisition and control, cable
layout computation, pasture fattening mixture computation on
handheld computer etc...
Some of the features described below are natural to other
languages or obscure without Forth knowledge. They are listed to
emphasize how Comforth compares to other Forth implementations.
In summary, the Comforth implementation objective is to
eliminate many inconveniences of traditional Forth systems
practices and provide a (let us say it) comfortable programming
environment similar to say Turbo-Pascal(TM) but with all the
advantages of Forth interactivity.
Notes to the Forth novice: the following text often refers
to the expression "word". A Forth word is what would be called
function or routine in other languages. Words make a sentence
that is either executed or used to define a new word.
- COMforth versions support and allow source portability between:
- MSDOS (version 2.0 or higher, including PCDOS and compatibles)
- CP/M 80 (version 2.0 or higher)
- CP/M 86
- Commodore 64
- Commodore 128 (mode 64, mode 128 or CP/M)
- Sinclair/Timex QL
- Atari ST
- Apple-Dos on Apple II
- Forth-83 standard with didactical Forth-79 and Fig-Forth
compatibility supersets. Of course, assemblers and double words
set. Many many extensions such as CASE, ?LEAVE, ?DO, .S, DUMP,
WITHIN, ROTATE and the like...
- Drastically easy to use system independent interface words to
access host system files in sequential or direct access mode
(FILE OPEN CLOSE LOOK GET PUT READ WRITE READLINE POINT NOTE
INRECORD INFILE INDATA SKIPEOR PUTEOR PUTEOF MUTEIOER IOER DELETE
RENAME...). MSDOS Path support.
- Source code can be maintained in and loaded from free format,
variable length records, operating system ASCII files. No storage
waste, no update nor documentation problems.
- Very handy and complete fullscreen EDITOR to update these
system source files from within Forth. It makes use of general
screen management functions that easily adapt it to any system
(GOTOXY, CLS, RUBLINE, HILIGHT, LOLIGHT). Special keyboard keys
are customizable for editing functions. Exiting the editor can
request interpreting the edit buffer and, in case of error, re-
editing with the cursor positioned at the point of error.
- Interactive command words to manage system files from within
Forth (DIR ERA DEL REN FTYPE FPRINT DOS etc...).
- Blocks use true LRU buffers management. I/O is made on direct
access host files. Line editor.
- COMGEN: Easy host system compact application modules generator.
One just types: COMGEN source-file main-word module-file map-file
It automatically selects the required words and relocates them to
a headerless execution file. Even defining words definition parts
are excluded. However, a user created dictionnary can be isolated
and searched in an application module to provide keywords
- A smart DECOMPILER can be used to examine the code of the
whole system nucleus to the deepest level. This is the way to
answer every possible question and even allow modifying the
compiler itself for specific needs. Compare this to other black
box compilers refusing to understand your program.
- BREAKPOINT facility used in conjunction with the decompiler.
Allows any word execution to be stopped, examined and amended. A
single return keystroke single-steps through the tested word
while displaying the parameter stack.
- Relocatable OVERLAYS creation and loading. Speeds up the
loading of utilities in a development system. The editor,
assemblers, decompiler, breakpoint and module generator are in
overlays. The user can easily create his own overlays.
- FLOATING POINT model (slow) in high level source code. Includes
trigonometric and hyperbolic functions. Designed to be data
representation independent and easily converted to interface any
coprocessor or ROM routines.
- 8087 math coprocessor (fast!) assembler and floating point for
MSDOS and CP/M 86. System ROM floating point for CBM64/128.
- CHAINING from one application module to the other.
- Editor-like command input line editing and previous lines
- Friendly user interfaces. e. g. long lists can be freezed on
the screen by the simple use of the return key and canceled with
the C key.
- The development system is very easily examined, patched,
augmented and saved as a new executable module. The user
variables and bootup literals are paired. Before saving, the
bootup literals can be modified for new default options (storage
allocation, dictionnary type, input/output redefinition
(execution vectors), numerical conversion radix etc...).
- ONERROR protects a code section from ABORT by defining a
recovery words sequence. It is used, for example, by the
breakpoint facility to protect the tested program against ABORTs
produced by interactive debug mode commands. A must for serious
- TEMPORARY and HEADERLESS words to conserve dictionnary space
(e. g. assemble then remove the assembler or remove the no longer
necessary names of words).
- Assembler LABELs can be coded anywhere within machine code
because they generate temporary constants. ENTRY: can be used to
redefine the entry point.
- ONLY ALSO PREVIOUS vocabulary stack search order. Selectable
sealed or linked vocabularies, optional search of CURRENT. These
allow a variety of vocabulary structures, including Fig-Forth
- Facility to implement a user defined word to be executed at
startup and closedown of the application module and/or
development system. Useful for setting up things like a restart
interrupt trap, screen options, printer initialization etc...
Restart interrupts are provided on non-generic systems and PCDOS.
- An aggregate STACK is integrated to easily store LIFO local
variables and data structures. This conserves memory space.
- Character STRINGS words making use of the aggregate stack.
- Input/Output redirection to any device and customizable printer
- Several general and system specific examples and extra gifts
(Assembler examples, Sort, Random numbers, Conditional
compilation, Graphics, Sound etc...)
- Selectable automatic or fixed adjustment of the size of memory
allocated to Forth. Non self-modifying code, word alignment for
faster 6502, 8086 and 68000 operation. Very fast 8088 operation.
Documentation: 65 pages explaining the COMforth special features
+ 60 pages of functionally organized full glossary + 15 pages
alphabetical index. Beginners will require an additional tutorial
Disk_formats: distribution as single sided disquettes on the two
sides of one diskette. Specify your machine, system, disk format
and if you were unable to read single sided.
MSDOS: IBM PC format.
Atari ST: own 3"1/2 MSDOS-like.
Apple Dos: own format.
Commodore 64: own format.
Commodore 128: own format.
Sinclair/Timex QL: own format (tape).
CP/M 80 or 86:
8" single density IBM 3740 format
or one of the following 5"1/4 double density:
IBM PC (CP/M 86) Zenith Z100 Kaypro II Epson QX-10 Osborne I
Other formats on request.
Price: Club price Commercial use (*)
MSDOS: 3600 FB ($90) 6400 FB ($160)
Atari ST: 3600 FB ($90) 6400 FB ($160)
Others: 2400 FB ($60) 6400 FB ($160)
Postage: Europe: 100 FB ($2.5) Others: 300 FB ($7.5)
Order and payment to:
DIALOGIC A. Pirard
Prepaid with postal money order or Eurocheque. To cheques
drawn on foreign banks, add $10 for endorsement.
(*) Only commercial use entitles the licencee to sell royalty-
free aplications compiled with COMGEN and to receive fixes, free
updates and application notes lists.