Kestrel-3

Check-in [bfb02a2af0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:I think I have completed the refinement of the boot menu logic. I feel confident I can proceed with the boot source discovery.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: bfb02a2af0dce97875e8e52b465bb35916d982e405d7122d6df24f51477b7af5
User & Date: kc5tja 2019-09-10 05:48:44.415
Context
2019-09-11
03:25
Simplify forth auto-load block logic check-in: 46379ac38b user: kc5tja tags: trunk
2019-09-10
05:48
I think I have completed the refinement of the boot menu logic. I feel confident I can proceed with the boot source discovery. check-in: bfb02a2af0 user: kc5tja tags: trunk
04:30
Switch methods of tracking which steps need refinement. This seems to be an easier approach, and I can track progress in an automated manner with clever use of grep. check-in: 01899c8062 user: kc5tja tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to REPORT.org.
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

The boot menu itself can be implemented in Forth, before the user ever
sees an OK prompt.  Selecting option 1 simply exits the menu, clears
the dictionary and stacks, and invokes ~LOAD~ on a well-defined block.
When that's done, it drops to the OK prompt.  Selecting option 2 exits
the menu, clears the dictionary and stacks, but just drops to an OK
prompt.  No attempt is made to auto-load any blocks.








The user may re-enter the boot menu at any time by invoking the word
~BYE~, so as to exit from the Forth environment.

I anticipate that this is what the firmware should perform upon





cold-boot:








#+BEGIN_SRC
  TO cold-boot the Kestrel-3 DO
U   Relocate the ROM image into RAM for faster performance.
U   Initialize the Forth binary interface.
R   Cold-boot the Forth interpreter.
  END
#+END_SRC

Since the system's flash ROM is a serial device, the processor will
need to wait hundreds of clock cycles for each instruction it executes
out of ROM.  This is why we relocate the software image in ROM into
RAM before executing the rest of the bootstrap process.

Initializing the Forth binary interface involves determining
(statically or dynamically) where to place the data and return stacks,
any user and global variables, and of course the dictionary itself.

Once the VM has been established, we can then "cold boot" the Forth
environment.  It is here that the boot menu is built and presented to
the user.

#+BEGIN_SRC
  TO cold-boot the Forth interpreter DO
R   Direct console I/O to the operator's console.

R   Configure the Forth bootmenu items.
R   Show startup banner.
R   Discover available bootable volumes.
O   Start at first page of menu items.
    DO FOREVER
R     Present menu to the operator.
O     Wait for a key.

U     IF selection made identifies a boot option THEN

R       Attempt to boot from the selected source.

O       Notify the user of the failed boot attempt.
O     ELSIF operator wants to page the list down THEN
U       Advance to next page of items.
O     ELSIF operator wants to page the list up THEN
U       Retreat to previous page of items.
      ELSE
O       Notify the user of the erroneous selection.

      END
    END
  END
#+END_SRC

Device discovery necessarily implies device configuration as well.  In
the case of the operator's console, this should be configured







>
>
>
>
>
>
>




|
>
>
>
>
>
|
>
>
>
>
>
>
>









<
<
<
<
<
<
<
<
<







>
|


<



>
|
>
|
>
|
<
<
<
<
|
|
>







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

The boot menu itself can be implemented in Forth, before the user ever
sees an OK prompt.  Selecting option 1 simply exits the menu, clears
the dictionary and stacks, and invokes ~LOAD~ on a well-defined block.
When that's done, it drops to the OK prompt.  Selecting option 2 exits
the menu, clears the dictionary and stacks, but just drops to an OK
prompt.  No attempt is made to auto-load any blocks.

Because only a single key press is sufficient to make a boot menu
selection, we restrict the set of keys capable of making a valid
selection.  These keys include ~0~ to ~9~, and ~A~ to ~Z~.  Lowercase
letters are converted to uppercase for operator convenience.  Thus,
our boot menu is restricted to 36 items maximum, two of which are
reserved for booting into the ROM-resident Forth system.

The user may re-enter the boot menu at any time by invoking the word
~BYE~, so as to exit from the Forth environment.

Upon power-on, the first thing the computer must do is establish its
runtime environment.  Since the system's flash ROM is a serial device,
the processor will need to wait hundreds of clock cycles for each
instruction it executes out of ROM.  To eliminate this waste, we first
copy the contents of ROM into RAM before executing Forth's main entry
point.

Initializing the Forth binary interface involves determining
(statically or dynamically) where to place the data and return stacks,
any user and global variables, and of course the dictionary itself.
Since this is only a small handful of instructions, we can perform
these steps in ROM without concern for efficiency.  This also allows
us to only copy the Forth software into RAM, and not the entire
contents of ROM, which will conserve RAM resources.

#+BEGIN_SRC
  TO cold-boot the Kestrel-3 DO
U   Relocate the ROM image into RAM for faster performance.
U   Initialize the Forth binary interface.
R   Cold-boot the Forth interpreter.
  END
#+END_SRC










Once the VM has been established, we can then "cold boot" the Forth
environment.  It is here that the boot menu is built and presented to
the user.

#+BEGIN_SRC
  TO cold-boot the Forth interpreter DO
R   Direct console I/O to the operator's console.
O   Zero the boot menu item vector.
R   Configure the Forth boot menu items.
R   Show startup banner.
R   Discover available bootable volumes.

    DO FOREVER
R     Present menu to the operator.
O     Wait for a key.
O     Convert letter to uppercase.
O     IF key in set {'0'..'9', 'A'..'Z'} THEN
O       Convert key to a candidate menu item number (0 <= i < 36).
O       IF menu item (key) has non-nil handler THEN
O         Delegate control to menu item (key)'s handler with corresponding parameter.
O         Notify the user of the failed boot attempt.




        ELSE
O         Notify the user of the erroneous selection.
        END
      END
    END
  END
#+END_SRC

Device discovery necessarily implies device configuration as well.  In
the case of the operator's console, this should be configured
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

Boot menu items are described using a collection of menu item
descriptors.  Each descriptor binds a key that a user can press on the
keyboard to a particular boot action.  See the data structures chapter
for a complete description.

#+BEGIN_SRC
  TO Configure the Forth bootmenu items DO




U   Create a menu item descriptor that binds key 0 to boot into Forth environment w/out Auto-Load.

U   Create a menu item descriptor that binds key 1 to boot into Forth environment with Auto-Load.





  END
#+END_SRC


Assuming that the user's console is 80x25 characters in size, we can
reasonably display up to 16 items on a single screen.  If there are
more than 16 items to display, we'll need a mechanism for paging the
display.  Up to 36 items should be easily supported, being keyed to
'0'..'9', then 'A'..'Z'.

#+BEGIN_SRC
  TO Present menu to the operator DO


U   Clear the screen.
R   Show startup banner.







U   Skip to the item which is to appear first.










O   Start menu item counter at 0.


O   DO WHILE fewer than 16 items have been shown AND more items are left to print















O     Print the menu key and item description.

O     Count the menu item.






    END

O   Print page up/down menu items.


O   Prompt user for which action to take.






  END
#+END_SRC

When booting into the Forth environment, the following sequence of
code can be performed.  Note that the decision of whether or not to
auto-load was made when the user selected the appropriate menu
selection in the boot screen.

#+BEGIN_SRC
  TO boot into Forth environment DO
O   IF user wants to perform auto-boot sequence DO
U     Find valid Forth auto-start block.
O     IF found THEN
O       Load Forth auto-start block.
      ELSE
O        Report that no auto-start block was found.
      END
    ELSE
O     Report that auto-start was skipped on user request.
    END
O   Quit into Forth interpreter.
  END
#+END_SRC

We attempt to boot into a particular selection by invoking its custom
handler.  If the handler ever returns, then we can safely assume the
boot attempt failed.  It's expected that software which is
bootstrapped into will generally not return.

#+BEGIN_SRC
  TO attempt to boot from the selected source DO
O   Delegate control to handler specified by the selected menu item, passing the provided parameter as an argument.
  END
#+END_SRC

* Forth Interpreter
** Interpreter
I probably won't delve as deeply into the innards of the Forth
environment as I will other components of the firmware, if only
because of how fluid Forth's implementation details can be.  However,







|
>
>
>
>
|
>
|
>
>
>
>
>



>
|
|
<
<
<



>
>
|

>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
|
>
|
>
>
|
>
>
>
>
>
>






















<
<
<
<
<
<
<
<
<
<
<







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

Boot menu items are described using a collection of menu item
descriptors.  Each descriptor binds a key that a user can press on the
keyboard to a particular boot action.  See the data structures chapter
for a complete description.

#+BEGIN_SRC
  TO Configure the Forth boot menu items DO
R   Bind menu item (0) to (boot into Forth environment) with (no auto-load) named (Kestrel Forth (Debug)).
R   Bind menu item (1) to (boot into Forth environment) with (auto-load) named (Kestrel Forth).
  END
#+END_SRC

Menu items can be created by filling in appropriate fields.

#+BEGIN_SRC
  TO Bind menu item (i) to (f) with (param) named (name) DO
O   Set menu item (i) field handler to (f).
O   Set menu item (i) field parameter to (param).
O   Set menu item (i) name to (name).
  END
#+END_SRC

Recall that our boot menu is restricted to 36 items.  Assuming that
the user's console is 80x25 characters in size, we can reasonably
display up to two columns of selections across 18 rows.




#+BEGIN_SRC
  TO Present menu to the operator DO
    PRECONDITION: len(formatting buffer) >= 80
    PRECONDITION: menu item vector initialized.
R   Clear the screen.
R   Show startup banner.
    FOR i = 0 TO 17 DO
R     Format left and right columns for row (i).
O     Print formatting buffer.
    END
O   Prompt user for which action to take.
  END
#+END_SRC

As a matter of simplification, we constrain boot menu items to 35 or
fewer characters.  In order to fit two columns on the screen, no
single column can exceed 38 characters (giving 2 characters of padding
in between them).  The key is expected to take three characters, since
it'll be formatted with something like ~X._~ (where the underscore is
a stand-in for a blank).  That leaves 35 characters for the item
description.  If the boot image names are constrained to 35 characters
or less (or, equally viable, if we truncate after 35 characters in
length), then can render the menu without excessive complexity in
display formatting logic.

To minimize complexity, we pre-render each row in the menu into a
formatting buffer wide enough to handle a full screen width.

#+BEGIN_SRC
  TO format left and right columns for row (i) DO
  PRECONDITION: 0 <= i < len(vector of menu items)
  PRECONDITION: len(formatting buffer) >= 80
O   Clear formatting buffer.
O   IF menu item i exists THEN
O     Set format margin to start of left column.
R     Format key and description for menu item (i).
    END
O   IF menu item i+18 exists THEN
O     Set format margin to start of right column.
R     Format key and description for menu item (i+18).
    END
  END
#+END_SRC

Each column is formatted uniformly.

#+BEGIN_SRC
  TO format key and description for menu item (i) DO
  PRECONDITION: 0 <= formatting offset < len(formatting buffer)-len(menu item description)-3
R   Write out key selector for item (i).
O   Write out menu item (i) description.
  POSTCONDITION: formatting offset <= len(formatting buffer)
  END
#+END_SRC

The key selector for a boot menu item should come from the set of
valid characters, discussed above.

#+BEGIN_SRC
  TO write out key selector for item (i) DO
  PRECONDITION: 0 <= formatting offset <= len(formatting buffer)-3
O   Emit the number (i) in base-36.
O   Emit ". "
  POSTCONDITION: 3 <= formatting offset <= len(formatting buffer)
  END
#+END_SRC

When booting into the Forth environment, the following sequence of
code can be performed.  Note that the decision of whether or not to
auto-load was made when the user selected the appropriate menu
selection in the boot screen.

#+BEGIN_SRC
  TO boot into Forth environment DO
O   IF user wants to perform auto-boot sequence DO
U     Find valid Forth auto-start block.
O     IF found THEN
O       Load Forth auto-start block.
      ELSE
O        Report that no auto-start block was found.
      END
    ELSE
O     Report that auto-start was skipped on user request.
    END
O   Quit into Forth interpreter.
  END











#+END_SRC

* Forth Interpreter
** Interpreter
I probably won't delve as deeply into the innards of the Forth
environment as I will other components of the firmware, if only
because of how fluid Forth's implementation details can be.  However,
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
* Data Structures and Variables
** Global Data
| Description                                   | Type                                                 |
|-----------------------------------------------+------------------------------------------------------|
| Flag that determines if OK prompt is visible. | BOOLEAN                                              |
| Mount list                                    | Pointer to volume descriptor                         |
| Device vector                                 | Maps device ID to device driver entry points, etc.   |




| Boot menu item vector                         | Array of 36 pointers to a boot menu item descriptor. |


** Forth USER Variables
These variables refer back to values deemed to be necessary in
previous sections of this document.  This list is not meant to be
exhaustive.

| Description            | Type                                              |
|------------------------+---------------------------------------------------|
| Exception Frame List   | Pointer to a record or NIL                        |
| ~THROW~ handler vector | Execution token of run-time semantics for ~THROW~ |

** Records and Control Blocks
Some of the material presented here will be duplicates from earlier
sections.  Where the two definitions differ, the version presented
with the specific section is to be taken to be normative.

*** Boot Menu Item Descriptor
| Field   | Purpose                                                        |
|---------+----------------------------------------------------------------|
| Key     | The key the user must press to activate this menu selection.   |
| Title   | The title of the menu selection.                               |
| Handler | The Forth word responsible for performing the item's action.   |
| Param   | A parameter passed to the handler (allows classes of handlers) |

*** Exception Handler Frame
| Field                                       | Purpose                                                                          |
|---------------------------------------------+----------------------------------------------------------------------------------|
| next                                        | Links to the next oldest exception handler; 0 if none.                           |







>
>
>
>
|
>



















<
|







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
* Data Structures and Variables
** Global Data
| Description                                   | Type                                                 |
|-----------------------------------------------+------------------------------------------------------|
| Flag that determines if OK prompt is visible. | BOOLEAN                                              |
| Mount list                                    | Pointer to volume descriptor                         |
| Device vector                                 | Maps device ID to device driver entry points, etc.   |

** Boot Menu Variables
| Description           | Type                                                 |
|-----------------------+------------------------------------------------------|
| Boot menu item vector | Array of 36 pointers to a boot menu item descriptor. |
| Formatting Buffer     | Array of >= 80 bytes                                 |

** Forth USER Variables
These variables refer back to values deemed to be necessary in
previous sections of this document.  This list is not meant to be
exhaustive.

| Description            | Type                                              |
|------------------------+---------------------------------------------------|
| Exception Frame List   | Pointer to a record or NIL                        |
| ~THROW~ handler vector | Execution token of run-time semantics for ~THROW~ |

** Records and Control Blocks
Some of the material presented here will be duplicates from earlier
sections.  Where the two definitions differ, the version presented
with the specific section is to be taken to be normative.

*** Boot Menu Item Descriptor
| Field   | Purpose                                                        |
|---------+----------------------------------------------------------------|

| Title   | The title of the menu selection (typ 32 chars; 35 chars max).  |
| Handler | The Forth word responsible for performing the item's action.   |
| Param   | A parameter passed to the handler (allows classes of handlers) |

*** Exception Handler Frame
| Field                                       | Purpose                                                                          |
|---------------------------------------------+----------------------------------------------------------------------------------|
| next                                        | Links to the next oldest exception handler; 0 if none.                           |