Jump to content

Lee Stewart

+AtariAge Subscriber
  • Posts

    5,846
  • Joined

  • Last visited

Everything posted by Lee Stewart

  1. That routine is part of the Level 1 ISR and gets executed if the screen timeout counter (console ISR R11 at >83D6) goes to 0. R11 gets incremented by 2 each time through the console Level 1 ISR. Any keystroke detected by the console KSCAN routine will reset the timer and redisplay the screen. The timer is 16 bits and, at 2 bits per tick (1/60 s), is 32768/3600 ≈ 9 m 6 s. You can effectively disable the timeout counter by storing an odd number at >83D6—until the next keystroke through KSCAN, that is. ...lee
  2. See also Thierry’s discussion of maskable interrupts on the TI-99/4A. ...lee
  3. Yeah...The reason R0 cannot be used for indexing is that there are 5 addressing modes, but only room in the T fields (see below) of the instruction word for 4 (002 012 102 112), so the operand fields were coopted by the TMS9900 designers to provide the extra information to indicate the extra mode for T=102. For T=102 and a corresponding operand of 0, the addressing mode is symbolic. And for T=102 and a corresponding non-zero operand, the addressing mode is indexed, with the non-zero operand indicating the index register, which, obviously cannot be R0 because of the above-mentioned design decision. Layout of TMS9900 instruction word: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐ │OP-CODE │B │ Td │Destination│ Ts │ Source │ └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘ ...lee
  4. It was never clear to me why the TI programmers of TI Forth defined the word DSRLNK to presume its use for only Level 3 file handling. I am seriously considering changing the fbForth word DSRLNK (inherited from TI Forth) to require an argument of 8 for Level 3 file handling and 10 for Level 1 and 2 subprograms, just as its ALC counterpart. This will obviously require any TI Forth code ported to fbForth to put 8 on the stack before DSRLNK is executed. Thoughts? ...lee
  5. Here is the promised build H: fbForth300_8_Ha.bin @Reciprocating Bill, please note that RL has been changed from 60 ticks to 100 ticks. You may, of course, prefer it slower yet. Let me know. ...lee
  6. 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. 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
  7. Maybe nothing more than a way to manage changing the CRU bit from ROM or an alternate way to organize the code. If all relevant code is in RAM, the following would be shorter and quicker for SBO (and similar for SBZ😞 *++ Set specified CRU bit (1). R0 has bit to set in MSB MOVB R0,@SBOBIT+1 ;set up SBO instruction for appropriate CRU bit SBOBIT SBO 0 ;execute SBO for bit in R0 MSB A good way to use the X instruction is on a table of instructions of constant length, which SBO and SBZ instructions are. This method is probably not useful for setting and clearing CRU bits because it would be larger than desirable, but, if most of the CRU bits between 0 and 7 needed attention, then the following might be useful for setting the bits: *++ Table of 1-word SBO instructions for successive CRU bits SBOTBL SBO 0 SBO 1 SBO 2 SBO 3 SBO 4 SBO 5 SBO 6 SBO 7 *++ Code to use above table (R1 has CRU bit to set) SLA R1,1 ;make it an index into SBOTBL X @SBOTBL(R1) ;execute appropriate SBO instruction R1 should probably be checked that it is within range of the table. A similar setup would be needed for clearing the bits. Again, a bit wasteful of space, but a possibly useful alternative. [Note: I originally had the table index in R0, but, as @Jeff White and @JasonACT indicated, R0 cannot be used for indexed addressing.] ...lee
  8. Here is one way: *++ Set CRU Bits (these two instructions must be in RAM so they can be modified!) SBOBIT SBO 0 SBZBIT SBZ 0 *++ Set specified CRU bit (1). R0 has bit to set in MSB. R12 must be set to appropriate CRU. MOVB R0,@SBOBIT+1 ;set up SBO instruction for appropriate CRU bit X @SBOBIT ;execute SBO for bit in R0 MSB *++ Reset specified CRU bit (0). R0 has bit to reset (clear) in MSB. R12 must be set to appropriate CRU. MOVB R0,@SBZBIT+1 ;set up SBZ instruction for appropriate CRU bit X @SBZBIT ;execute SBZ for bit in R0 MSB ...lee
  9. Jim (@Ksarul) was working on that a few years ago. I guess he has either abandoned the project or relegated it to a far back burner. ...lee
  10. If you know this information at assembly time, tighter code is simply LI R12,>1300 ;LOAD CRU BASE IN R12 SBO 0 ;ACTIVATE CARD SBO 7 ;TURN ON CARD LED Manipulating R12 becomes useful when you don’t know this information at assembly time. Such an example might be a program that gets CRU bits to turn on/off from the user. ...lee
  11. 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
  12. Just remember that CRU bits in R12 are offset 1 bit left, i.e., you should double any bits you add to R12. For example, if you want to set bit 5 of CRU >1D00, You would set R12 to >1D0A and use “SBO 0” to set it. That way you can always use the same SBO instruction without knowing the CRU bit at assembly time. This is actually the way it is done in fbForth (inherited from TI Forth). ...lee
  13. It has come to my attention that folks may not be privy to an FBLOCKS file that allows these betas to boot up as expected. Thanks, Bob (@atrax27407). Though it is not really ready for prime time (e.g., none of the BLOADs work!), here is my latest: FBLOCKS ...lee
  14. See information on the latest fbForth 3.0 betas and TODO list in this post. ...lee
  15. 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
  16. If you are using the console ISR to process sound lists, they must be located in VRAM or GROM/GRAM as @HOME AUTOMATION said. The examples in “Chapter 20” of the E/A Manual use VRAM. For VRAM, the LSb of >83FD must be 1 and for GROM/GRAM, it must be 0. >83FD is the GPL flag byte for 5 flags that occupy the 5 rightmost bits. You should not mess with the other flags. They have to do with cassette, multicolor settings, and VRAM. 8 indicates 16 KiB VRAM. If you want the list in CPU RAM, then you must write your own sound list processor as @FarmerPotato said. For fbForth, I wrote my own (starting with @Willsy’s TurboForth implementation), which is serviced by the fbForth ISR. You are welcome to the code, but it may be difficult to understand without a lot of explanation. ...lee
  17. Pretty sure this is not the case. I write to registers 8..14 in fbForth to set up 80-column text with no problem. That mode persists until changed by my code. The only caveat is to never attempt 80-column text mode with the TMS9918 unless you write the registers in descending order because the TMS9918 definitely masks registers 0..7. ...lee
  18. This should work: VDPWA EQU >8C02 ;VDP Write Address *++ Writing registers in reverse order is TMS9918 safe. TEXT80 BYTE 0,>10,>4F,0,0,0,>88,>4F,1,6,1,>E8,3,>F0,4 ;registers VR14..VR00 *++ Change these ^^ ^^ for different FG/BG colors. *++ They should be the same values. The >4F is dark blue on white. The reverse *++ (white on dark blue) would be >F4 for each of those two registers. *++ Set up VDP registers VR00 to VR14 in reverse order... VRSET LI R0,TEXT80 ;load address register table for TEXT80 LI R1,VDPWA ;load VDP Write Address LI R2,>8E00 ;start at VR14..8 (MSb set) is register-write flag MOVB @TEXT80+13,@>83D4 ;VR01 value to scratchpad RAM screen timeout loc LIMI 0 ;don't need if interrupts already disabled VSET02 MOVB *R0+,*R1 ;copy next VDP register's value to VDP NOP ;delay..not sure we need it MOVB R2,*R1 ;write VR# and write-reg flag AI R2,>FF00 ;next register down JNO VSET02 ;write another register if not done ...lee
  19. 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. ...lee
  20. 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
  21. 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
  22. Are you planning on just one day? I would think two or three days would be better. One of the problems with the Chicago Faire is that it is limited to a single day from 10:00 AM – 4:00 PM. I have been retired for a long time and would also visit family in Houston, so dates and times are of little concern to me. Count me in for whenever. ...lee
  23. * Mute all four sound generators * BL @MUTE to execute this routine * SOUND EQU >8400 MUTE LI R0,>9F00 byte to mute tone generator 0 LI R1,4 count for 4 generators MUTE1 MOVB R0,@SOUND mute next generator AI R0,>2000 inc to next generator DEC R1 done? JNE MUTE1 do another if not RT return to caller ...lee
×
×
  • Create New...