Jump to content

Airshack

+AtariAge Subscriber
  • Content Count

    1,549
  • Joined

  • Last visited

Posts posted by Airshack


  1. The 99/4 Equation Calculator menu option is evidence that this calculator company lacked vision and invited too many calculator engineers to the party.

     

    I'd be interested to hear about the decision to remove that (along with the calculator style overlay ready keyboard) from the 99/4A.

     

    Seems the calculator guys lost a battle but not before TI had already embarrassed themselves.

     

    Of course hindsight is always 20/20. I suppose it can be argued that the 99/4's overall form factor was better than the Atari 400 and PET.

     

     

     

    • Like 1

  2. No need to. We got Muliplan instead.

    The 99/4 Equation Calculator menu option is evidence that this calculator company lacked vision and invited too many calculator engineers to the party.

     

    I'd be interested to hear about the decision to remove that (along with the calculator style overlay ready keyboard) from the 99/4A.

     

    Seems the calculator guys lost a battle but not before TI had already embarrassed themselves.


  3.  

    ... it has comments from the original TI programmers for the same code.

     

    ...lee

    Wondering if any original TI Programmers are lurking about on AtariAge, or anywhere else?

     

    Just finished listening to a four part interview with Chuck Peddle the inventor of the 6502 CPU and Commodore PET.

     

    http://retrobits.libsyn.com/show-123-an-interview-with-chuck-peddle-part-i

     

    Wondering if any of our guys are still around and talking?


  4.  

    You might have a look at this thread: The TI-99/4A Operating System. TI’s KSCAN is in the first of the 3 files in the ZIP file of the first post. It is the original TI source code as far as we can tell.

     

    ...lee

     

     

    Hey Lee,

     

    Did I get it all?

    B    @>0070            To GPL interpreter** GPL SCAN (Scan keyboard with return to GPL interpreter):*       LI   11,>0070          Trick with return** Keybord scanning*KEYSCN MOV  11,@>83D8         Save R11       BL   @PUSHGA           Save GROM address to substack       CLR  12                CRU 0       SBO  >0015             Alpha lock       MOVB @>8374,5          Keyboard mode       SRL  5,8       MOV  5,6       JEQ  >02EC             0       LI   0,>0FFF       DEC  6                 1 R0=>0FFF       JEQ  >02F4       LI   0,>F0FF       DEC  6                 2 R0=>F0FF       JEQ  >02F4       DEC  6                 3       C    6,@>0072       JH   >0382             >5?       MOVB 6,@>8374          Keyboard mode 0       SWPB 6       MOVB 6,@>83C6          Keybord debounce (3=0, 4=1, 5=2)       CLR  5       CLR  0       CLR  6       JMP  >032E             Mode 0,3,4,5       DATA >2925       LI   12,>0024          Mode 1,2 scan Joystick       LDCR @>0405(5),3       CRU 06 and 07       LI   12,>0006       CLR  3       SETO 4       STCR 4,5               Fetch CRU       SRL  4,9       JOC  >0310             No fire key?       MOVB @>02F1(5),@>83E7  Lbyte R3       SLA  4,1       AI   4,>16E0           GROM address Joystick table       MOVB 4,@>0402(13)      Write address       MOVB @>83E9,@>0402(13)       JMP  >0322       MOVB *13,@>8376        Fetch values Y**~~Page 19:  TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*       MOVB *13,@>8377        and X       MOV  3,3               Fire key ?       JNE  >03AA       LI   1,>0005           Scan keys       CLR  2       CLR  7       LI   12,>0024       SWPB 1       LDCR 1,3               Load CRU       SWPB 1       LI   12,>0006       SETO 4       STCR 4,8               Fetch CRU       INV  4                 Invert bits       MOV  1,1               0?       JNE  >0354       MOVB 4,7       ANDI 4,>0F00       SZC  0,4       JEQ  >037A             No key?       MOV  1,1               Last loop?       JNE  >0360       MOV  5,5               Mode 1 or 2?       JNE  >037A       MOV  2,2               Already a key?       JNE  >037A       SETO 2       MOV  1,3       SLA  3,3       DEC  3       INC  3       SLA  4,1               Built key value in R3       JNC  >036C       MOV  1,1       JEQ  >037A       LI   1,>0001           Shorten loop       DEC  1       JOC  >0336             Smaller than 0?       MOV  2,2               Key pressed?       JNE  >03AA       CLR  6                 Set pointer for no key       MOVB 6,@>83C7       SETO 0       CB   0,@>83C8(5)       JEQ  >0394       BL   @>0498            Time delay       MOVB 0,@>83C8       MOVB 0,@>83C8(5)       MOV  5,5               Mode 1 or 2?       JNE  >0478             End       MOVB 0,@>83C9       MOVB 0,@>83CA       JMP  >0478             End**~~Page 20:  TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*       CB   @>83E7,@>83C8(5)  Same key as last time?       JEQ  >03E6       LI   6,>2000           Set GPL status       BL   @>0498            Time delay       MOVB @>83E7,@>83C8     Set pointer (Lbyte R3)       MOVB @>83E7,@>83C8(5)       MOV  5,5               Mode 1 or 2       JNE  >03E2       MOV  3,12       AI   12,>FFF8       JLT  >03E2       LI   1,>0002       SRL  12,3       JOC  >03DC       DEC  1       MOVB @>83E7,@>83C8(1)       MOVB 7,@>83C7          Last loop scanning on >83C7       MOVB @>83C7,7       LI   1,>17C0           GROM table mode 1 and 2       MOV  5,5       JNE  >040E       LI   1,>1790           GROM table CNTRL       SLA  7,2       JOC  >040E       LI   1,>1760           GROM table FCTN       SRL  7,15       JOC  >040E       LI   1,>1730           GROM table SHIFT       DEC  7       JEQ  >040E       LI   1,>1700           GROM address table small letters       A    3,1               +Key value       MOVB 1,@>0402(13)      Write address       MOVB @>83E3,@>0402(13)       JMP  >041C       MOVB *13,0             Values from GROM       MOV  5,5               Mode 1 or 2?       JNE  >0478       MOVB @>83C6,@>83E7     Keyboard mode in R3 Lbyte       BL   @>04A2            Compare       DATA >617A**~~Page 21:  TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*       JNE  >0444             Small letter?       CLR  12       MOV  3,3               Mode <4       JEQ  >043E       SBZ  >0015             Activate ALPHA LOCK       SRC  12,14       TB   >0007             Scan ALPHA LOCK       JEQ  >0442       SB   @>03B4,0          ->20 (Capital letter)       SBO  >0015       MOV  3,3               Mode 4 or 5       JNE  >0456       BL   @>04A2            Compare       DATA >101F       JEQ  >0382             R0 between >10 and >1F       CB   0,@>0587          5F?       JH   >0382       DEC  3                 Mode 5       JNE  >0478       CB   0,@>0025          0D (CR)?       JEQ  >0478       CB   0,@>02CA          0F?       JH   >046C       SOCB @>0470,0          Set 1st bit       JMP  >0478       BL   @>04A2            Compare       DATA >809F       JNE  >0478             R0 smaller than >80 or bigger than >9F       SZCB @>0470,0          Reset 1st bit       MOVB 0,@>8375          ASCII value key on >8375       BL   @POPGRA           Restore GROM address       MOVB 6,@>837C          Set GPL status       JEQ  >0492       MOVB @>83D4,*15        Load VDP register 01       CLR  @>83D6            Clear screen timeout counter       MOVB @>0B61,*15       MOV  @>83D8,11         Fetch return       B    *11** Time delay*       LI   12,>04E2          Loop counter       DEC  12       JNE  >049C       B    *11** Compare RO with status EQU if R0 is in area of Hbyte and Lbyte* of the data value*       MOV  *11+,12       CB   0,12       JL   >04B0**~~Page 22:  TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*       CB   0,@>83F9       JH   >04B0       CB   0,0       B    *11** CLEAR keyboard scanning(status EQU, if pressed):*CLRSCN LI   12,>0024          Load CRU keyboard select       LDCR @>0012,3          >00       SRC  12,7       LI   12,>0006       STCR 12,8              Fetch CRU       CZC  @>0036,12         Right key?       JNE  >04DC       LI   12,>0024          CRU 2nd key       LDCR @>0074,3          >03       SRC  12,7       LI   12,>0006       STCR 12,8              Fetch CRU       CZC  @>0036,12         Right key       B    *11               Back
    I'm guessing the time delay segment will raise issues with at least one member of this group?

  5. My .mag file? Okay, head over to the Berly thread, about page 15 or so and download the map *you* posted. icon_winking.gif It is your map. I used Magellan to check a few things like tile pattern assignments and actual size of the map, and the data export to assembly code, but that's it. The map data is unmodified since the idea was to use Magellan generated data and load it from disk. Right?

     

    lava.zip <==== Early Beryl Magellan File

     

    Magellan Graphics Editor Tool for TI-99/4A (runs on Windows): http://atariage.com/forums/topic/267322-programming-resources-for-ti-xb-graphicssprites/?p=3798140

     

    Some graphics inspiration: http://bifi.msxnet.org/msxnet/konami/

     

    Useful links while looking at the Viewport code from 2 June 2010


  6.  

    Remember, FUN1RT is just a label that we put at the last line of the function, line #1003. As written above the code would do an unconditional branch to address 0000 (and pretty much crash the computer). However, the 0000 is just a placeholder value so the code will assemble, and the value 0000 is modified when the code runs (which is what makes it "self modifying" code).

     

    It is now clear what is meant by "a placeholder," and the self-modifying code example is understood. The key for me understanding this example was realizing the placeholder is only there to satisfy the assembler.

     

    Coming from an interpreted BASIC paradigm, I was assuming the code "FUN1RT B @0" was always going to Branch to >0000. I forgot that this looks crash-worthy post-assembly, on a listing of the assembled code, yet it's modified at run-time to Branch to the intended return address.

     

    Clever!


  7. GameLp4D.a99 <==== Corrected GameLoop for Dummies commented code

     

     

    Playing around with that viewport code of Owen's (and the Matthew Methodology version) has me really excited right now. At first I thought Owen's Viewport code represented some skipping ahead, or at very least some confusing thread creep. My expectations were for Matthew to transition towards the next logical conversation --KSCAN..

     

    Loading and running the Viewport code has opened up some very interesting possibilities. It appears Owen is using the traditional KSCAN routine with his viewport code while Matthew is taking the "Roll Yer Own" approach.

     

    What better way to learn than to pour through both code segments and test the differences?

     

    InsaneMultitasker (Tim) correctly noted that there's nothing wrong with using the console routines. Here lies an opportunity to get familiar with the pre-written routines as well as some efficient custom routines. Win-Win!


  8. Thanks Lee! Earlier posts here outline the problems with using BLWP: speed, scratchpad RAM overwriting, etc.

     

    Looks to me like TI's KSCAN requires this... along with the REF... thus limitations to be avoided.

     

    I'll investigate your link. Thanks!


  9. After Matthew's GameLoop breakdown the thread seems to have moved along (page4), to Owen's viewport code (Beryl) with KSCAN used.

     

    I'm going to download that code and try to figure everything out next.

     

    Matthew mentioned his disappointment with TI's KSCAN code due to wasted speed via two delay loops.

     

    This is probably a good time to look into how KSCAN works. Hopefully Owen's code will be helpful in unravelling yet another TI coding mystery.

     

    Willsy posted (6 Jun 2010) KSCAN replacement code? Probably something I need to understand before moving on.

     

    I'll start with p.250 of the E/A manual, 16.2.1 KSCAN.


  10. Beware self-modifying code... I often do things like this versus using a stack... icon_wink.gif

     

    SUB1   MOV  R11,@SUB1RT+2
           ...
    SUB1RT B  @0
    

    Matthew - this is an awesome thread you've got running icon_smile.gif This is giving me some great ideas for a few programs I'd have trouble writing without getting out of my dsr/utility/input-driven serial-event processing mindset icon_smile.gif

     

     

    This sparked my interest! I'm guessing here:

     

    SUB1 MOV R11, @SUB1RT+2 * this stores the PC/return address of the calling code into a hard memory location immediately following this routine ???

     

    <code>

     

    SUB1RT B @0 *I don't get what the '@0' does or how it somehow gets ignored and replaced with the stored return address at SUB1RT+2 ???


  11. Thanks for the feedback guys!

     

    I just finished page three of this wonderfully informative 19 page thread. Again, I'm humbled by all the help I've received. Matt's approach to learning Assembly Language is something that has grabbed my attention but more importantly, it's really helping me learn while staying engaged.

     

    The Gameloop code from page three of this thread took me a while to wrap my mind around. In the process I read multiple user's comments and did some research into the TMS9900 Guide and TI's E/A manual.

     

    I've attached a version of Matthew's GameLoop code with "For Dummies" style comments and additional information in an attempt to encapsulate everything I have learned while pouring through the code. A beginner with some of the same questions as myself, and very few of the expert-like assumptions of a proficient Assembly programmer, may find the additional comments useful. Hopefully I'm not stepping on any toes doing so.

     

    This week I was able to demo the BASIC gameloop v Assembly Gameloop programs to Sparkdrummer at the July VAST meeting in PHX. We had a lot of fun looking at this code and comparing its performance to BASIC.

     

    Thanks again! - James

     

    GameLoop.a99

    • Like 1

  12.  

    You may understand this perfectly well, but the above code snippet might indicate otherwise. Just to be sure, DIV does operate on a 32-bit dividend in R4—R5. The only caveat is that R4 (MSW) must be smaller than R3, the divisor. Otherwise, the overflow bit will be set and R4—R5 will be untouched. R4 is not ignored. It is the MSW of the 32-bit dividend. It so happens as you indicated, that the dividend happens to fit in the 16 bits of the LSW.

     

    ...lee

    Thanks For the rapid feedback Lee! I read that about the source operand having to be larger than the first word of the destination operand, for "normal division to occur." Otherwise the resulting quotient won't fit inside a 16-bit word.

     

    What I meant by "ignored" (R4) is this specific code does nothing with the number (integer quotient) in R4 after the DIV executes. It's only concerned with the remainder.

     

    Seem right you? Otherwise, I will move on with the assumption that it's all understood.

     

    The big takeaway here was learning the peculiarity of the DIV OpCode, which is only peculiar to me because there's nothing similar going on with BASIC regarding which end of the equation needs to be smaller.


  13. This is the highly anticipated (well, for Owen anyway. icon_winking.gif ) game loop post!

    *********************************************************************** Plot a random character*PLOT*      Only draw on the VSYNC       C    @VSYNC,@NUM01     * If VSYNC is not active, return       JEQ  PLOT01       B    *R11PLOT01       MOV  R11,*R10+         * Push return address onto the stack*      Get a random screen location       BL   @RANDNO           * Get a random number (in R5)       LI   R3,768       CLR  R4                * Dividend will be R4,R5       DIV  R3,R4             * Make a number between 0 and 767       MOV  R5,R0             * Move to R0 for the VDP routine       AI   R0,NAMETB         * Adjust to the name table base*      Get a random character 40, 48, 56, 64       BL   @RANDNO           * Get a random number (in R5)       SRL  R5,14             * Make a number between 0 and 3       SLA  R5,3              * Multiply by 8 (number is now 0, 8, 16, 24)       A    @CHR040,R5        * Add to the base character       MOV  R5,R1       SWPB R1                * Remember, the MSB goes to the VDP!       BL   @VSBW       DECT R10               * Pop return address off the stack       MOV  *R10,R11       B    *R11*// PLOT

    Hey Matthew,

     

    I was able to easily understand most of this post up to the point where your code started plotting random characters on the screen. The DIV OpCode is where I started to stumble as I've never really used it before. I went to p.88 of the E/A manual as a reference.

     

    To help in my understanding of the logic I added comments as notes. A way to further clarify what exactly is going on between registers during the Divide, etc.

     

    Here's what I came up with in order for it all to be clear in my mind:

    *********************************************************************** Plot a random character*PLOT*      Only draw on the VSYNC       C    @VSYNC,@NUM01     * If VSYNC is not active, return       JEQ  PLOT01       B    *R11PLOT01       MOV  R11,*R10+         * Push return address onto the stack*      Get a random screen location       BL   @RANDNO           * Get a random number (in R5)... between 0 and 65,535 (2^16 -1)       LI   R3,768            * by cleverly using 768 as a divisor we assure any DIV remainder is ALWAYS 0-767       CLR  R4                * Dividend will be 32-bit R4&R5 (two words used by DIV) which is really just*                               a 16-bit dividend (R5) with leading zeros in R4 to satisfy the TI DIV OpCode       DIV  R3,R4             * divides destination operand (a consecutive 2-word workspace, R4&R5) by 768*                               Makes a number between 0 and 767 (see E/A manual p.88) in R5*                               - the resulting integer quotient (R4) is ignored here, does not matter*                               - the resulting integer remainder (R5) is ALWAYS between 0 and 767*       MOV  R5,R0             * Move to R0 for the VDP routine       AI   R0,NAMETB         * Adjust to the name table base*      Get a random character 40, 48, 56, 64       BL   @RANDNO           * Get a random number (in R5), again 0-65,535       SRL  R5,14             * Make a number between 0 and 3 using Shift Right Logical*                               Shifts bits in R5 right 14 times and fills left with zeros, leaving 2 LS-bits       SLA  R5,3              * Multiply by 8 (number is now 0, 8, 16, 24) using Shift Left Arithmetic*                               Shifts bits 1&0 left to positions 4&3, and fills in the right bits (2,1,0) with zeros       A    @CHR040,R5        * Add to the base character       MOV  R5,R1       SWPB R1                * Remember, the MSB goes to the VDP!       BL   @VSBW       DECT R10               * Pop return address off the stack       MOV  *R10,R11       B    *R11*// PLOT
    Does this all seem correct to you? I want to make sure my understanding of the situation is correct.

     

    I'm finding this thread incredibly helpful. Forgive my snails pace as I pick my way through the lessons. To me it seems to be moving along quite well yet based on the dates of your original posts I'm moving along a bit slower than Owen and the guys from 2010. Thanks again!

     

    -James


  14. While certain specialized applications like interfacing require coding on real hardware, everything else is so much easier and faster when done in emulation first.

    I absolutely get the special nostalgic feeling of coding on real hardware, and some of us create amazing stuff doing just that like Marc Hull for example, but there comes a point where the aggravation of aging and flaky hardware is counterproductive in my view...

    Have you tried Tidbit? Allows programming BASIC with labels in place of line numbers which really improves the BASIC experience.

     

    Editing on a modern PC + Tidbit = a delight!

    • Like 2

  15. Would there be any interest in a series of "how-to" videos showing how to do various things in TurboForth?

    Yes! I'd like to see some sort of TI version of this:

     

    http://64bites.com/

     

    "If so please say so here and give an idea of the topics you'd like to see covered and I'll see what I can do."

     

    An introduction to include workflow and supporting software: editor, emulator, etc. it doesn't have to be ultra professional, just informative. The following example was made with an iPhone in just 30 minutes and one take:

     

    Example: https://youtu.be/YwQL1-CZGO8

     

    ^^^Includes the all-important "how-to" on getting code written and imported into the emulator, and then exported to the TI itself. Ideal for beginners new to the TI Cult.

     

    "If anyone else wants to make some videos, of TurboForth, fbForth, or Camel 99 Forth please go right ahead. I'd love to get more TIers at least having a dabble with Forth!"

     

    It'd be nice to have a pinned thread to go to or an agreed upon YouTube central channel.

    • Like 1

  16. This was posted on Facebook:

     

    http://spectrum.ieee.org/geek-life/history/the-inside-story-of-texas-instruments-biggest-blunder-the-tms9900-microprocessor

     

    Bit of a hatchet job if you ask me. It also contains a number of facial errors.

     

    Thanks to Stefan Holtgen for posting it.

     

    I wasn't aware of the video game console part of the story. Wondering if any details exist?


  17. RoLB and ROLB are the same, but R0LB is not. It should be R0LB in this case.

     

    And yes, END marks the physical end of what should be assembled, not the logical end of the main program.

     

     

    Yep! I must have had R<zero>LB in there. Good to know RoLB = ROLB so no case sensitivity. I was using the "END" as I had with BASIC I suppose. So it's an Assembler Directive, not an OpCode.

     

     

     

    You can make code absolute or relocatable. When it's absolute, it's always possible to fully resolve all addresses during assembly. You know for example that the code should load at >A000, so you know that an address, like KALLE, that's >10 bytes down the code must be >A010. The CPU can only execute absolute code.

     

    Is it safe to assume I'll be writing strictly relocatable code vs absolute code?

     

    Thus the assembler will resolve the address relative the code segment start, and then the loader will finally resolve the address by adding the code segment loading address. When that's completed, the code in memory is now absolute and can be executed.

     

    The way you phrased this makes it easy for me to understand. I didn't get that earlier in my reading.

     

     

    But the loader supplied with the TI 99/4A is more clever than that. It's not only a loader capable of loading relocatable code, but it's a linking loader. That implies that you can load code that contains addresses that are completely unknown at assembly time.

     

    Same comment as above.

     

    That piece of code also contains the directive DEF KALLE, to indicate that the definition of KALLE is external, and thus made available to other programs.

     

    I didn't realize this was happening with DEF making it external/global. This is quite powerful and a big potential time saver.

     

    Wondering if this how SPECTRA by Retroclouds works? A collection of arcade game enabling routines imported by REF's at the beginning of my code?

     

    1. You have loaded this code, with DEF KALLE inside, before you load the code that contains REF KALLE.

     

    My Assembler workflow includes using Classic99 with the E/A Cart, Option 3 Load and Run.

     

    With multiple source code files I'd have to load.... say... the VDP Routine file before the Main Program file. I'd need DEFs in the VDP Routine file and associated REFs in the Main Program file. I'd have to remember to load the VDP Routine file first.

     

    How do most people automate this?

     

    I anticipate issues with several or more support (DEF) packages.

     

     

    In the example above, you got away with REF VSMW ​at assembly time, because it simply tells the assembler that it's up to the loader to fix the VSMW reference. But at load time, it would have exploded, since the label VSMW wasn't actually externally DEFined by any other program.

     

    This really clears up a lot regarding REF v DEF.

     

     

    This whole concept is a powerful one, since it allows you to build libraries of frequently used functions, and include external definitions in these libraries. They may then be externally referenced from other programs, so that you can load the same library as one code file, and use it from different other code files. This is exactly what the E/A system provides for you.

     

    Also seems it'd become tedious if you had more than a few libraries to load.

     

    Since the tagged object code loader can load relocatable code at any address it finds convenient, it doesn't matter how big the library is. Your program will always load after it, regardless of where that's in memory. This was a capability inherited from the system used in the TI 990 minicomputers, and was more powerful than what was available in several contemporary home computers.

     

    Always appreciate a little History with my daily computer lessons! THANK YOU! Great reply!

×
×
  • Create New...