Jump to content
IGNORED

fbForth—TI Forth with File-based Block I/O [Post #1 UPDATED: 06/05/2024]


Lee Stewart

Recommended Posts

1 hour ago, TheBF said:

Is there a way to not load R7 and rather replace the MYSELF line with 

         BL @ROLLIT

or some such computed address to the entry to the code

 

Of course. I only used R7 because I thought it saved bytes, but, alas, it is actually worse because it takes the same space (8 bytes) with an extra instruction, so here it is as suggested:

ROLL   DATA $+2
       MOV  *SP+,R2     ;pop position (count)
       BL   @ROLLIT     ;do the ROLL
ROLLEX B    *NEXT

ROLLIT 
*++ Push return address to return stack
       DECT R
       MOV  R11,*R
*++ 1-
       DEC  R2
*++ IF
       JLT  ROLITX      ;we're done if negative
*++ >R       
       DECT R
       MOV  *SP+,*R
*++ MYSELF (recurse)
       BL   @ROLLIT
*++ SWAP R>  (SWAP and pop return stack to under TOS)
       DECT SP
       MOV  @2(SP),*SP  ;over
       MOV  *R+,@2(SP)  ;under
*++ Pop return address and return
ROLITX MOV  *R+,R11
       RT

 

...lee

  • Like 2
Link to comment
Share on other sites

5 hours ago, TheBF said:

Here is another way that I did ROLL. 

 

: ROLL \ nn..n0 n -- nn-1..n0 nn ; 6.2.2150
  DUP>R PICK
  SP@ DUP CELL+ R> 1+ CELLS MOVE DROP ;

 

I don’t believe you actually used that code because it That code cannot possibly will not work in fbForth for two reasons*:

  1. MOVE copies cells, not bytes, so that code will underflow the stack.
  2. The source address for MOVE is below the destination address and the source and destination overlap, with the result that the TOS gets duplicated down the stack, overwriting everything in its path.

...lee

__________________

* This does work in ANS Forth (see next post by @TheBF).

Edited by Lee Stewart
correction
Link to comment
Share on other sites

MOVE in ANS Forth does a test to determine if it should do CMOVE or CMOVE>.

(not very true to Forth philosophy but there it is)

 

I just tried it before I posted to make sure that darn thing actually worked. :)

It seems to. 

Maybe because my top of stack in R4. ?

 

(Way back , after I found the recursive one in your source code, I just played around until something seemed to work. I have not actually put it in a program to your point.)

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, TheBF said:

MOVE in ANS Forth does a test to determine if it should do CMOVE or CMOVE>.

(not very true to Forth philosophy but there it is)

 

I just tried it before I posted to make sure that darn thing actually worked. :)

It seems to. 

Maybe because my top of stack in R4. ?

 

(Way back , after I found the recursive one in your source code, I just played around until something seemed to work. I have not actually put it in a program to your point.)

 

Ah! Well, I will change my comment to its not being possible in fbForth. Thanks.

 

...lee

  • Like 1
Link to comment
Share on other sites

All clever code aside, I will likely use high-level code for both PICK and ROLL because bank #0 is getting awfully cramped—or—I may loop out to other banks (requires only 8 bytes in bank #0), but I will need to check the speed hit first—not holding my breath. 

 

...lee

  • Like 1
Link to comment
Share on other sites

It's always been the thrill of the chase though hasn't it?  I think your recursive ALC version was something of a first around here.

You could always make the fast versions a block of machine code for those sinful creatures that need to roll as fast as possible.

  • Like 1
Link to comment
Share on other sites

Timing to run "7 ROLL" 10,000 times for different implementations of ROLL :

Code               Time (s)
----------------   --------
Forth              45
ALC recursive       9
ALC loop            3.5
ALC loop, bank#1    4.8

I expected the bank#1 code to take longer, but that looks like the way to go.

 

...lee

  • Like 1
Link to comment
Share on other sites

I have added the following words to fbForth 3.0:

 

2*  CELLS (synonym for 2*)  2/  -ROT  PICK  ROLL  2DUP  2DROP  2SWAP  2OVER  NIP  TUCK  WITHIN  <>  $.  UDSQRT

 

Regarding UDSQRT (Unsigned Double SQuare RooT), it now rounds up the calculated square root if warranted. It only required 3 additional instructions before the return:

 

UDSQRD C    R1,R3       ; round up?
       JLE  UDSQEX      ; no..we're good
       INC  R3          ; yes
UDSQEX RT               ; return R3 with 16-bit unsigned root

 

For the terminally curious, the full code for UDSQRT (accompanied by a copious preamble!) is in the spoiler:

Spoiler
*   _   _         _                  _   ___           _    _     
*  | | | |_ _  __(_)__ _ _ _  ___ __| | |   \ ___ _  _| |__| |___ 
*  | |_| | ' \(_-< / _` | ' \/ -_) _` | | |) / _ \ || | '_ \ / -_)
*   \___/|_||_/__/_\__, |_||_\___\__,_| |___/\___/\_,_|_.__/_\___|
*                  |___/                                          
*           ___                           ___          _   
*          / __| __ _ _  _ __ _ _ _ ___  | _ \___  ___| |_ 
*          \__ \/ _` | || / _` | '_/ -_) |   / _ \/ _ \  _|
*          |___/\__, |\_,_\__,_|_| \___| |_|_\___/\___/\__|
*                  |_|                                     
* 
* /* from Craig McQueen's response on stackoverflow.com to "Looking for
*    an efficient integer square root algorithm for ARM Thumb2": 
*  (https://stackoverflow.com/questions/1100090/looking-for-an-efficient-
*   integer-square-root-algorithm-for-arm-thumb2)
* */ 
* #define BITSPERLONG 32
* #define TOP2BITS(x) ((x & (3L << (BITSPERLONG-2))) >> (BITSPERLONG-2))
* 
* struct int_sqrt {
*     unsigned sqrt, frac;
* };
* 
* /* usqrt:
*     ENTRY x: unsigned long
*     EXIT  returns floor(sqrt(x) * pow(2, BITSPERLONG/2))
* 
*     Since the square root never uses more than half the bits
*     of the input, we use the other half of the bits to contain
*     extra bits of precision after the binary point.
* 
*     EXAMPLE
*         suppose BITSPERLONG = 32
*         then    usqrt(144) = 786432 = 12 * 65536
*                 usqrt(32) = 370727 = 5.66 * 65536
* 
*     NOTES
*         (1) change BITSPERLONG to BITSPERLONG/2 if you do not want
*             the answer scaled.  Indeed, if you want n bits of
*             precision after the binary point, use BITSPERLONG/2+n.
*             The code assumes that BITSPERLONG is even.
*         (2) This is really better off being written in assembly.
*             The line marked below is really a "arithmetic shift left"
*             on the double-long value with r in the upper half
*             and x in the lower half.  This operation is typically
*             expressible in only one or two assembly instructions.
*         (3) Unrolling this loop is probably not a bad idea.
* 
*     ALGORITHM
*         The calculations are the base-two analogue of the square
*         root algorithm we all learned in grammar school.  Since we're
*         in base 2, there is only one nontrivial trial multiplier.
* 
*         Notice that absolutely no multiplications or divisions are performed.
*         This means it'll be fast on a wide range of processors.
* */
* 
* void usqrt(unsigned long x, struct int_sqrt *q)
* {
*       unsigned long a = 0L;                   /* accumulator      */
*       unsigned long r = 0L;                   /* remainder        */
*       unsigned long e = 0L;                   /* trial product    */
* 
*       int i;
* 
*       for (i = 0; i < BITSPERLONG; i++)   /* NOTE 1 */
*       {
*             r = (r << 2) + TOP2BITS(x); x <<= 2; /* NOTE 2 */
*             a <<= 1;
*             e = (a << 1) + 1;
*             if (r >= e)
*             {
*                   r -= e;
*                   a++;
*             }
*       }
*       memcpy(q, &a, sizeof(long));
* }
* 
* /**
*  * \brief    Fast Square root algorithm
*  *
*  * Fractional parts of the answer are discarded. That is:
*  *      - SquareRoot(3) --> 1
*  *      - SquareRoot(4) --> 2
*  *      - SquareRoot(5) --> 2
*  *      - SquareRoot(8) --> 2
*  *      - SquareRoot(9) --> 3
*  *
*  * \param[in] a_nInput - unsigned integer for which to find the square root
*  *
*  * \return Integer square root of the input value.
*  */
* uint32_t SquareRoot(uint32_t a_nInput)
* {
*     uint32_t op  = a_nInput;
*     uint32_t res = 0;
* // The second-to-top bit is set: use 1u << 14 for uint16_t type;
* // use 1uL<<30 for uint32_t type
*     uint32_t one = 1uL << 30; 
* 
* 
*     // "one" starts at the highest power of four <= than the argument.
*     while (one > op)
*     {
*         one >>= 2;
*     }
* 
*     while (one != 0)
*     {
*         if (op >= res + one)
*         {
*             op = op - (res + one);
*             res = res +  2 * one;
*         }
*         res >>= 1;
*         one >>= 2;
*     }
*     /* Do arithmetic rounding to nearest integer */
*     if (op > res)
*     {
*         res++;
*     }
*     return res;
* }
* 
* 
;[*** UDSQRT ***   ( ud -- u )
*        DATA HONK_N
* UDSQ_N .NAME_FIELD 6, 'UDSQRT '
* UDSQ   DATA $+2
*        BL   @BLF2A
*        DATA _UDSQ->6000+BANK1
* Registers:   R0,R1 = udh,udl
*              R2,R3 = root (nh,nl)
*              R4,r5 = floating 1 (f1h,f1l)
*              R6,R7 = wkh,wkl
       
_UDSQ  MOV  *SP+,R0        ; pop udh to R0
       MOV  *SP,R1         ; get udl to R1
       BL   @__UDSQ        ; branch to body of this routine
       MOV  R3,*SP         ; copy u to top of stack
       B    @RTNEXT        ; back to bank 0 and the inner interpreter

*++ Body of UDSQRT routine to allow call by other routines in this bank
*++ Registers in...
*++   R0: unsigned double high word (udh)
*++   R1: unsigned double low word (udl)
*++ Register out...
*++   R3: square root as 16-bit unsigned integer

__UDSQ
       CLR  R2             ; clear running..
       CLR  R3             ; ..root (uh,ul)
       CLR  R5             ; set floating 1..
       LI   R4,>4000       ; ..to >4000 0000
   
*
* get highest power of 4 <= square (udh,udl)
UDSQ0  C    R4,R0          ; f1h = udh?
       JNE  UDSQ1          ; jump if not =
       C    R5,R1          ; f1l = udl?
UDSQ1  JLE  UDSQ3          ; jump if we power of 4 OK
       C    R4,R5          ; f1h < f1l?
       JL   UDSQ2          ; jump if bit in low word
       SRL  R4,2           ; shift f1h right 2 bits
       JNE  UDSQ0          ; check again if bit not shifted out
       LI   R5,>4000       ; set f1l to shifted-out bit
       JMP  UDSQ0          ; check again
UDSQ2  SRL  R5,2           ; shift f1l right 2 bits
       JMP  UDSQ0          ; check again
*
* calculate square root
UDSQ3  C    R4,R5       ; f1h:f1l?
       JEQ  UDSQRD      ; if done, check for rounding and exit
*
* set up wkh,wkl = uh,ul + f1h,f1l to compare to udh,udl
       MOV  R2,R6       ; uh to wkh
       MOV  R3,R7       ; ul to wkl
       A    R5,R7       ; f1l + wkl
       JNC  UDSQ4       ; jump if no carry
       INC  R6          ; carry..so increment wkh
UDSQ4  A    R4,R6       ; f1h + wkh
*
* check if need to update running values of udh,udl & uh,ul
       C    R0,R6       ; udh = wkh?
       JNE  UDSQ5       ; jump if not =
       C    R1,R7       ; udl:wkl?
UDSQ5  JL   UDSQ8       ; jump if udh,udl < wkh,wkl?
*
* udh,udl = udh,udl - wkh,wkl
       S    R7,R1       ; udl - wkl
       JOC  UDSQ6       ; jump if carry
       DEC  R0          ; no carry..reduce udh
UDSQ6  S    R6,R0       ; udh - wkh
*
* uh,ul = wkh,wkl + f1h,f1l
       A    R5,R7       ; wkl + f1l
       JNC  UDSQ7       ; jump on no carry
       INC  R6          ; carry..increment wkh
UDSQ7  A    R4,R6       ; wkh + f1h
       MOV  R6,R2       ; wkh to uh
       MOV  R7,R3       ; wkl to ul
*
* f1h,f1l >> 2 
UDSQ8  C    R4,R5       ; f1h:f1l?
       JL   UDSQ9       ; jump if bit in low word
       SRL  R4,2        ; bit in f1h..shift it right 2 bits
       JNE  UDSQ10      ; jump if bit not shifted out
       LI   R5,>4000    ; set f1l to shifted-out bit
       JMP  UDSQ10      ; next operation
UDSQ9  SRL  R5,2        ; shift f1l right 2 bits
*
* uh,ul >> 1
UDSQ10 SRL  R3,1        ; shift ul right 1 bit
       SRL  R2,1        ; shift uh right 1 bit
       JNC  UDSQ3       ; back for another round if no carry
       ORI  R3,>8000    ; set MSb of ul
       JMP  UDSQ3       ; back for another round

UDSQRD C    R1,R3       ; round up?
       JLE  UDSQEX      ; no..we're good
       INC  R3          ; yes
UDSQEX RT               ; return R3 with u
;]*

 

 

As far as the number of changes left to do for fbForth 3.0, there are not many, but the last one could be a lot of work—we’ll see:

 

I intend to change SPRDIST and SPRDISTXY to include UDSQRT to get the actual distance instead of reporting its square.

 

I also intend to include the new DSRLNK we’ve been working on in another thread if it and all the required changes to other code will fit. The cartridge ROM is getting kind of tight:

Current free space in ROM banks:
    bank 0:   112 bytes
    bank 1:   276 bytes
    bank 2:   166 bytes
    bank 3:   300 bytes

 

...lee

  • Like 2
Link to comment
Share on other sites

On 1/27/2024 at 10:50 PM, Lee Stewart said:

I intend to change SPRDIST and SPRDISTXY to include UDSQRT to get the actual distance instead of reporting its square.

 

SPRDIST and SPRDISTXY both used DXY to get (x2-x1)2 and (y2-y1)2 before incorporating UDSQRT to get the actual distance, √((x2-x1)2+(y2-y1)2). The problem with the former is that neither SPRDIST nor SPRDISTXY  can handle a distance greater than 181 pixels because d2=(x2-x1)2+(y2-y1)2 exceeds 16 bits, so they each return  d2=32767 for d2>1812. The problem is that the actual maximum pixel distance on the screen, corner to corner, is 319 pixels. I suppose this was acceptable to TI developers because game programmers were likely only concerned with hits and near misses, which entail much shorter distances than full screen.

 

After incorporating UDSQRT into the distance calculation, I wrote a time test to compare the two:

\ Old DXY leaves 2 values, hence 2DROP to maintain the stack
: DXYOLD   ( n -- )
    0 DO
       0 0 125 130 DXY
       2DROP
    LOOP ;

\ New DXY leaves 1 value, hence DROP to maintain the stack
: DXYNEW   ( n -- )
    0 DO
       0 0 125 130 DXY
       DROP
    LOOP ;

\ Baseline loop, needed 4DROP to maintain the stack
: BASELN   ( n -- )
    0 DO
       0 0 125 130
       4DROP
    LOOP ;

 

Running each 10,000 times resulted in

Routine  Time(s)  Diff
-------  -------  ----
DXYOLD     8.12    2.88
DXYNEW    21.50   16.26
BASELN     5.24    0

 

Using UDSQRT obviously significantly increases the execution time for DXY , but is still pretty fast at 1.6 ms. Interestingly, running the 10,000x loop with SPRDISTXY and a sprite at (0,0) and pixel at (125,130) takes only a fraction of a second more! For reference, running this last loop in XB takes 6 m, 20 s.

 

Any objections to using UDSQRT for the distance calculation?

 

...lee

  • Like 3
Link to comment
Share on other sites

I went looking in my collection and I found these two unsigned square root functions.

 

Interesting, but they would still not have the range you need. 

\ recursive version by Gerry Jackson comp.lang.forth 
: USQRT ( u -- u1 )
   DUP 2 U< IF EXIT THEN
   DUP >R 2 RSHIFT RECURSE
   2*                ( -- u sm )
   1+ DUP            ( -- u la la )
   DUP *             ( -- u la la^2 )
   R> U> IF 1- THEN  ( -- u1 )
;
     
\ Dr. Ting's version 
: SQRT-TING ( n -- root )
   65025 OVER U< ( largest square it can handle)
   IF DROP 255 EXIT THEN ( safety exit )
   >R ( save sqaure )
   1 1 ( initial square and root )
   BEGIN ( set n1 as the limit )
      OVER R@ U< ( next square )
   WHILE
      DUP CELLS 1+ ( n*n+2n+1 )
      ROT + SWAP
      1+ ( n+1 )
   REPEAT
   NIP
   R> DROP
;

 

  • Like 3
Link to comment
Share on other sites

4 hours ago, TheBF said:

I went looking in my collection and I found these two unsigned square root functions.

 

Interesting, but they would still not have the range you need. 

\ recursive version by Gerry Jackson comp.lang.forth 
: USQRT ( u -- u1 )
   DUP 2 U< IF EXIT THEN
   DUP >R 2 RSHIFT RECURSE
   2*                ( -- u sm )
   1+ DUP            ( -- u la la )
   DUP *             ( -- u la la^2 )
   R> U> IF 1- THEN  ( -- u1 )
;
     
\ Dr. Ting's version 
: SQRT-TING ( n -- root )
   65025 OVER U< ( largest square it can handle)
   IF DROP 255 EXIT THEN ( safety exit )
   >R ( save sqaure )
   1 1 ( initial square and root )
   BEGIN ( set n1 as the limit )
      OVER R@ U< ( next square )
   WHILE
      DUP CELLS 1+ ( n*n+2n+1 )
      ROT + SWAP
      1+ ( n+1 )
   REPEAT
   NIP
   R> DROP
;

 

 

One advantage my UDSQRT has over these is that it operates on an unsigned double. The maximum useful square is 4,294,836,225 (>FFFE 0001), the square root of which is 65535 (>FFFF). Higher squares result in the same root, which for about half of them is only off by 1. The other half are correct.

 

...lee

  • Like 1
Link to comment
Share on other sites

8 minutes ago, Lee Stewart said:

 

One advantage my UDSQRT has over these is that it operates on an unsigned double. The maximum useful square is 4,294,836,225 (>FFFE 0001), the square root of which is 65535 (>FFFF). Higher squares result in the same root, which for about half of them is only off by 1. The other half are correct.

 

...lee

Indeed.  Is it all ALC? 

I am tempted to try and make one of these 16 bit Forth versions take an Unsigned double. They will be slow but at least more useful. 

 

Edited by TheBF
typo
Link to comment
Share on other sites

Just now, TheBF said:

Indeed.  Is it all ALC? 

I am tempted to try and make of these 16 bit Forth versions take an Unsigned double. They will be slow but at least more useful. 

 

I posted the code in a spoiler 6 posts back.

 

...lee

  • Thanks 1
Link to comment
Share on other sites

5 minutes ago, Lee Stewart said:

 

I posted the code in a spoiler 6 posts back.

 

...lee

I missed that spoiler. Wow! That is really neat.  Good coding by you.

I don't fully grok the method yet but that's pretty slick.

 

Would you say the c code is doing the method in the Forth below but non-recursively ?

: USQRT ( u -- u1 )
   DUP 2 U< IF EXIT THEN
   DUP >R 2 RSHIFT RECURSE
   2*                ( -- u sm )
   1+ DUP            ( -- u la la )
   DUP *             ( -- u la la^2 )
   R> U> IF 1- THEN  ( -- u1 )
;

 

Link to comment
Share on other sites

3 hours ago, TheBF said:

I missed that spoiler. Wow! That is really neat.  Good coding by you.

I don't fully grok the method yet but that's pretty slick.

 

Would you say the c code is doing the method in the Forth below but non-recursively ?

: USQRT ( u -- u1 )
   DUP 2 U< IF EXIT THEN
   DUP >R 2 RSHIFT RECURSE
   2*                ( -- u sm )
   1+ DUP            ( -- u la la )
   DUP *             ( -- u la la^2 )
   R> U> IF 1- THEN  ( -- u1 )
;

 

 

Possibly, it has been a while (2 years?) since I was immersed in that code—fun, but grueling! There are no multiplications in the C code except for the one “2 *”, which is really only a left shift. The “DUP *” in the above Forth, however, is clearly a wholesale multiplication. I will probably try to analyze the Forth at some point. :ponder:

 

...lee

  • Like 1
Link to comment
Share on other sites

Here are 2 non-inverted betas of fbForth 3.0

fbForth300_8_Fa.bin     fbForth300_8Ga.bin

 

They both are up-to-date versions of the TODO list (check out FONTED in particular!): 

fbForth300_TODO.txt

 

Items in the TODO list marked with “══>” have not been done yet.

 

The reason I post these two different betas is that I want feedback as to which you prefer with regard to the VDP Mode changing words: TEXT TEXT80 GRAPHICS GRAPHICS2 SPLIT SPLIT2

 

Please, play with changing from one to another to test them. Note that once you invoke GRAPHICS2 (bitmap mode), you cannot see what you are typing, but you can easily get to the next mode by typing the desired mode word.

 

Note also that fbForth 3.0:F has more screen “anomalies” between mode changes than fbForth 3.0:G, with the latter taking 22 bytes extra in bank #1 (288 bytes free) for the cleaner presentation.

 

...lee

  • Like 6
  • Confused 1
Link to comment
Share on other sites

Man you have done a great deal of work.  It's a really nice system. Very polished.

The modes all seem to switch nicely. 

I still love SPLIT2  for the editor. 

 

We spoke about having the 64 col. editor bouncing down to the text window when you escape the editor.

This lets you see your code and manually test it so easily.  

I never did give you my changes to the TI Forth 60col editor for that.

Is that something you could use now?

 

  • Like 1
Link to comment
Share on other sites

21 hours ago, TheBF said:

We spoke about having the 64 col. editor bouncing down to the text window when you escape the editor.

This lets you see your code and manually test it so easily.  

I never did give you my changes to the TI Forth 60col editor for that.

Is that something you could use now?

 

I would like to see your code—though I did make a temporary change to pop to the 32-column window in SPLIT2, just to check it out. I may go that route. Thanks for the poke.

 

...lee

Link to comment
Share on other sites

31 minutes ago, TheBF said:

Here's a dump of my TI-Forth disk that I did in 2019.

There's some ugly stuff in here but the editor is how I left it in 1987 when I got my first PC clone. :)

 

 

BF TI-FORTH SCREENS DISK1-2019.TXT 84.01 kB · 1 download

 

Wow! That’s impressive!—and disgustingly neat! :-o

 

...lee

  • Thanks 1
Link to comment
Share on other sites

On 2/6/2024 at 4:18 PM, Lee Stewart said:

Please, play with changing from one to another to test them.

On real hardware (F18a and 16-bit console) I much prefer the G version, as the F version displays all manner of screen initialization during the transitions. There are minor glitches in G:

 

- Text to Graphics: sometimes briefly displays a single horizontal line during transition

- Text to Graphics2: clean transition, but leaves a cursor-like block on upper right hand corner of screen

- Text to Text80: a brief full screen white flash during transition

- Text to Split and Split2: clean

 

- Graphics to Text: sometimes briefly displays a single horizontal line during transition

- Graphics to Graphics2: clean, but leaves a cursor in upper right corner

- Graphics to Split and Split 2: clean

 

Also - the key-repeat starts too quickly for me. I have to be careful not to shoot out a row of characters. 

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Reciprocating Bill said:

On real hardware (F18a and 16-bit console) I much prefer the G version, as the F version displays all manner of screen initialization during the transitions.

 

The old version of the VDPSET ALC routine blanks the screen until all VDP registers are set and various tables are updated for the given VDP mode change, but it also set the registers in ascending order, which would screw up the screen if a user inadvertently attempted TEXT80 mode with a TMS9918 VDP. I changed it to set the registers in descending order with a loop that ends when decrementing the register number causes the overflow bit to set. The side effect of this is that the screen is unblanked after VR01 is set. For build F, VR00 is set and all tables are initialized while the screen is visible. For build G (22 bytes more than build F), the screen is re-blanked immediately after VR00 is set, so all you see until the screen is unblanked (after all the initializing) is the result of a mode change from setting VR00:  0 for TEXT GRAPHICS MULTI; 2 for GRAPHICS2 SPLIT SPLIT2; 4 for TEXT80. I will post build H in a little bit, which will be the same as before build F, except for the order of setting the VDP registers, to see how much extra code is involved.

 

1 hour ago, Reciprocating Bill said:

Also - the key-repeat starts too quickly for me. I have to be careful not to shoot out a row of characters.

 

You can change that by changing DCT+16 (Repeat High = timer ticks for starting repeat; 900 at bootup) and/or DCT+18 (Repeat Low = timer ticks for continuing repeat; 60 at bootup). Also, see “++Re-wrote low-level code for KEY” of my TODO list. You can check the current values with

DECIMAL
DCT 16 + ?    \ to display current RH
DCT 18 + ?    \ to display current RL

and set them with

DECIMAL
1000 DCT 16 + !   \ to change RH to 1000 ticks
200 DCT 18 + !    \ to change RL to 200 ticks

 

Please, let me know what RH and RL you think are best. I can change those in the next build.

 

...lee

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...