Jump to content

Photo

That's why TI BASIC is so slow!


177 replies to this topic

#1 Airshack OFFLINE  

Airshack

    Moonsweeper

  • 346 posts
  • Location:Phoenix, AZ

Posted Tue Apr 11, 2017 12:53 PM

I'm not sure I understand why?

A. BASIC is written in GPL (vs assembler) so it's twice interpreted: once for BASIC-to-GPL + once for GPL-to-machine code. Most BASICs of the day were written in Assembler so they're only interpreted once (BASIC-to-machine code) as they run programs.

B. The whole 16-bit CPU shoehorned into an 8-bit motherboard (data bus 8-bit) is the reason.

C. The VDP RAM boondoggle? CPU needs to request info from VDP and then wait for VDP to grab info and notify CPU.

D. Other reasons such as the water in Lubbock.

Please clarify if you understand the complete story. Thx!




Sent from my iPhone using Tapatalk

#2 mizapf ONLINE  

mizapf

    River Patroller

  • 2,308 posts
  • Location:Germany

Posted Tue Apr 11, 2017 1:16 PM

A. I see the GPL support as an early version of a virtual machine, as you know from Java. In fact, TI emulates a complex instruction set 8-bit CPU, the GPL is its machine language, and thus TI BASIC is actually running in this virtual machine. So yes, I would consider this is the primary cause. Note that Extended Basic reimplements some functions in its cartridge ROM for faster execution.

 

B. Partly yes, but the Geneve uses the 9995 which has the data bus multiplexer built into the package and is arguably pretty fast (with higher clock, yes). Also, this was not so uncommon; consider the Intel 8088, a 16-bit CPU with 8 bit data bus, or the 80386SX (32 bit with 16 bit data bus). The problem is rather that the TI CPU 9900 implements byte access in an awkward way, requiring it to always load a memory word before changing one of its bytes, then writing the word back. Together with the data bus multiplexer and wait states, this add up to a lot of CPU cycles.

 

C. The VDP is not such a narrow bottleneck in that architecture, particularly considering the virtual machine as described in A. It is a problem for the native machine, since you cannot execute machine language programs from it. The VDP does not notify the CPU; it does not even have a busy line, which is also a pity, since that means you have to take care for the timing in your program (using NOPs for example).


Edited by mizapf, Tue Apr 11, 2017 1:17 PM.


#3 Asmusr ONLINE  

Asmusr

    River Patroller

  • 2,273 posts
  • Location:Denmark

Posted Tue Apr 11, 2017 1:46 PM

I would add:

 

E. That all numbers are floating point.

 

But I guess that was the standard in BASIC.



#4 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,044 posts

Posted Tue Apr 11, 2017 3:13 PM

Several BASICS of the era supported straight integers as well as numerics... I believe they used the % symbol to indicate an integer variable or array.

 

I think the worst problem with the architecture is just the (near) lack of CPU memory. I understand why all the RAM was in the VDP only; memory was expensive at the time.

 

The memory issue cropped up even with cartridges as well. I know that several of TI's attempts to get commercial software produced for the TI failed in part because they demanded the 3rd party try and fit everything in the 8K memory slot for cartridges. In particular, Zaxxon was right out.



#5 RXB OFFLINE  

RXB

    River Patroller

  • 2,514 posts
  • Location:Vancouver, Washington, USA

Posted Tue Apr 11, 2017 9:30 PM

A. I see the GPL support as an early version of a virtual machine, as you know from Java. In fact, TI emulates a complex instruction set 8-bit CPU, the GPL is its machine language, and thus TI BASIC is actually running in this virtual machine. So yes, I would consider this is the primary cause. Note that Extended Basic reimplements some functions in its cartridge ROM for faster execution.

 

B. Partly yes, but the Geneve uses the 9995 which has the data bus multiplexer built into the package and is arguably pretty fast (with higher clock, yes). Also, this was not so uncommon; consider the Intel 8088, a 16-bit CPU with 8 bit data bus, or the 80386SX (32 bit with 16 bit data bus). The problem is rather that the TI CPU 9900 implements byte access in an awkward way, requiring it to always load a memory word before changing one of its bytes, then writing the word back. Together with the data bus multiplexer and wait states, this add up to a lot of CPU cycles.

 

C. The VDP is not such a narrow bottleneck in that architecture, particularly considering the virtual machine as described in A. It is a problem for the native machine, since you cannot execute machine language programs from it. The VDP does not notify the CPU; it does not even have a busy line, which is also a pity, since that means you have to take care for the timing in your program (using NOPs for example).

 

Very true in the XB ROM's you see a crap load of JMP $+2 which means do nothing and just jump to next instruction and I think they did not know there was a CPU NOP (No Operation) instruction in the CPU.

These are there in XB ROM's to allow for all the VDP only access being used which slows down XB considerably. 

Example in VDP STACK takes much longer then RAM stack to do the same thing and every variable name or Subroutine is pushed onto the VDP Stack temporarily at one time or another again slows XB.


Edited by RXB, Tue Apr 11, 2017 9:37 PM.


#6 RXB OFFLINE  

RXB

    River Patroller

  • 2,514 posts
  • Location:Vancouver, Washington, USA

Posted Tue Apr 11, 2017 9:37 PM

I'm not sure I understand why?

A. BASIC is written in GPL (vs assembler) so it's twice interpreted: once for BASIC-to-GPL + once for GPL-to-machine code. Most BASICs of the day were written in Assembler so they're only interpreted once (BASIC-to-machine code) as they run programs.

B. The whole 16-bit CPU shoehorned into an 8-bit motherboard (data bus 8-bit) is the reason.

C. The VDP RAM boondoggle? CPU needs to request info from VDP and then wait for VDP to grab info and notify CPU.

D. Other reasons such as the water in Lubbock.

Please clarify if you understand the complete story. Thx!




Sent from my iPhone using Tapatalk

 

Most of the issue with TI BASIC speed was EVERYTHING RAN FROM VDP. 

This is unlike XB that with no memory expansion XB still has Assembly in three 4K ROM's running from a console, thus improved speed of XB execution.

With a memory expansion of 32K XB would move the Numeric variables and XB program into upper 24K of RAM, as this also increased speed of XB execution.

 

Both TI BASIC and XB were mostly written in GPL, but TI Basic being 100% restricted to VDP RAM ONLY and no Assembly support built in really slowed it to a crawl.



#7 Torrax OFFLINE  

Torrax

    Star Raider

  • 80 posts

Posted Tue Apr 11, 2017 10:56 PM

The question is why they didn't uncripple several features with the release of the TI-99/4A in 1981.  Like extend the SRAM to 1,2, or 4K and add the 32K internally. A MMU of some sort would of been nice too -- along with a newer mlx XB with expanded memory support (similar to the TI-99/8).  This would of allowed it to compete with the likes of the C64, Atari 800, and Apple II+/e.  Instead they battled it out in price war against Commodore's low-end Vic-20.

 

Just boils down to woulda-shouda-coulda that TI missed in the 80's.


Edited by Torrax, Tue Apr 11, 2017 11:05 PM.


#8 --- Ω --- OFFLINE  

--- Ω ---

    --- Ω ---

  • 9,971 posts
  • Location:Virgo Supercluster, Gould Belt in the Orion arm of Milky Way galaxy.

Posted Tue Apr 11, 2017 11:34 PM

TI-BASIC

 

slower-than-molasses-copy.jpg

 

IN JANUARY


  • RXB likes this

#9 Stuart OFFLINE  

Stuart

    Dragonstomper

  • 648 posts
  • Location:Southampton, UK

Posted Wed Apr 12, 2017 2:57 AM

 

...  and I think they did not know there was a CPU NOP (No Operation) instruction in the CPU.

 

 

Really? I think you'll find that NOP just assembles to JMP $+2.



#10 RXB OFFLINE  

RXB

    River Patroller

  • 2,514 posts
  • Location:Vancouver, Washington, USA

Posted Wed Apr 12, 2017 4:10 AM

 

Really? I think you'll find that NOP just assembles to JMP $+2.

I used to have the original XB ROM source code from TI and no it did not use the NOP but had JMP $+2

Seems unlikely he TI Assembler did not contain NOP, more likely like many things in the TI the left had did not know what the right hand was doing.

 

Like in XB ROMs they have odd code that GPL does faster than the Assembly versions they made in XB ROMs. 

 

GVWITE is a GROM to VDP routine that is slower then the GPL MOVE command as it takes more bytes to set up and execute and is no faster.

I have run tests and many of the routines in XB ROM are faster but some are actually slower than GPL equivalent commands.


Edited by RXB, Wed Apr 12, 2017 4:23 AM.


#11 senior_falcon OFFLINE  

senior_falcon

    Dragonstomper

  • 828 posts
  • Location:Lansing, NY, USA

Posted Wed Apr 12, 2017 5:26 AM

The 9900 instruction set does not have NOP.  It is a pseudo-instruction that the TI assembler converts to a JMP instruction as Stuart says.



#12 Lee Stewart ONLINE  

Lee Stewart

    River Patroller

  • 3,150 posts
  • Location:Silver Run, Maryland

Posted Wed Apr 12, 2017 5:50 AM

 

Really? I think you'll find that NOP just assembles to JMP $+2.

 

The 9900 instruction set does not have NOP.  It is a pseudo-instruction that the TI assembler converts to a JMP instruction as Stuart says.

 

Indeed so!  Here is Section 13.1 on page 206 of the Editor Assembler Manual, Section 13 “Pseudo Instructions”:

 
13.1  NO OPERATION--NOP
 
Syntax definiton:
 
    [<label>] b NOP b [<comment>]
 
NOP places a machine instruction in the object code which only effects [sic] the execution
time of the program. Use of the label field is optional. When the label field is
used, the label is assigned the location of the instruction. The operation field
contains NOP. The operand field is not used. Use of the comment field is optional.
 
Enter the NOP pseudo-instructions as shown in the following example.
 
    MOD NOP
 
Location MOD contains a NOP pseudo-instruction when the program is loaded.
Another instruction may be placed in location MOD during execution to implement a
program option. The Assembler supplies the same object code as though the source
statement contained the following code.
 
    MOD JMP $+2
 
...lee


#13 apersson850 OFFLINE  

apersson850

    Chopper Commander

  • 228 posts

Posted Wed Apr 12, 2017 11:40 AM

Reading data from GROM or VDP RAM isn't that extremely slow, as long as you read consecutive addresses. But when you start modifying the address, the overhead to load a new address and then read data is substantial.

At least the GPL interpreter runs from 16 bit ROM.

My console, which has 64 K RAM built in, on 16 bit wide bus, is about 110% faster than an original TI 99/4A, when you run programs that has both code and workspace in expansion RAM. That is, in memory that normally is only 8 bit wide. This give you an idea about how a "real" Commodore 64 competitor version could have performed, with little change to the rest of the architecture.

Of course, all sensibly written software doesn't speed up that much, since it has workspace in RAM PAD, which already is 16 bit wide.



#14 Tursi OFFLINE  

Tursi

    River Patroller

  • 4,597 posts
  • Location:BUR

Posted Wed Apr 12, 2017 3:36 PM

I did some analysis when I first implemented the UberGROM, since I expected to see some speed boost if I pulled the console GROMs out, and did not. My analysis suggested it's all in the GPL interpreter. It's partly because the GPL interpreter was coded for memory, not speed - as such it jumps around a lot and tends to repeat calculations and memory sets that it has already done. But on average (IIRC), I came up with a number of something like 30:1 CPU instructions to GPL instructions - even the simple ones. Many of them could be much faster with the coding techniques we have today - but that's a rewrite of the GPL interpreter. Every so often I get the urge to prove this claim, but time is not something I've got a lot of. :/ Basically it means that any time lost to accessing slow VDP or slower GROM is completely overshadowed by how much code is executed just to get there. They add impact, but it's a smaller piece.



#15 apersson850 OFFLINE  

apersson850

    Chopper Commander

  • 228 posts

Posted Thu Apr 13, 2017 6:14 AM

That makes sense. Here's a stub of an interpreter for a byte-coded (to save memory) stack machine (similar to the PME, that runs the p-code card). SP is stack pointer, CP is code pointer. EREC is the current environment record, inside which the currently executing procedure's local variables are stored.

Each op-code is assumed to define the instruction completely. Even with this very simple approach, the instruction fetch and decoding loop is five instructions. Then add the instruction itself, which for these simple examples adds 2-5 instructions to interpret one instruction code. So here we have ten instructions to accomplish what two could do, or seven to do what one could do, if it was normal assembly code that was running instead of interpreted code on byte level.

interp: MOVB *CP+,R1
        SRL  R1,7
        MOV  @INTTAB(R1),R0
        BL   *R0
        JMP  interp

; Code for ADD values at stack, return result on stack
addc:   A    *SP+,*SP
        B    *R11

; Code for INC top of stack
incc:   INC  *SP
        B    *R11

; Code for push integer immediate to stack
push:   MOVB *CP+,R1
        MOVB *CP+,@R1LBYT
        DECT SP
	MOV  R1,*SP
	B    *R11

; Code for local store integer (offset into local variable area in byte after instruction)
locst:  MOVB *CP+,R1
        SRL  R1,7
        MOV  *SP+,@EREC(R1)
        B    *R11






















Edited by apersson850, Thu Apr 13, 2017 6:23 AM.


#16 RXB OFFLINE  

RXB

    River Patroller

  • 2,514 posts
  • Location:Vancouver, Washington, USA

Posted Thu Apr 13, 2017 12:11 PM

Interpreted means you can program and test on the fly instantly.

 

Interpreted requires:

1. Write Code.

2. if not correct go to step 1 and start over.

 

Pro and Con interpreted is fast on turn around on finished product is  easy to read and debug. Slow execution.

 

Compiled requires:

1. Write Code.

2. Compile Code.

3 Load and RUN code to test it.

4. If not correct go to step 1 and start over.

 

Pro and Con compiled is slow on turn around on finished product is hard to read and debug. Fast execution.

 

I think Forth is best for both worlds as it is both interpreted and compiled. Big con is you write Forth code to suit the RPN stack construction.


Edited by RXB, Thu Apr 13, 2017 12:14 PM.


#17 --- Ω --- OFFLINE  

--- Ω ---

    --- Ω ---

  • 9,971 posts
  • Location:Virgo Supercluster, Gould Belt in the Orion arm of Milky Way galaxy.

Posted Thu Apr 13, 2017 12:29 PM

If it's FINISHED, I would not be at all concerned with reading it or debugging it in it's compiled form.

I'd keep the BASIC source code if I thought I might want to change it at a later date.

 

For a guy like me a BASIC compiler is a WIN(1)-WIN(2)-WIN(3).

 

1)  I don't have to spend the rest of my life trying to learn assembly language just to write a program.

2)  I can use a language I already know and can tweak at whim.

3)  Once I get it the way I want it... convert it into something better and more 'usable'.



#18 mizapf ONLINE  

mizapf

    River Patroller

  • 2,308 posts
  • Location:Germany

Posted Thu Apr 13, 2017 1:49 PM

1)  I don't have to spend the rest of my life trying to learn assembly language just to write a program.

 

Think twice. You deliberately waste the chance to become a 1337 h4XX0r of the TI. ;)



#19 Asmusr ONLINE  

Asmusr

    River Patroller

  • 2,273 posts
  • Location:Denmark

Posted Thu Apr 13, 2017 2:00 PM

My build cycle for assembly is like this:

 

1) Edit code in IntelliJ IDEA on PC (using Ralph's plugin) with syntax highlighting,  global label renaming, short cut key for jumping to labels, etc..

2) Press a button to build disk and cartridge images within seconds using the xas99, xdm99 and my own cartridge build tool.

3) Open and run object file directly in js99er.net without pressing any keys on the TI.

 

All in all about 10 seconds from making a change in the code until you can see the result.  :grin:



#20 apersson850 OFFLINE  

apersson850

    Chopper Commander

  • 228 posts

Posted Thu Apr 13, 2017 3:11 PM

I've never really used any TI 99/4A that hasn't been the real thing.

But when the 99 was the computer I had, I mainly used the p-system, and Pascal, for my software development. In that case I wrote everything that was doable in Pascal, and that's quite a lot, in Pascal. When the code worked, I used it as it was, if that was satisfactory. If there was a speed problem, I'd think about what part of the code was best to optimize, and then convert that to assembly. Normally I had a good idea about which part would be a good candidate for conversion to assembly already when starting out, so I made sure I wrote that part as a Pascal function/procedure in such a way that it would be easy to convert it to assembly.

Thus I didn't spend time designing things like data entry or disk access in assembly, since there are other things around these activities that are slowing them down anyway. Like running the drive or me typing on the keyboard. But a procedure to sort numbers or whatever would be very good to convert to assembly, to speed it up. Especially since such tasks often are time consuming.



#21 RXB OFFLINE  

RXB

    River Patroller

  • 2,514 posts
  • Location:Vancouver, Washington, USA

Posted Thu Apr 13, 2017 8:55 PM

My build cycle for assembly is like this:

 

1) Edit code in IntelliJ IDEA on PC (using Ralph's plugin) with syntax highlighting,  global label renaming, short cut key for jumping to labels, etc..

2) Press a button to build disk and cartridge images within seconds using the xas99, xdm99 and my own cartridge build tool.

3) Open and run object file directly in js99er.net without pressing any keys on the TI.

 

All in all about 10 seconds from making a change in the code until you can see the result.  :grin:

And not on a TI Console, you have to use a PC and then you can run it on the TI99/4A or a Emulator.

 

I use Classic99 myself using text and using TIDIR99 to put into a TI DV80 Source file, then assemble it in Editor Assembler.

Most of what I do could be done on the TI instead, you are on the other hand have to use the PC.

 

Point is it is not TI in anyway it is all Emulation of TI.

Fine you can do that but do not pretend it is the same as using a real TI99/4A, and I do realize I am using a emulator not real hardware.



#22 Tursi OFFLINE  

Tursi

    River Patroller

  • 4,597 posts
  • Location:BUR

Posted Thu Apr 13, 2017 11:33 PM

I use Classic99 myself using text and using TIDIR99 to put into a TI DV80 Source file, then assemble it in Editor Assembler.

 

Classic99 can read Windows text files natively - you could skip this step. Just give it a .TXT extension (and of course use a disk folder, rather than a disk image). I used to build my programs through Editor Assembler this way.

 

https://youtu.be/GbpiUzn6kt0



#23 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 8,220 posts
  • Location:Cookeville, TN

Posted Fri Apr 14, 2017 1:02 AM

^^That's how I do it on the occasion I use EdAsm on Classic99.

Great feature!!

Edited by Opry99er, Fri Apr 14, 2017 1:03 AM.


#24 RXB OFFLINE  

RXB

    River Patroller

  • 2,514 posts
  • Location:Vancouver, Washington, USA

Posted Fri Apr 14, 2017 1:15 AM

 

Classic99 can read Windows text files natively - you could skip this step. Just give it a .TXT extension (and of course use a disk folder, rather than a disk image). I used to build my programs through Editor Assembler this way.

 

https://youtu.be/GbpiUzn6kt0

This gives me a second copy in DV80 format in case I make changes to text file. It is my way to have auto backups of what I am doing without the worry of forgetting to backup files.

 

Also when GPL Assembling files 4000 lines long I have no line numbers in PC Text files to find the line with the problem.

 

GPL Assembler says unknown symbol in line 743 so how the hell do I know where line 743 is in a PC NotePad text file?

(I do not like Notepad + or Notepad 2 as they attempt to make everything a NotePad + or NotePad 2 file.)


Edited by RXB, Fri Apr 14, 2017 1:20 AM.


#25 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 8,220 posts
  • Location:Cookeville, TN

Posted Fri Apr 14, 2017 2:02 AM

Notepad++ saves as a standard .txt file... it also has line numbers. Has been a life saver when assembling long source files. I dont have anything 4000 lines long but I do have some over 100. :)




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users