Jump to content

TheBF

+AtariAge Subscriber
  • Posts

    4,470
  • Joined

  • Last visited

Posts posted by TheBF

  1. Typically the ASM code you need is not very big so 10 bytes may or may not be important. Speed/size. It's the classic trade-off.

    BTW on 6809 is might be smaller because of 8 bit op-codes in some cases.  However the ASM[ will be pretty much the same for any ITC Forth. (I think)

  2. CAMEL99 Forth /TTY

     

    For anyone interested here is a re-built version of CAMEL99 Forth /TTY.  This is the first time I have put this out to the public. I am not 100% certain it is a perfect mirror of what is on my floppy disk here but it should start ok.  If you get into trouble type COLD to reboot the system if it is still responding.

     

    It runs over RS232/1 on a regular TI-994a with RS232 card and floppy drives.  I would be interested to hear what happens with some of the alternative disk systems out there. It "should" work with whatever DSR is installed for the device. (he said quietly,  his lip trembling slightly...)

     

    Disk utilities are CAT, DIR and MORE (to see a text file)

    Editors are only working for VDP and console keyboard at this time. More work for me.

     

    Disclaimer: Not all of the demo programs on DSK3. work as expected because they were made for VDP terminal. Caveat Emptor

     

     

     

    CAMEL99TTY.260.zip

    • Like 4
  3. Working on re-building the TTY version of Camel99 Forth I did some testing to see the effect of increasing the baud rate.

    I simply used WORDS and ELAPSE to see how long it took to show the dictionary of 379 words on Terraterm.

    Here are the results

    Baud    Seconds
    9600      2.60
    19200     2.11
    38400     2.10

    Looks like there is very little point in going past 19,200 bps on this implementation of Forth.  I might be able to go faster with a version of TYPE in Assembler.

    Might give that a try...

     

    Edit:  However the current version is vectored and multi-tasking friendly so maybe not...

     

  4. 1 hour ago, D-Type said:

    What is the state of the art for '99 Forth cross compilers regarding macro inlining of small code words?

     

    I was thinking about how to improve the speed of my 6809 Vectrex/Camel Forth and came to a similar conclusion as this thread i.e. instead of rewriting the compiler as STC (not enough time, never going to happen) I could make it make it STC-ish by inclining code and reducing the call overhead.

     

    (I remembered the inlining thread that came after this one and searched for it, but first came across this thread - will reread the inlining thread next. Simple inlining was actually what I was thinking about using initially, but of course the mind wanders...)

    In-lining Assembly language in indirect threaded code is pretty space wasteful.  I wrote a way to do it and here is how it goes.

     

    You need to create  the indirect links to move from threaded code to native machine code.  That adds 4 bytes to enter the code.

    After the machine runs the instruction pointer has moved forward but the Forth interpreter doesn't know about it so you have to move Forth IP register forward to which I did by compiling more machine code. :)  That added 4 more bytes.  Then you compile a way to run the Forth inner interpreter which in my case is another 2 bytes. 

     

    So all together you add 10 bytes just to enter and exit machine code from within ITC Forth code.

    Not great.

    \ put inline ASM in colon definitions
    : ASM[
               HERE CELL+ ,            \ compile a pointer to the next cell
               HERE CELL+ ,            \ which is the CFA of the inline code
               [  ;  IMMEDIATE         \ switch to interpreter mode
    
    : ]ASM     0209 ,  HERE 2 CELLS + , \ macro:  LI R9,HERE+4
                                        \ moves Forth IP reg.)
               NEXT,
               ] ;   IMMEDIATE          \ switch ON compiler
    

    Better to just write some code words because at least they are re-useable elsewhere. 

    However for 1 use the size of the dictionary entry is probably bigger than using ASM[  ]ASM so … maybe it's useful.

     

    Now in a sub-routine threaded system it is beautiful. In fact on some processors like the 9900 the Forth instruction and machine code are the same size as the  CALL <ADDRESS> combination.

    So for STC systems it's best to inline most of the Forth intrinsic instructions.  ( + - @ ! etc.) 

     

     

     

    • Like 1
  5. 2 hours ago, Tursi said:

    Hmm.. makes it seem unlikely. Is it possible that the instruction before the decrement is responsible? It's unlikely, but sometimes I don't trust the internal PC in debug statements, the cause can be an instruction or two earlier.

     

    I just noticed I was focused on A074, cause that's where the arrow is, but the debug says A072. Definitely look at the previous instruction. The PC needs to be incremented before the hardware access occurs. ;)

     

    I was thinking the  it must be something like that.

     

    (I am your favourite pain in the _ss I think.)

     

    It was happening in my key scan loop which was calling the 9901 timer to determine when to flash the cursor or flash the space character. {called BL in Forth (blank)}

    : KEY      ( -- char)
                BEGIN                 \ start the loop
                  PAUSE               \ Essential for Multi-tasking with Console
    \ *BAD*       TMR@ 1FFF <         \ compare harware timer to 1FFF
    \ *good*      8378 @ 0F AND 7 <   \ compare interrupt counter to 7
                  IF   CURS @         \ true? fetch the cursor char
                  ELSE BL             \ false? get the screen char
                  THEN VPUT           \ then put on screen
                  KEY?                \ check the keyboard
                  ?DUP                \ DUP IF <> 0
                UNTIL                 \ loop until a key pressed
                BL VPUT ;             \ put the space char on screen
    

    Here is VPUT which does the talking to the 9918.  The BL to WMODE sets LIMI 0 on entry.

    variable: VPG   \ holds address of VDP page ( >400 increments only)
    CODE: VPUT  ( char -- )  \ put a char at cursor position
                 TOS PUSH,
                 R1         STWP,    \ workspace is USER area base address
                 32 (R1) R3  MOV,    \ vrow->r3
                 2E (R1) R3  MPY,    \ vrow*c/l->tos
                 34 (R1) TOS ADD,    \ add vcol
                 VPG @@  TOS ADD,    \ add video page address
    l: _VC!  ( char Vaddr  -- )      \ VSBW in Forth style  pronounced "Vee-Cee-store"
                 TOS  R0 MOV,
                 WMODE @@ BL,
                *SP SWPB,
                *SP+ VDPWD @@ MOV,   \ write char & POP
                 2 LIMI,
                 TOS POP,            \ refill TOS
                 NEXT,
                 END-CODE
    

     

    Here is that code to read the 9901 timer, which you have seen before. ? 

    CODE: TMR@   ( -- n)         \ read the TMS9901 timer
                 0 LIMI,
                 TOS PUSH,
                 R12 2 LI,      \ cru = 1 (honest, 2=1)
                -1 SBO,         \ SET bit 0 TO 1, Enter timer mode
                 TOS 0E STCR,   \ READ TIMER (14 bits)
                -1 SBZ,         \ RESET bit 1, exit timer mode
                 2 LIMI,
                 NEXT,
                 END-CODE
    

    First I remove the call to TMR@ above and voila!  Problem solved.

    So then I remove the  LIMI 2 instruction at the end of this and it flashed the warning once, but only once for the 2 ..3 minutes that I tried to make it happen.

    Not sure why calling the timer did it.

  6. R6 is the base address of the data stack and starts at >FF7C.

    There will be occasions where I put a VDP address on the data stack and then run a VDP read or write routine but all of these are now running with interrupts off.

     

    It seems quite hard to nail down.

    It might be related to my disk DSR routine... I will check if it is doing VDP on it's own. 

     

    (EDIT:  Not DSR.  BLWP to the  DSR routine starts with LIMI 0  and ends the LIMI 2 )

     

     

  7. Addendum:

     

    You mentioned [  and ]   Here is the definition of these two words in CAMEL99 Forth.

    : ]         ( -- ) STATE ON  ;  IMMEDIATE
    : [         ( -- ) STATE OFF ;  IMMEDIATE

    They simply turn on the compiler or turn off the compiler , via the STATE variable and they do it Immediately.  ie: they don't care if the compiler is running at the moment or not.

    STATE=true means we are compiling

  8. 1 hour ago, FarmerPotato said:

    What is the difference between $OF  and:

     

    
    : $OF OVER =$ IF DROP ;

    or

    
    : $OF [ OVER =$ IF DROP ] ; IMMEDIATE

     

    I'm trying to understand POSTPONE and IMMEDIATE and [ ] from Starting FORTH. One of the chapters I could not understand at all when I was younger.

     

     

     

    It can make your head spin. It does mine. :)

     

    Before ANS Forth and POSTPONE it took two words to handle this action. There was COMPILE and [COMPILE].   

    Arguably they describe the action better as English words go.

    So think of POSTPONE as a "compiler" of a word that will happen not now... but later.

     

    So here goes:

     

    Just for reference a normal "colon" word in a colon definition has its address or "execution token" compiled into memory inline kind of like this.

    : FOO ;
    : BAR ;
    : TEST  FOO BAR ;
    \ COMPILES TO
    <LINK>,<4>,"TEST", <DOCOLON> <'FOO>, <'BAR>, <SEMI>

    Sometime we want to make words that compile things into a colon definition, ie: make them "inline" rather than adding another sub-routine call.

    Example:  We want to compute the address of an array. We could do this:

    CREATE Q   1000 ALLOT
    : [] ( n array -- addr[n])  SWAP 2* + ;
    
    9 Q []  \ returns address of 9th cell

    But since [] could be used inside inner loops maybe we want it faster so we could compile 'SWAP 2* +'  inline everywhere in the code, but that's a pain so we can make the equivalent of a macro with:

    : []     POSTPONE SWAP   POSTPONE 2*  POSTPONE + ;  IMMEDIATE 

    Now when we use []  in a definition it will not compile a call to []

    Now []  is an immediate word and so during compilation it will be interpreted (even though the compiler is turned on)

    and it will "compile" the addresses of "SWAP" "2*" and "+"  into the definition for us. How cool.

     

    Your example for $OF  is using the [  and ]  words.

    Let's go step by step:

    When you compile $OF  the first thing  you hit is   [     which turns off the compiler so now the interpreter is running... :) 

    The interpreter will see OVER and try and take the 2nd item on the stack and put it on the top of the stack (might fail)

    Then it will try to compare to strings on the stack for equality, but there are no strings on the stack right now so it will fail there

    No need to continue. I am sure you see what happened now.

     

    *** Your mind is in the right place. You want to get rid of all those damned POSTPONE words.

     

    There are two ways to do that:

    1.  Not implemented in Camel99 but part of Forth 2012 ( I think) are the ]]  [[   words.  Everything between those two operators, in a colon definition, is "postponed"

    Example:  :  $OF      ]]  OVER =$ IF DROP [[ ;   IMMEDIATE

     

    2.  Use a "text macro"

    Example  : $OF      S" OVER =$ IF DROP" EVALUATE ;  IMMEDIATE 

    This will read the text string with EVALUATE and if your compiling it will compile and if interpreting will interpret the text. These are handy and easy to understand usually.

     

    BTW the reason POSTPONE was created was because COMPILE is for non-immediate words  and [COMPILE] does the job for immediate words.

    This was deemed to be *confusing by the committee and so POSTPONE figures out what it needs to do regardless of the IMMEDIATEness of the word your are POSTPONEing.

     

    Clear? :)

    My head hurts now.

     

    * Imagine the ANS committee thought something in Forth might be confusing. |:)

  9. Yes the super cart is an Editor Assembler cartridge with 8K static RAM in place at HEX 6000. This memory space normally has a ROM in place for big applications like Extended BASIC.

     

    The 32K word  address buss looks like this:

    (from my memory)

    0000   1FFF    console ROMs
    2000   3FFF    Expansion RAM 8K low block
    4000   5FFF    expansion box cards DSR code
    6000   7FFF    Cartridge slot ROM/RAM
    8300   83FF    16 BIT RAM CHIP in console
    8400 ...       sound chip memory map I/O, VDP I/O ports
    9000   9FFF    grom memory I/O ??
    A000   FFFF    expansion RAM 24K block
    
    

    Edit I forgot to mention the 16K VDP RAM which is not on the buss but is memory mapped via address ports in the HEX 8000 space.

    • Like 1
  10. So that was a pretty easy fix. 

    I LIMI 0 at the start of the VDP address setting sub-routine and  LIMI 2  after the last instruction that touches the VDP in the routine.

    Timings using the screen time-out counter seem about the same. 

     

    Most of the time the VDP warnings are gone but occasionally I get this"

    Warning: PC >A072 reading VDP with LIMI 2

    And here is the debugger code that runs at >A072

       A072  0646  dect R6                     (14)
    >  A074  C584  mov  R4,*R6                
       A076  C108  mov  R8,R4                 
       A078  045A  b    *R10                  

    This is the runtime code for a Forth variable. (which is just a pointer to memory like a label on a DATA statement)

    Push R4  ( top of stack cache register) onto the data stack

    Move the address of the interpreter pointer (R8) into R4

     

    Why would that show the VDP warning?

     

    Edit: And now the debug screen is repeating this over and over.

     

     

  11. On 4/27/2020 at 12:24 PM, Tursi said:

    Version 399.025

    <SNIP>
    - add debug warning when VDP accessed with interrupts active
    - <snip>

     

    Version 399.024
    - Fix reading imagedisk files by sector - file type was not being ignored
     

    http://harmlesslion.com/software/classic99

     

    Hi Tursi,  Thanks again for all your efforts with this program. It's a beaut.  I am running 399.025 now.

     

    I have written Camel99 Forth to keep interrupts running as much as possible so that I can use ISR counters measuring elapsed time for code evaluations.

    So I have interrupts masked while setting the VDP addresses and during KSCAN calls, but I do VDP read/writing with LIMI 2.

    I don't seem to have any bad effects from this on real iron but I don't push things anywhere near a speed limit.

     

    I can't find a reference in the manual. Is there a flag to disable the VDP warnings?

    My debug screen is full of warnings.  :)  

     

  12. 3 hours ago, D-Type said:

    How fast was the Pascal version?

     

    Not really comparable, but CamelForth running on 1.5MHz Vectrex runs the following code to a PC terminal via a serial interface with a buffer that doesn't overflow in 16 seconds:

     

    
    : U.R \        \ u width -- ; Display u right-aligned in a field n characters
      >R <# 0 #S #> R> OVER - 0 MAX SPACES TYPE
    ;
    
    variable ii
         
    : counter 
       0 ii ! 
       begin 
          ii 1 over +! 
          @ dup 5 u.r 
          2000 = 
       until
    ;

     

     

    Damn that  6809 runs Forth well!

    At 9600 baud, the TI99 ran your code in 21.8 seconds. At 19.2k baud it was still 20.4

     

     

    counter.jpg

    • Like 1
  13. 1 hour ago, Lee Stewart said:

    I am a bit surprised that fbForth is so much slower than the other Forths. There just might be more thrashing between bank switching and branching to low RAM for system functions with GOTOXY and .R than I thought.

     

    ...lee

    Ya I was surprised too.   And I also had to go look inside Mark's code to see why it is so fast. All code. :)

     

  14. Over in the TP99 topic there is an nice video demonstration of TP99, a Pascal system for TI-99.

    I am always interested in how Forth, the lonely step-child language, compares to other development platforms so I translated the Pascal program to Forth.

    \ ANS/Camel99 Forth
    NEEDS .R FROM DSK1.UDOTR ( Camel99 needs to load justified printing)
    
    VARIABLE i
    DECIMAL
    : COUNTER
         PAGE
         0 i !
         2 2 AT-XY
         ." Counting from 1 to 2000"
         BEGIN
           i 1 OVER +!
           10 10 AT-XY  @ DUP 5 .R
           2000 =
         UNTIL ;
    
    \ FB Forth/Turbo Forth version
     0 VARIABLE i
    
    DECIMAL
    : COUNTER
         PAGE
         0 i !
         2 2 GOTOXY
         ." Counting from 1 to 2000"
         BEGIN
           i 1 OVER +!
           10 10 GOTOXY  @ DUP 5 .R
           2000 =
         UNTIL ;
    

     

    The development process is much faster in Forth. Source code compiles to memory and can run immediately.

    In that regard Forth is more like Turbo Pascal for DOS. 

     

    But since most Forth systems are written in indirect threaded Forth the execution speed is slower.

    Turbo Forth demonstrates what happens when key parts of the Forth system are written in Assembler.

     

    Here is what I measured on Classic99

     System          Secs                          Comment

    -------------------------------------------------------------------------------
     Turbo Forth         7     Number conversion, VDP I/O in assembler
     Camel99 Forth   21     Number conversion, VDP I/O in Forth + Assembler primitives
     FB Forth            42     Number conversion, VDP I/O in Forth + Assembler primitives

     

    As Vorticon mentioned over there "choose your poison".   :) 

     

     

    • Like 1
  15. Super Cart is pretty cool

     

    I have spent some time cleaning up the cross-compiler that builds Camel99 Forth. It's still not as pretty as I would like. In the beginning of the project I was simply happy to get it to build a working program.  :) 

     

    Just recently I learned that Classic99 has Super Cart RAM in place with the E/A cartridge.  I didn't take to much to convince the Cross-compiler to make an image that starts at >6000.

    I did have to remember to move the Forth dictionary pointer to >A000 when the kernel starts.

    Since the kernel is built to load into RAM all my other assumptions seem to work and the E/A5 loader seemed happy to put the program at >6000.  

     

    Does the loader work this way on real iron?

     

    After I beat it up for while I will put a zip version here.

     

     

     

    • Like 1
  16. 14 hours ago, oddemann said:

    Snazzle! A snake game. Think I got most bugs, but 580 is "bugging" me!
    (Book: "Zappers: having fun programming and playing 23 games for TI -99/4A")

    BAD VALUE IN 580

    Any ideas?

    Sometimes99er got the bug, and now it is correct! Have fun playing it!

    
    100 REM SNAZZLE
    110 RANDOMIZE
    120 DIM S(100,2),TABLE(26)
    130 TABLE(5)=1
    140 TABLE(4)=2
    150 TABLE(24)=3
    160 TABLE(19)=4
    170 FOR LEVEL=1 TO 3
    180 CALL CLEAR
    190 PRINT "   YOU ARE NOW ENTERING"::::::::::
    200 PRINT "L    EEEE V  V  EEEE L"
    210 PRINT "L    E    V  V  E    L"
    220 PRINT "L    EEE  V  V  EEE  L"
    230 PRINT "L    E     VV   E    L"
    240 PRINT "LLLL EEEE  VV   EEEE LLLL"
    250 PRINT :::TAB(11);"# ";LEVEL
    260 FOR T=1 TO 1000
    270 NEXT T
    280 CALL CLEAR
    290 SCORE=0
    300 FOR I=1 TO L
    310 S(I,1)=0
    320 S(I,2)=0
    330 NEXT I
    340 ON LEVEL GOSUB 1150,1160,1200
    350 X =INT(RND*26)+2
    360 Y =INT(RND*22)+2
    370 CALL GCHAR(Y,X,T)
    380 IF T<>32 THEN 350
    390 D=INT(RND*4)+1
    400 RC=31
    410 CALL CHAR(128,"FFFFFFFFFFFFFFFF")
    420 CALL COLOR(13,5,1)
    430 CALL CHAR(136,"FFFFFFFFFFFFFFFF")
    440 CALL CHAR(144,"00FF7E4C4C7EFF00")
    450 CALL COLOR(14,7,1)
    460 CALL HCHAR(1,1,128,RC)
    470 CALL HCHAR(24,1,128,RC)
    480 CALL VCHAR(1,1,128,24)
    490 CALL VCHAR(1,RC,128,24)
    500 L=4
    510 GOSUB 1090
    520 REM
    530 FOR I=0 TO L
    540 IF S(I,2)=0 THEN 560
    550 CALL HCHAR(S(I,2),S(I,1),32)
    560 S(I,1)=X
    570 S(I,2)=Y
    580 CALL GCHAR(Y,X,T)
    590 IF T<>32 THEN 790
    600 CALL HCHAR(Y,X,136)
    610 CALL KEY(3,KEY,STATUS)
    620 IF STATUS THEN 740
    630 ON D GOSUB 660,680,700,720
    640 NEXT I
    650 GOTO 530
    660 Y=Y-1
    670 RETURN
    680 X=X+1
    690 RETURN
    700 Y=Y+1
    710 RETURN
    720 X=X-1
    730 RETURN
    740 IF (KEY<65)+(KEY>90) THEN 630
    750 KEY=KEY-64
    760 IF TABLE(KEY)=0 THEN 630
    770 D=TABLE(KEY)
    780 GOTO 630
    790 REM
    800 IF (T=128)+(T=136)THEN 1010
    810 CALL SOUND(50,1700,0)
    820 CALL SOUND(50,892,0)
    830 L=L+3
    840 SCORE=SCORE+1
    850 IF SCORE=10 THEN 920
    860 SCORE$=STR$(SCORE)
    870 FOR J=1 TO LEN(SCORE$)
    880 CALL HCHAR(1,J+10,ASC(SEG$(SCORE$,J,1)))
    890 NEXT J
    900 GOSUB 1090
    910 GOTO 600
    920 FOR I=1 TO 16
    930 CALL SCREEN(I)
    940 CALL SOUND(50,I*110,0)
    950 NEXT I
    960 NEXT LEVEL
    970 CALL CLEAR
    980 PRINT "CONGRATULATIONS!"
    990 PRINT " YOU HAVE WON"::::::
    1000 END
    1010 FOR I=4 TO 1 STEP -.25
    1020 CALL SOUND(50,I*110,0)
    1030 CALL SCREEN(15)
    1040 CALL SCREEN(2)
    1050 NEXT I
    1060 FOR T=1 TO 1000
    1070 NEXT T
    1080 END
    1090 RX=INT(RND*(RC-2))+2
    1100 RY =INT(RND*22)+2
    1110 CALL GCHAR(RY,RX,T)
    1120 IF T<>32 THEN 1090
    1130 CALL HCHAR(RY,RX,144)
    1140 REM
    1150 RETURN
    1160 CALL HCHAR(4,4,128,22)
    1170 CALL HCHAR(12,12,128,6)
    1180 CALL HCHAR(20,4,128,22)
    1190 RETURN ^
    1200 FOR I=5 TO 25 STEP 5
    1210 CALL VCHAR(7,I,128,17)
    1220 NEXT I
    1230 CALL HCHAR(4,12,128,26)
    1240 RETURN

     

    One more,   1190  RETURN ^

     

     

    • Like 1
  17. 4 hours ago, Kchula-Rrit said:

    While investigating my runaway light show problem, I think I found a bug in TI's VMBW routine!  Here's a disassembly of the VMBW routine:

     

    If R2 is zero (writing zero bytes to VDP) it will decrement before the check, sending 65536 bytes to the VDP, causing the "lights show," and trashing any PABs and other stuff.  VMBR has the same "problem."

     

    Maybe not necessarily a bug; TI probably did not expect someone to send "nothing" to the VDP.

     

    K-R.

    Thanks for mentioning this. :)

     

    After reviewing my own version of this I was able to take some bytes out it by using your observation.

    My original version used a jump around the routine if the the count was zero.

    It's pretty much free to protect from 0 count arguments by using the the carry flag to exit the loop when the count transitions from 0 to -1.

    Here it is in Forth Assembler:

    CODE: VWRITE  ( RAM-addr VDP-addr cnt -- )
                 R0 POP,             \ vaddr to R0
                 R1 POP,             \ cpu addr to R1
                 WMODE @@ BL,
                 R3 VDPWD LI,        \ vdp addr. in a reg. makes this 12.9% faster
                 BEGIN,
                    TOS DEC,         \ decr count in R4
                 OC WHILE,           \ while carry=true
                     *R1+ *R3 MOVB,  \ write byte to vdp write port
                 REPEAT,
                 TOS POP,            \ refill top of stack cache register
                 NEXT,               \ return to Forth
                 END-CODE
    

     

    And it assembles to this:

    * VWRITE (VMBW)
       A7D8  C036  mov  *R6+,R0
       A7DA  C076  mov  *R6+,R1
       A7DC  06A0  bl   @>a754    \ set write address
       A7E0  0203  li   R3,>8c00
       A7E4  0604  dec  R4
       A7E6  1702  jnc  >a7ec
       A7E8  D4F1  movb *R1+,*R3
       A7EA  10FC  jmp  >a7e4
       A7EC  C136  mov  *R6+,R4
       A7EE  045A  b    *R10     \ return to Forth
      

    I set R3 to the VDP write port address because I have found it is almost 13% faster on large memory block moves.

     

  18. 47 minutes ago, Kchula-Rrit said:

    While investigating my runaway light show problem, I think I found a bug in TI's VMBW routine!  Here's a disassembly of the VMBW routine:

    
    VMBW_START                                                                2200
           BL   @VDP_SET_WRITE_ADDR         >06A0,>223A        '..":'         2200
    
    VMBW_LOOP                                                                 2204
    * Get data from caller's buffer,
    *  pointed-to by R1 MS byte,
    *  and send to VDP.
           MOVB *R1+,@VDPWD                 >D831,>8C00        '.1..'         2204
    
    * Done?
           DEC  R2                          >0602              '..'           2208
    
    * If not, send another byte.
           JNE  BW                          >16FC              '..'           220A
    
    * Return to caller.
           RTWP                             >0380              '..'           220C
    

    If R2 is zero (writing zero bytes to VDP) it will decrement before the check, sending 65536 bytes to the VDP, causing the "lights show," and trashing any PABs and other stuff.  VMBR has the same "problem."

     

    Maybe not necessarily a bug; TI probably did not expect someone to send "nothing" to the VDP.

     

    K-R.

    I ended up putting a protection jump around mine, but your idea is better. I will re-organize the loop.

    Thanks

     

    • Like 1
  19. 45 minutes ago, Lee Stewart said:

     

    This is how TI Forth does screen/block I/O. This method uses DSR Level 1 Read/Write Sector subprogram >010 via what is termed a transfer block at FAC (>834A in 16-bit scratchpad memory) instead of a PAB in VRAM as required by DSR Level 3 file I/O. Only one sector at a time is transferred to a program-designated 256-byte buffer in VRAM. TI Forth moves 4 contiguous sectors (1 at a time) into a 1 KiB VRAM buffer before copying said buffer to a CPU RAM block buffer for Forth’s use. This kind of sector access is obviously dangerous as it totally disregards the file system and can easily trash a disk that contains files such as does the TI Forth system disk. That is the main reason I developed fbForth (from TI Forth), which uses DSR Level 3 file-record I/O (eight 128-byte records/block) via VRAM PABs to manage Forth blocks located in separate blocks files.

     

    ...lee

    Has anyone every written an alternate DOS that uses raw sectors? 

    As I write this I remember that USCD Pascal seems to have a different disk system but I am thinking more along the lines of putting an MS DOS format on TI disks for example.

×
×
  • Create New...