home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / FPC355_3.ZIP / FPCDOC.ZIP / APPENDXB.TXT < prev    next >
Encoding:
Text File  |  1989-10-29  |  18.9 KB  |  520 lines

  1. B-1
  2.  
  3.  
  4. APPENDIX B:  SAMPLES AND TUTORIALS
  5.  
  6.  
  7.  
  8.  
  9. F-PC is such a monstrous system that most Forth users would feel lost
  10. facing it the first time.  To make a new user feel more at home with it
  11. and help him overcome the initial shock, Tom Zimmer prepared a set of
  12. tutorial examples illustrating many unique and interesting features in
  13. F-PC. These examples are collected in the EXAMPLES.ARC file.  You will
  14. also find many good tutorial materials in the user contributed files.
  15. However, these user contributed files are more application oriented and
  16. do assume that you are familiar with the F-PC system.
  17.  
  18.  
  19. B1.   MEMORY ALLOCATION
  20.  
  21.  
  22. SALLOC.SEQ contains an example of how to use the memory allocation and
  23. deallocation words. This example allocates space at F-PC cold start time
  24. by placing the word MY-INIT into the deferred word chain called
  25. INITSTUFF.  You do not have to allocate your memory at this time, but it
  26. will prevent your memory allocation from interfering with the editor's
  27. usage of memory.  It is fairly easy using allocation and deallocation to
  28. cause memory to get fragmented to the point where almost any ALLOC will
  29. fail.
  30.  
  31.  
  32. hidden clearmem forth           \ make sure the editor is not using memory
  33.  
  34. 16000 constant bytes_needed     \ Size of the array I need in bytes.
  35.  
  36. 0 value myseg                   \ a place to put my base segment pointer.
  37.  
  38. : alloc-myseg   ( --- )         \ allocate the space I need
  39.         myseg ?exit             \ don't allocate again if already done
  40.         bytes_needed paragraph  \ adjust needed to # of paragraphs
  41.         alloc                   \ allocate the space test for error in alloc
  42.         8 = abort" Not enough memory forMYSEG"
  43.         nip                     \ discard largest block available
  44.         !> myseg ;              \ asign start of array into MYSEG
  45.  
  46. alloc-myseg                     \ really allocate the space now so we can
  47.                                 \ experiment
  48.  
  49. : my-init       ( --- )
  50.                 defers initstuff \ inserted into INITSTUFF chain
  51.                 off> myseg
  52.                 alloc-myseg ;
  53.  
  54. \ ' my-init is init-stuff       \ un-comment this line to cause
  55.                                 \ initialization to be done at cold boot
  56.  
  57. If you need to deallocate the space that you have allocated, you can use
  58. DEALLOC to release the space back to DOS.
  59.  
  60. : release-myseg ( -- )
  61.         myseg dealloc abort" failed to deallocate MYSEG" ;
  62.  
  63. The other operation you can perform on an allocated memory segment is to
  64. resize it to a new size. This is done with SETBLOCK.
  65.  
  66. : resize-myseg  ( n1 -- )       \ adjust myseg to new size n1 in bytes
  67.         myseg swap paragraph setblock
  68.         abort" Failed to resize MYSEG" ;
  69.  
  70. To put something into the array MYSEG, I might do something like the
  71. following.
  72.  
  73. : string-save   ( | <string> -- )       \ accept a <string> to save
  74.         ?cs: 0 word dup>r               \ moving FROM here
  75.         myseg 0                         \ TO the beginning of MYSEG
  76.         r> c@ 1+ CMOVEL ;               \ move the data with CMOVE LONG
  77.  
  78. And you can then display the text from MYSEG.
  79.  
  80. : type-string   ( -- )
  81.         myseg 0                         \ FROM myseg
  82.         2dup c@L >r                     \ fetch the count
  83.         ?cs: here                       \ TO here
  84.         r> 1+ CMOVEL                    \ move data to HERE
  85.         here count type ;               \ display it
  86.  
  87.  
  88. B2.   USER BOOT PROCESS
  89.  
  90.  
  91. SBOOT.SEQ contains an example of how to make F-PC perform your own
  92. function in place of starting F-PC and just running Forth.  Before
  93. describing how to modify F-PC, let us first look at the things F-PC does
  94. at BOOT time so you can have a better understanding of the startup
  95. process.
  96.  
  97. At BOOT time F-PC proceeds through the following sequence:
  98.  
  99. : COLD
  100. {deferred}      SETSEG
  101.                         Setup Segments
  102.                         Verify DOS > 2
  103.                         Adjust memory allocation
  104.                         Seg cursor position
  105. {deferred}      VMODE.SET
  106.                         test Video mode
  107.                         Adjust display attributes
  108. {deferred}      >COLOR
  109.                         or
  110. {deferred}      >MONO
  111.                         Set the Video segment
  112. {deferred}      INITSTUFF
  113. \ Various initializations, performed in a chain through this
  114. \ Deferred word. Things like:
  115.                         MACROS
  116.                         EDITOR
  117.                         SAVE SCREEN
  118.                         READ BUFFER SIZE
  119.                         FILE SYSTEM
  120.                         DIRECTORY BUFFER etc.
  121. {deferred}      BOOT
  122.                         HELLO
  123.                         Initialize TIB
  124.                         Initialize VOCABULARY to FORTH
  125. {deferred}      DEFAULT
  126.                         HDEFAULT
  127.                         Move command line to TIB
  128.                         OPEN a file if available
  129. {deferred}      .HELLO
  130.                         Display signon message
  131. {deferred}      .CURFILE
  132.                         Display current file
  133. {deferred}      INTERPRET
  134.                         Process command line
  135.                 QUIT ;
  136.  
  137. As you can see from the above sequence, there are several places you can
  138. modify what F-PC does at boot time. A substantial portion of the above
  139. process must be done, and so we want to be careful to tie in at the right
  140. point.  In general eveything before BOOT must be done for F-PC to operate
  141. properly. If we tie in at BOOT though we will have to do some additional
  142. initialization to specifically much of the stuff done by HELLO.  If we
  143. tie in at DEFAULT, we usually still want the DOS command line to be moved
  144. to TIB, and probably still want a file to be opened, so my normal choice
  145. would be to use DEFERS to link into DEFAULT without eliminating the
  146. function that is already there.  This will then turn DEFAULT into a
  147. DEFERred chain.  If we want in addition to have our own sign-on message,
  148. we can replace the functions in .HELLO and/or .CURFILE although a user
  149. application need not return from the chained DEFAULT, and as such .HELLO
  150. will never get performed.  Here then without further delay is MYDEFAULT.
  151.  
  152. : mydefault     ( -- )
  153.         defers default          \ link into default as additional
  154.                                 \ stuff to be done.
  155.  
  156. \ Your program stuff goes here. 
  157. \ *****************************
  158.  
  159.         cr ." This is my program "
  160.         cr ." Press a key to terminate "
  161.         key drop                \ wait for a key before leaving
  162.         cr
  163.  
  164. \ This ends your program, so leave. 
  165. \ *************************
  166.  
  167.         bye ;                   \ got it so leave
  168.  
  169. ' mydefault is default
  170.  
  171. FSAVE MYBOOT.EXE                \ Now save the system back to disk with the
  172.                                 \ name MYBOOT.EXE.
  173.  
  174.  
  175. B3.  F-PC KEYSTROKE MACROS
  176.  
  177.  
  178. SMACRO.SEQ contains an example of how to use macros in the F-PC editor to
  179. reduce the keystrokes required to perform a given task.  The first
  180. example is a real one.  We want to shorten the glossary entries.  A
  181. typical entry is shown below for +! :
  182.  
  183. +!              ( n1 a1 -- )
  184.                 FORTH           KERNEL1
  185.         Increment the value at a1 by n1.  This is equivalent
  186.         to the following:   DUP @ ROT + SWAP ! but
  187.         much faster.
  188.  
  189. Since all of the words in the glossary are in the  FORTH  vocabulary, we
  190. can delete the word FORTH .  Furthermore,  the second line containing the
  191. source file name can be joint with the first line, and  a little more
  192. editing can also be done at the same time.  The desired new entry would
  193. be:
  194.  
  195. +!              ( n1 a1 -- )            KERNEL1
  196.         Increment the value at a1 by n1.  This is equivalent
  197.         to the following:   DUP @ ROT + SWAP ! but
  198.         much faster.
  199.  
  200. The glossary is a very large file, and the manual editing required to
  201. correct this would have been prohibitive, so a macro is created to join
  202. the second line with the first line and remove the Vocabulary from each
  203. entry when a single MACRO key is pressed.
  204.  
  205. Here then is the key sequence that will make a macro to join the first
  206. and second lines of the second type glossary entry and remove the
  207. vocabulary from the entry.  The macro will then go to the next paragraph
  208. which starts the next entry.
  209.  
  210. This macro is always executed when the cursor in on the first line of a
  211. glossary entry at the leftmost column, and we are in INSERT mode.
  212.  
  213.         Alt-M           Start a MACRO
  214.         Alt-1           We are starting the macro for Alt-1
  215.         INS             Select OVERWRITE mode
  216.         TAB             Move to first TAB position
  217.         Ctrl-T          Remove spaces before stack picture
  218.         TAB             Move to 2nd TAB
  219.         TAB             Move to 3rd TAB
  220.         TAB             Move to 4th TAB
  221.         INS             Go back into INSERT mode
  222.         DEL             Delete the last char in the line forcing a join line. Cursor is now on
  223.                         the word FORTH
  224.         Ctrl-T          Delete the Vocabulary
  225.         HOME            Move back to beginning of line
  226.         Alt-G_N         Goto Next paragraph
  227.         Alt-M           Complete macro
  228.  
  229. Macros are performed as they are created, so you must be on a glossary
  230. entry that needs to be modified while you are in the process of making
  231. the macro.
  232.  
  233. In the following section I have included several copies of the +!
  234. glossary entry.  Try making the macro described above while you are on
  235. the first entry, then press Alt-1 to try the macro on each successive
  236. entry.
  237.  
  238. Macros can be saved with Alt-M_S, and loaded again with Alt-M_L.  You can
  239. view the currently defined macros with Alt-M_V, but they will look very
  240. funny since they are mostly graphics characters.
  241.  
  242.  
  243. ----------------------  Try some macros here --------------------
  244.  
  245. +!              ( n1 a1 -- )
  246.                 FORTH           KERNEL1
  247.         Increment the value at a1 by n1.  This is equivalent
  248.         to the following:   DUP @ ROT + SWAP ! but
  249.         much faster.
  250.  
  251. +!              ( n1 a1 -- )
  252.                 FORTH           KERNEL1
  253.         Increment the value at a1 by n1.  This is equivalent
  254.         to the following:   DUP @ ROT + SWAP ! but
  255.         much faster.
  256.  
  257. +!              ( n1 a1 -- )
  258.                 FORTH           KERNEL1
  259.         Increment the value at a1 by n1.  This is equivalent
  260.         to the following:   DUP @ ROT + SWAP ! but
  261.         much faster.
  262.  
  263. +!              ( n1 a1 -- )
  264.                 FORTH           KERNEL1
  265.         Increment the value at a1 by n1.  This is equivalent
  266.         to the following:   DUP @ ROT + SWAP ! but
  267.         much faster.
  268.  
  269. +!              ( n1 a1 -- )
  270.                 FORTH           KERNEL1
  271.         Increment the value at a1 by n1.  This is equivalent
  272.         to the following:   DUP @ ROT + SWAP ! but
  273.         much faster.
  274.  
  275. +!              ( n1 a1 -- )
  276.                 FORTH           KERNEL1
  277.         Increment the value at a1 by n1.  This is equivalent
  278.         to the following:   DUP @ ROT + SWAP ! but
  279.         much faster.
  280.  
  281. HRENAME ( handle1 handle2 -- return-code )
  282.                 FORTH           HANDLES
  283.         Change the name of the file specified in handle1 to the name
  284.         specified in handle2. Can be used to move a file from one
  285.         directory to another on the same drive. Returns 18 if the
  286.         rename was good, not zero.
  287.  
  288. HRENAME ( handle1 handle2 -- return-code )
  289.                 FORTH           HANDLES
  290.         Change the name of the file specified in handle1 to the name
  291.         specified in handle2. Can be used to move a file from one
  292.         directory to another on the same drive. Returns 18 if the
  293.         rename was good, not zero.
  294.  
  295. As you can see, having performed the macro on one of the last two
  296. glossary entries for HRENAME, a macro will not always work as you expect.
  297. If the information being manipulated does not follow the rules, you can
  298. get quite unexpected results.  Use caution with macro, they can be
  299. wonderful time savers, but it is difficult to make a macro that will
  300. always work.
  301.  
  302. This is only the start for macros.  Experiment with some junk text to see
  303. what other neat things they can do.  When you leave this file you
  304. probably DO NOT want to save your changes.
  305.  
  306. Press  Alt-F10  to leave SED without saving any changes.
  307.  
  308. cr .( Use LISTING to print this file and then try editing it. )
  309.  
  310.  
  311. B4.  A SAMPLE MENU FILE
  312.  
  313.  
  314. SMENU.SEQ is an example of menu usage.  You can make a copy of this file
  315. and edit it to suit your need.  Deferred routine to handle all keys the
  316. menu handler doesn't understand.  It can be used to insert any unknown
  317. key pressed in an editor if you want, or it can just throw the keys away
  318. as is done here. The character the menu driver didn't understand is on
  319. the stack when AOTHER is called.
  320.  
  321. The word AMENU is then called whenever a menu operation is to be
  322. performed.  In an editing application, use ESC to enable this menu.  To
  323. do this you look for the user to press the ESC key while typing in text.
  324. If ESC key is pressed, then execute RMENU rather than inserting the next
  325. key pressed.
  326.  
  327.  
  328. only forth also definitions hidden also
  329.  
  330. \ Install the functions into these deferred words you want performed when
  331. \ a menu item is selected.
  332.  
  333. defer item1
  334. defer item2
  335. defer item3
  336. defer item4
  337. defer item5
  338. defer item6
  339. defer item7
  340. defer item8
  341. defer item9
  342.  
  343. 0 value amsave                  \ a place to save the previous menu column
  344. 0 value amline                  \ Menu starting line and column on screen
  345. 0 value amcolumn
  346.  
  347. newmenu menu1$
  348.         menuline"  A item1            Alt-1 " item1
  349.         menuline"  B item2            Alt-2 " item2
  350.         menuline" --------------------------" noop
  351.         menuline"  C item3                     " item3
  352.         menuline"  D item4            Alt-4 " item4
  353.         menuline" --------------------------" noop
  354.         menuline"  Quit item5           F10 " item5
  355. endmenu
  356.  
  357. newmenu menu2$
  358.         menuline"  E item6            Alt-6 " item6
  359.         menuline"  F item7            Alt-7 " item7
  360.         menuline" --------------------------" noop
  361.         menuline"  G item8               F8 " item8
  362.         menuline" --------------------------" noop
  363.         menuline"  H item9               F9 " item9
  364. endmenu
  365.  
  366. newmenubar amenubar 
  367.                 +," A menu1 "   \ the menu bar contains only two items
  368.                 +," B menu2 "
  369. endmenu
  370.  
  371. create amenulist menu1$ ,       \ and two lists of functions
  372.                 menu2$ ,
  373.  
  374. \ initialize the default condition of the menu bar
  375.  
  376. amenubar   =: menubar
  377. amenulist  =: menulist
  378. ' amline   is mline
  379. ' amcolumn is mcolumn
  380. ' drop     is doother
  381.  
  382. defer aother            ' drop is aother
  383.  
  384. : amenu ( -- )                  \ the sample menu driver
  385.         amsave =: mcol
  386.         savemenu
  387.         amenubar     =: menubar
  388.         amenulist    =: menulist
  389.         ['] amline   is mline
  390.         ['] amcolumn is mcolumn
  391.         ['] aother   is doother
  392.         menu
  393.         restmenu
  394.         mcol =: amsave ;
  395.  
  396.  
  397. B5.  MY STARTUP MESSAGE
  398.  
  399.  
  400. SMESSAGE.SEQ contains an example of how to change the sign-on message to
  401. display a user defined message in place of the default system message.
  402.  
  403. : myhello       ( -- )
  404.         ." Hello!"  ;           \ here is the message
  405.  
  406. ' myhello is .hello             \ install new hello function into .HELLO
  407.  
  408. \ We will also disable the displaying of the current file at boot time
  409.  
  410. ' noop is .curfile
  411.  
  412.  
  413. B6.   SUBSCREEN SCROLLING
  414.  
  415.  
  416. SSCROLL.SEQ contains an example of how to make the screen scroll only a
  417. limited set of lines. The file contains three user words as follows:
  418.  
  419.         SUB-SET ( n1 -- )       \ set the line where scrolling starts
  420.         SUB-ON                  \ start sub screen scrolling
  421.         SUB-OFF                 \ stop sub screen scrolling
  422.  
  423. Following is the code to implement sub-screen scrolling:
  424.  
  425. 0 value sub-line
  426.  
  427. : sub-scroll    ( -- )          \ scroll only a portion of the screen
  428.         #line @ sub-line <
  429.         if      crlf            \ scroll only a portion
  430.         else    0 sub-line 1 max rows 1- min at -line
  431.                 0 rows 1- at    \ move to last line of screen
  432.         then    ;
  433.  
  434. \ ******************* User words start here *******************
  435.  
  436. : sub-set       ( n1 -- )       \ set the starting sub screen scroll line
  437.         1 max 23 min !> sub-line ;
  438.  
  439. : sub-on        ( -- )          \ Turn on sub screen scrolling
  440.         ['] sub-scroll is cr ;
  441.  
  442. : sub-off       ( -- )          \ Turn off sub screen scrolling
  443.         ['] crlf is cr ;
  444.  
  445.  
  446. B7.   USAGE OF VALUES
  447.  
  448.  
  449. SVALUES.SEQ contains an example of how an existing program can be
  450. modified to use a VALUE word in place of a VARIABLE to enhance program
  451. readability and performance.  You must be aware that VALUEs are not
  452. portable.  It will make your programs more difficult to move to another
  453. Forth system.
  454.  
  455. Observe the use of the word COUNTER in the following program segments.
  456.  
  457. \ Program segment using a VARIABLE named COUNTER
  458.  
  459. create vowels ," aeiouAEIOU"
  460. variable counter
  461.  
  462. : vcount        ( | <string> -- )       \ get count of vowels in <string>
  463.         counter off
  464.         0 word  drop
  465.         vowels count bounds
  466.         ?do             here count
  467.                 begin   i c@ scan dup
  468.                 while   1 counter +!
  469.                         1 -1 d+
  470.                 repeat  2drop
  471.         loop
  472.         cr ." Found "
  473.         counter @ . ." vowels" ;
  474.  
  475. \ Program segment using a VALUE named COUNTER
  476.  
  477. create vowels ," aeiouAEIOU"
  478. 0 value counter
  479.  
  480. : vvcount       ( | <string> -- )       \ get count of vowels in <string>
  481.         off> counter
  482.         0 word drop
  483.         vowels count bounds
  484.         ?do      here count
  485.                 begin   i c@ scan dup
  486.                 while   incr> counter
  487.                         1 -1 d+
  488.                 repeat  2drop
  489.         loop
  490.         cr ." Found "
  491.         counter . ." vowels" ;
  492.  
  493.  
  494. B8.  POPUP WINDOW
  495.  
  496.  
  497. SWINDOW.SEQ contains an example on how to make a popup window.  While it
  498. may seem complicated at first, we are really doing only a few simple
  499. things.  We save the screen positon, turn off the cursor, and save the
  500. screen before drawing the box and writing into it. After the user views
  501. the box and presses a key, we restore the things we saved.  It is
  502. actually pretty simple.
  503.  
  504. : popup ( -- )
  505.         #out @ #line @ 2>r      \ save cursor position for later
  506.         cursor-off              \ remove cursor from screen
  507.         savescr                 \ preserve current screen contents
  508.         15 05 60 09 box&fill    \ DRAW THE BOX on the screen
  509.                                 \ PUT SOME TEXT IN IT
  510.         ."        This is a sample POPUP window" bcr
  511.                                 \ following line in reverse video
  512.         >rev ."    Screen attributes can be used as well    "
  513.         >norm bcr
  514.         ."  Press a key to restore the previous screen"
  515.         key drop                \ wait for user to press a key
  516.         restscr                 \ restore previous screen
  517.         cursor-on               \ turn cursor back on
  518.         2r> at ;                \ restore cursor position
  519.  
  520.