I may have given Fleet Forth's EXPECT nonstandard behavior.
The Forth-83 Standard states the following concerning EXPECT .
Code: Select all
9.5.2 EXPECT
Control characters may be processed to allow system dependent
editing of the characters prior to receipt. Therefore, a
Standard Program may not anticipated that control characters can
be received.
It doesn't seem to say anything about intercepting function keys; however, I thought such a capability would be useful. In Fleet Forth, EXPECT is a DEFERred word. It is normally set to (EXPECT) .
The high level portion of (EXPECT) reads the keyboard and echoes the characters back to the screen. If a carriage return is detected in the keyboard buffer, it is not read. Control flow passes to the low level portion of (EXPECT) which uses the Commodore 64's screen editor, kernal routine CHRIN , $FFCF.
The word which echoes keys to the screen is DEMIT . It is a primitive which uses the same C64 kernal routines as (EMIT) . As the leading 'D' in the name implies, it is normally used to send a character to a disk drive, but can also send a character to the screen. The difference with (EMIT) , the vector for EMIT , is DEMIT does not update the variables CHARS and LINES . These variables are used for 'print formatting'. They keep track of the number of characters emitted since the last carriage return or page and the number of lines since the last page.
DEMIT was replaced with the following:
Code: Select all
7 OVER #133 - U< \ is this not a function key?
IF \ if it is not
DEMIT \ echo to the screen as usual
ELSE \ else
#63 + 4 /MOD SWAP 2* + \ convert PETSCII code
" F0" TUCK 2+ C! \ insert digit character into string
CONTEXT @ (FIND) \ and search CONTEXT vocabulary
IF DUP EXECUTE THEN \ if found, execute
DROP
THEN
The search of the CONTEXT vocabulary will include the parent vocabularies.
The Commodore 64's function keys are a little different. There are only four actual function keys: F1, F3, F5 and F7. F2 is obtained with shift-F1, F4 with shift-F3 and so on.
The PETSCII codes are as follows:
Code: Select all
F1 133
F3 134
F5 135
F7 136
F2 137
F4 138
F6 139
F8 140
in function key order:
Code: Select all
F1 133
F2 137
F3 134
F4 138
F5 135
F6 139
F7 136
F8 140
This line:
Code: Select all
#63 + 4 /MOD SWAP 2* + \ convert PETSCII code
performs the following conversion:
Code: Select all
133 => 49
137 => 50
134 => 51
138 => 52
135 => 53
139 => 54
136 => 55
140 => 56
An eight byte look-up table could have been used, but this was smaller.
If function key F1 is pressed and there is no word by that name, it's the same as if the function key was not pressed. If the name exists, it is executed.
I've notice the function key names could be confused with hexadecimal numbers. I've gotten too used to using $F1 for a hexadecimal number. I could change this line:
Code: Select all
" F0" TUCK 2+ C! \ insert digit character into string
to this:
Code: Select all
" FKEY0" TUCK 5 + C! \ insert digit character into string
Or something similar.
Code: Select all
" FKEY0" [ HERE 1- ] SWAP LITERAL C! \ insert digit character into string
or even
Code: Select all
[ HERE 2+ ] $FFFF \ compile a literal
C!
" FKEY0" [ HERE 1- SWAP! ] \ patch literal with address of
\ last character in string.
To use function key F1 with this change there would need to be a word with the name FKEY1 .