Jump to content
IGNORED

TI-99/4A vs ZX81


2600problems

Recommended Posts

That could be. The floating point instructions in the TI 99/4A are optimized towards accuracy, not speed. It uses radix 100 coding instead of binary, to avoid rounding errors. Divide or multiply by 100 is frequently called for in such math routines, so maybe they do use that. I've not studied these routines in detail. I just know that the 99/4A computes floating point numbers to significantly better accuracy than most other computers.

This is probably due to the influence from the calculator division, since TI calculators, like the TI-59, had good math accuracy.

 

I didn't think about the block move instruction in the Z80. That for sure makes a difference in favor of the Z80. I've mainly used the Intel 8085 back then, not the Z80.

Edited by apersson850
Link to comment
Share on other sites

If you are dealing with floating point, you probably aren't using the integer multiply and divide instructions.

I don't know the guts of the TI BASIC math library, but I know Microsoft doesn't take advantage of the multiply instructions on the 6803 and 6809.

 

TI Basic uses the TI-99/4A's console routines (both XML and GPL) for floating point math. The XML FMULT and FDIV routines use the TMS9900 MPY and DIV instructions, which are integer operations. Here are the relevant XML console routines:

 

 

 

*
* FLOATING MULTIPLICATION FAC:= ARG * FAC
*
* ENTRY NOT KNOWN
FMULT MOV R11,R10 SAVE RTN
JMP FMULT1
* = BL *R2
SMULT MOV R11,R10 STACK MULTIPLICATION
BL @POPSTK
FMULT1 LI R3,FAC IF FAC IS ZERO
LI R5,ARG
MOV *R3,R8 IF FAC IS ZERO
JEQ FMULZR THEN RESULT IS ZERO
XOR *R5,R8 COMPUTE SIGN RESULT
ABS *R5 IF ARG IS ZERO
JEQ FMULZR THEN ZERO FAC AND RTN
ABS *R3 TAKE ABS VALUE OF FAC
CLR R9 TO ZERO LOW BYTE OF RESULT EXP
MOVB *R3,R9 RESULT EXP = FAC EXP
AB *R5,R9 +ARG EXP
SWPB R9
AI R9,-63 - BIAS
MOV R9,@EXP
MOVB R8,@SIGN SAVE TILL NORMAL, ROUND
LI R5,FAC+8 LOW ORDER DIGITS
FMCLR CLR *R5+ WILL BE
CI R5,FAC+16 FORMED
JNE FMCLR HERE
*
* R0-R1 WORK REGISTERS FOR MPY, DIV
* R2 CURRENT RESULT DIGIT
* R3 CURRENT FAC DIGIT
* R4 REGISTER NUMBER LOOP COUNT
* R5 FAC LOOP COUNT
* R6 POINTER TO RESULT IN FAC
* R7 NUMBER OF SIGNIF. BYTES IN ARG FRACTION
* R8 RB(R0) POINTER
* R9 RADIX 100 VALUE
LI R5,FAC+8 BYTES IN FAC +1
FMUL02 DEC R5 CHANGE SIGNIF. BYTE COUNT
MOVB *R5,R0 IF NEXT FAC BYTE IS ZERO
CECE JEQ FMUL02 THEN DECREMENT COUNT FOR IT
LI R7,8 COUNT SIGNIF. BYTES IN ARG
FMUL03 DEC R7 DEC. FOR ZERO BYTE
MOVB @ARG(R7),R0 IF THIS BYTE OF ARG IS ZERO
JEQ FMUL03 THEN DEC. COUNT
CLR R0 MPY, DIV WORK REGR
MPY R0,R2 CURRENT RESULT IN HIGH BYTE
MOV R5,R6
LI R8,R0LSB RB (R0)
LI R9,100 RADIX
FMUL04 MOV R7,R4 INNER LOOP CTR = BYTES IN ARG
A R7,R6 RESULT PTR TO END OF NEXT PARTIAL
* PRODUCT
MOVB *R5,@R3LSB RB(R3) IS NEXT DIGIT OF FAC
MOVB R3,*R5 CLEAR FAC DIGIT FOR NEXT PARTIAL
FMUL05 MOVB @ARG(R4),*R8 GET NEXT DIGIT OF ARG
MPY R3,R0 AND MPY IT
MOVB *R6,@R2LSB TO CORRESPONDING PARTIAL PRODUCT
* DIGIT IN RB (R2)
A R2,R1 ADD IN NEXT PARTIAL PROD DIGIT
DIV R9,R0 CONVERT PRODUCT TO RADIX DIGIT
* AND CARRY
MOVB @R1LSB,*R6 STORE NEW RESULT DIGIT IN FAC
DEC R6 POINT TO NEXT HIGHER BYTE OF RESULT
AB *R8,*R6 ADD IN CARRY TO NEXT HIGHER BYTE
* OF RESULT
DEC R4 IF ALL ARG DIGITS NOT DONE,
JGT FMUL05 THEN CONTINUE
DEC R6 POINT TO START OF NEXT PARTIAL PROD
DEC R5 IF FAC DIGITS REMAIN
CI R5,FAC
JGT FMUL04 THEN CONTINUE
FMEND CLR @FAC+10 CLEAR ERROR INDICATOR
*
* SIGN DESTROYS R0 - R2
*
NORMAL LI R1,-9 NUMBER OF BYTES IN FAC INCLUDING
* GUARD BYTES
NORM01 MOVB @FAC+10(R1),R2 IS NEXT BYTE OF FAC NON-ZERO?
JNE NORM02 YES, SHIFT REST LEFT
INC R1 NO, ALL BYTES ZERO?
JLT NORM01 YES, LOOK AT NEXT BYTE
*
* ZERO FAC, SETS FAC =0
*
FMULZR CLR @FAC INSTALL FLOATING ZERO
CLR @FAC+2 CLEAR POSSIBLE BASIC TYPE CODE
JMP STEX AND EXIT WITH STATUS
NORM02 MOV R1,R0 NUMBER OF NON-ZERO BYTES
AI R0,9 FIRST BYTE NON-ZERO?
JEQ ROUN1 YES, FINISH
S R0,@EXP NO, ADJUST EXPONENT FOR SHIFT
LI R2,FAC+1 POINT TO FIRST BYTE OF FAC
NORM03 MOVB @FAC+10(R1),*R2+ MOVE NON-ZERO BYTE
* TO FAC FIRST DIGIT
INC R1 IF NON-ZERO BYTES REMAIN
JLT NORM03 THEN MOVE ANOTHER BYTE
NORM04 MOVB R1,*R2+ MOVE A ZERO
DEC R0 LAST BYTE DONE?
JGT NORM04 NO, CONTINUE
* YES, ROUND THE NO. IN FAC AND FINISH
*
* ROUND THE NUMBER IN THE FAC USING THE GUARD DIGITS
* DESTROYS R0-R2
* ENTRY NOT KNOWN
JMP ROUN1 SKIP SAVE IF INTERNAL CALL
ROUND MOV R11,R10 SAVE RTN
ROUN1 LI R0,50*HIBYTE
C @FAC+8,R0 IS ROUNDING NECESSARY?
JLT PACKUP NO, PUT EXPONENT BACK
LI R1,7 ROUND UP, GET NO. OF FAC BYTES
ROUNUP LI R2,1*HIBYTE 1 (FOR BYTE INSTN)
LI R0,100*HIBYTE 100 (SAME)
ROUN02 AB R2,@FAC(R1) ADD ONE TO A BYTE OF FAC
CB @FAC(R1),R0 IF BYTE NOT GREATER THAN RADIX
JL PACKUP THEN PUT EXPONENT IN FAC
SB R0,@FAC(R1) BRING DIGIT BACK IN RANGE
DEC R1 IF CARRY PAST HIGH BYTE OF FAC
JGT ROUN02 THEN CARRY TO NEXT HIGHER BYTE
INC @EXP FRACTION HAS OVERFLOWED (WAS ALL 9'S)
* SHIFT NO. BY ADDING 1 TO EXP
MOVB R2,@FAC+1 MAKE THE HIGH BYTE A 1
*
* PUT SIGN AND EXPONENT IN FAC
*
PACKUP MOV @EXP,R3
CI R3,128
JHE OVEXP1
MOVB @R3LSB,@FAC PUT EXPONENT IN FAC
MOVB @SIGN,R2
INV R2 IF SIGN IS -VE
JLT PACK01
NEG @FAC THEN INVERT 1ST WORD
PACK01 JMP STEX SKIP SAVE IF INTERNAL CALL
* ENTRY NOT KNOWN
STEXIT MOV R11,R10 SAVE RETURN ADR
STEX MOV @FAC,R1 SET STATUS ON FAC
STEX01 STST R2 AND PUT IT
MOVB R2,@STATUS IN THE STATUS REGISTER
B *R10 THEN RETURN TO GLI
* ROUND FAC BEGINING AT DIGIT SPECIFIED IN ARG
* ENTRY NOT KNOWN
ROUNU MOV R11,R10 SAVE RTN
MOVB @FAC+10,R1 PICK UP OFFSET
SRL R1,8
JMP ROUNUP AND DO IT
*
* ERROR ROUTINE EXITS
*
* DIVIDE BY ZERO EXIT
*
* ENTRY NOT KNOWN
DIVZER LI R9,DZERR DIVIDE BY ZERO CODE FOR USER
JMP BIGFLT LARGEST MAGNITUDE WITH SIGN
* ----- OVER/UNDERFLOW -----
* ENTRY NOT KNOWN
OVEXP MOV R11,R10 SAVE RTN
OVEXP1 MOVB @EXP,R2 IS EXPONENT -VE?
JLT FMULZR YES, RETURN ZERO
JMP OV1 SKIP SAVE IF INTERNAL CALL
* ENTRY NOT KNOWN
OV MOV R11,R10 SAVE RTN
OV1 LI R9,OFERR
* SUPPLY THE LARGEST MAGNITUDE VALUE WITH PROPER SIGN
BIGFLT LI R0,->7F63 HIGH WORD OF LARGEST VALUE
MOVB @SIGN,R2 IS FAC -VE
JLT BIGF01 YES, PUT HIGH WORD IN FAC
NEG R0
BIGF01 LI R2,FAC GET PRT TO FAC
MOV R0,*R2+ PUT APPROPRIATE HIGH WORD IN FAC
LI R0,>6363 GET 99'S
MOV R0,*R2+ PUT IN FAC TO GIVE LARGEST POS
MOV R0,*R2+ OR MOST NEG NUMBER
MOV R0,*R2
MOVB R9,@FAC+10 PLACE ERROR CODE IN RAM
JMP STEX NO ROUTINE SPECIFIED, RETURN
*
* FLOATING DIVISION FAC = ARG / FAC
*
* = BR TABLE
FDIV MOV R11,R10
JMP FDIV1
SDIV MOV R11,R10 SVE RTN
BL @POPSTK STACK DIVISION
FDIV1 LI R3,FAC PTR TO FAC
MOV *R3,R8 GET DIVISOR 1ST WORD
LI R0,ARG PTR TO ARG
XOR *R0,R8 NO, COMPUTE SIGN OF QUOTIENT
MOVB R8,@SIGN SAVE SAME
ABS *R3 ABS OF DIVISOR
D010 JEQ DIVZER CAN'T BE ZERO
ABS *R0 IS DIVIDEND ZERO?
JEQ FMULZR YES, RESULT IS ZERO
MOVB *R0,R9 GET DIVIDENT EXP
SB *R3,R9 SUB EXP'S TO GET QUOTIENT EXP
SRA R9,8 GET DIFF IN LOW BYTE
AI R9,64 ADD BIAS TO EXPONENT
MOV R9,@EXP AND SAVE FOR RESULT
LI R4,4
LI R5,ARG+8
FDV01 MOV *R3+,@10-2(R3)
CLR *R5+
DEC R4
JGT FDV01 LOOP TILL 4 BYTE MOVED
MOVB R4,@ARG CLEAR EXTRA HIGH BYTE OF DIVIDEND
*
* REFS FOR DIVISION ALGORITHM:
* DONALD E. KNUTH, THE ART OF COMPUTER PROGRAMMING, VOLUME 2
* SEMINUMERICAL ALGORITHMS, ADDISON-WESLEY, 1969, P 235 FF
*
* THE DIVIDEND IS THE SERIES OF RADIX DIGITS:
* U0,U1,U2 .... U7 (IN ARG)
* THE DIVISOR IS THE SERIES OF RADIX DIGITS:
* V1,V2,V3 .... V7 (IN FAC+8 OR FDVSR)
* (U0 IS THE EXTRA HIGH BYTE OF THE DIVIDEND)
*
* NORMALIZE DIVISOR AND DIVIDEND SO V1 GT 50
* IF V1 LT 50, MULTIPLY DIVISOR AND DIVIDEND BY
* INT(100/(V1+1))
*
* R0-R1 MPY, DIV WORK REGS
* R2 CARRY
* R3 MULTIPLIER
* R4 LOOP COUNT
* R5 PTR TO RB (R0)
* R6 PRT TO RB(R1)
* R77 100
*
LI R5,R0LSB GET POINTERS INTO MULTIPLY
LI R6,R1LSB WORK AREA
LI R7,100 RADIX
HX0064 EQU $-2
D045 EQU $-1
CLR R2 CLEARR HIGH BYTE OF WHERE V1 WILL BE
MOVB @FDVSR+1,@R2LSB GET V1 IN RB(R2)
CI R2,49 IS V1 ALREADY NORMALIZED?
JGT FDIV06 YES, PROCEED WITH DIVISION
INC R2 NO, COMPUTE V1+1
CLR R3 GET RADIX IN 2 REGS FOR DIV
MOV R7,R4 GET RADIX
DIV R2,R3 COMPUTE MULTIPLIER =INT(100/V1+1))
LI R9,FDVSR+8
FDVLP LI R4,8 GET NO. OF BYTES IN DIVIDEND+1
FDIV04 DEC R4 IGNORE ZERO BYTES AT END
DEC R9
MOVB *R9,R0 IS NEXT HIGHER ORDER BYTE ZERO?
JEQ FDIV04 YES, KEEP LOOKING FOR NON-ZERO
CLR R0 NO, LEAR CARRY INTO LOW ORDER BYTE
FDIV05 MOV R0,R2 SAVE CARRY FROM LAST BYTE
MOVB *R9,*R5 GET NEXT BYTE OF DIVIDEND
MPY R3,R0 MULTIPLY THIS BYTE BY MULTIPLIER
A R2,R1 ADD IN CARRY FROM PREVIOUS BYTE
DIV R7,R0 CNVRT TO A RADIX DIGIT AND A CARRY
MOVB *R6,*R9 PUT RESULT BYTE IN DIVIDEND
DEC R9
DEC R4 LOOP UNTIL ALL DIVIDEND BYTES
JGT FDIV05 NO, CONTINUE MULTIPLYING
CI R9,FDVSR
JNE FDVLPA
LI R9,ARG+8
JMP FDVLP
FDVLPA MOVB *R5,@ARG YES, PUT CARRY OUT OF HIGH ORDER
* IN HIGHEST BYTE
*
* DIVIDE LOOP:
* U(J) IS THE HIGHEST ORDER BYTE OF WHAT IS LEFT OF THE DIVIDEND
* EACH QUOTIENT DIGIT IS ESTIMATED AS FOLLOWS:
* IF U(J) = V1 THEN Q := 99
* ELSE Q:= INT((100*U(J)+U(J+1))/V1)
* IF V2*Q GT (100*U(J)+U(J+1)-Q*V1)*100+U(J+2)
* THEN Q := Q-1 ADN THE TEST IS REPEATED.
* THIS WILL ENSURE THAT Q-1 LE NEXT-QUOTIENT-DIGIT LE Q.
* NOTE THAT 100*U(J)+U(J+1)-Q*V1 =
* REMAINDER ((100*U(J)+U(J+1))/V1
* Q*V IS THEN SUBTRACTED FROM U
* IF THE RESULT IS -VE, V IS ADDED BACK IN AND A:= Q-1 (THE PROB
* -ABILITY OF ADDING BACK IS APPROX .03)
*
* R0-R1 TEMPORARY
* R2 NEXT QUOTIENT DIGIT
* R3-R4 TEMPORARY
* R5 QUOTIENT BYTE LOOP COUNT
* R6 NUMBER OF SIGNIFICANT BYTES IN DIVISOR
* R7 V1
* R8 V2
* R9 100*V1+V2
* R11 POINTER INTO DIVIDEND (USUALLY POINTS TO U(J)
*
FDIV06 LI R6,8 NUMBER OF DIVISOR BYTES +1
FDIV07 DEC R6 COMPUTE NO. OF SIG BYTES IN
* DIVISOR
MOVB @FDVSR(R6),R0 GET NEXT HIGHER ORDER BYTE
JEQ FDIV07 IGNORE IF ZERO
CLR R7 CLR HIGH BYTE OF WHERE V1 WILL BE
MOVB @FDVSR+1,@R7LSB RB(R7) IS V1
MOV R7,R8 COPY V1 TO COMPUTE 100*V1
MPY @HX0064,R8 COMPUTE 100*V1
MOVB @FDVSR+2,@R8LSB GET V2 (HIGH BYTE IS ZERO)
A R8,R9 COMPUTE 100*V1+V2
LI R5,-9 COMPUTE 9 BYTES OF QUOTIENT
LI R11,ARG PTR TO HIGH BYTE OF DIVIDEND
FDIV08 CLR R2 CLEAR HIGH BYTE OF WHERE U(J) WILL BE
MOVB *R11,@R2LSB RB(R2) IS U(J)
MPY @HX0064,R2 COMPUTE 100*U(J)
CLR R0 WHERE U(J+1) WILL BE
MOVB @1(R11),@R0LSB GET U(J+1)
A R0,R3 100*U(J)+U(J+1)
DIV R7,R2 GET Q AND REMAINDER
MPY @HX0064,R3 100* REMAINDER
MOVB @2(R11),@R0LSB U(J+2)
A R0,R4 100*REM + U(J+2)
MOV R2,R0 GET Q FOR THE TEST
MPY R8,R0 COMPUTE V2*Q
C R2,@HX0064 DOES Q=100?
JEQ FDIV09 YES, MAKE Q=99
S R4,R1 NO, COMPUTE V2*Q-(100*REM+U(J+2)
JMP FDIV11 GO CHECK IF IT IS IN RANGE
FDIV09 S R4,R1 COMPUTE V2*Q-(100*REM+U(J+2))
FDIV10 DEC R2 DECREMENT Q
S R9,R1 COMPUTE ABOVE FOR NEW Q
FDIV11 JGT FDIV10 IF Q TOO BIG, MAKE IT SMALLER
MOV R2,R2 IS Q ZERO?
JEQ FDIV16 YES, DO NOTHING
* NO, SUBTRACT Q*V FROM U
*
* R0-R1 TEMPORARY
* R2 NEXT QUOTIENT DIGIT
* R3 CARRY
* R4 LOOP COUNT
* R5 QUOTIENT BYTE LOOP COUNT
* R6 NUMBER OF SIGNIFICANT BYTES IN DIVISOR
* R7 V1
* R8 V2
* R9 100*V1+V2
* R11 POINTER INTO DIVIDEND (USUALLY POINTS TO U(J)
*
CLR R3 CLEAR CARRY INTO 1ST BYTE
MOV R6,R4 GET DIVISOR LOOP COUNT
A R6,R11 TO LOW BYTE OF DIVID. OF INTEREST
FDIV12 MOV R0,R3 SAVE CARRY FROM PREV. BYTE
MOVB @FDVSR(R4),@R0LSB GET NXT BYTE DIVISOR
MPY R2,R0 MPY BYTE OF DIVSR BY QUOTIENT
A R3,R1 ADD IN CARRY FROM LAST DVSR BYTE
DIV @HX0064,R0 CONVERT TO A RADIX 100 DIGIT
SB @R1LSB,*R11 SUB. PRODUCT BYTE FROM DIVIDEND
JGT FDIV13 IS RESULT +VE?
JEQ FDIV13 OR ZERO ?
AB @HX0064+1,*R11 NO, ADD RADIX BACK
INC R0 INC PRODUCT CARRY TO BORROW FROM
* NEXT BYTE
FDIV13 DEC R11 POINT TO NEXT HIGHER BYTE OF DVDND
DEC R4 SUB'D ALL BYTES OF DIVISOR?
JGT FDIV12 NO, CONTINUE SUBTRACTING
SB @R0LSB,*R11 YES, SUB CARRY FROM DIVISOR PRODUCT
JGT FDIV16 HIGH ORDER FROM HIGHEST ORDER
JEQ FDIV16 DIVIDEND BYTE. -VE RESULT?
* YES, ADD DIVIDEND BACK IN, Q WAS
* ONE TOO BIG
DEC R2 DEC Q, WAS ONE TOO BIG
MOV R6,R4 GET ADD-BACK LOOP COUNT
A R6,R11 PNT TO LOW ORDER BYTE OF DVDND
* OF INTEREST
FDIV14 AB @FDVSR(R4),*R11 ADD BYTE OF DVSR TO DVDND
CB *R11,@HX0064+1 RESULT LARGER THAN RADIX?
JL FDIV15 NO, RESULT IS CORRECT
SB @HX0064+1,*R11 YES, SUBTRACT RADIX
AB @HX01,@-1(R11) ADD 1 FOR CARRY TO HIGHER BYTE
FDIV15 DEC R11 TO NEXT HIGHER BYTE OF DIVIDEND
DEC R4 DONE ADDING IN ALL BYTES OF DVDND?
JGT FDIV14 NO, ADD IN THE NEXT ONE
FDIV16 MOVB @R2LSB,@FDVSR(R5) PUT AWAY NEXT QUOT BYTE
INC R11 HIGH ORDER OF NEXT SIGNIF DVDND
INC R5 COMPUTED ALL NECESS. BYTES OF QUO?
JLT FDIV08 NO, CONTINUE
B @FMEND YES, NORMALIZE AND FINISH UP

 

 

 

...lee

Link to comment
Share on other sites

Which implies that it's fairly equal then, considering the more efficient instruction set in the TMS 9900.

 

The MHz may be about the same. The instruction set may seem a bit like "next generation", especially with 16 bits, and these nice multiply and divide instructions. The TI-99/4A performance compared with the ZX Spectrum is however rather disappointing. Tursi calculated the MIPS at 0.15 here. mizapf counted instructions here, and we see that we actually end up moving truckloads of bytes in a shoehorned 16 bit environment. "Graphics and games" (usually then and now) has to do with 256 bytes of pure 16 bit RAM for any higher speed. The ZX Spectrum has internal registers and direct access to video RAM *), whereas the 9900 performs 16 bit operations through an 8 bit video bottleneck (and fewer CPU slots when display is drawn).

 

*)

48K ZX Spectrum
If you run a program in the lower 16K of RAM, or read or write in that memory, the processor is halted sometimes, as the ULA needs to access the video memory to keep the TV updated; the electron beam can't be interrupted, so the ULA is given a higher priority to access the contended memory. This part of memory is therefore somewhat slower than the upper 32K block. This is also the reason that you cannot write a sound- or save-routine in lower memory; the timing won't be exact, and the music will sound harsh. Also ... Read more here.
:)
Link to comment
Share on other sites

It seems all who did the MIPS math are aware of that first you get a figure for average instructions, but second you have to look at examples that do something useful, as the actual number of instructions executed can be quite different, depending on the CPU architecture.

It's also obvious from the code segment Lee showed above that there are quite a lot of DIV and MPY in the floating point multiply and divide instructions. In a computer like the TI 99/4A, you sometimes can't optimize for speed only, but also have to optimize memory usage.

And, as everybody says, the environment the TMS 9900 is stuffed into in the TI 99/4A isn't the most efficient... I can measure a speed increase of about 110%, if I compare code running with both workspace and code in normal, 8-bit wide RAM expansion, compared to when it runs entirely in my own RAM expansion design, which has 16-bit wide, zero wait state memory. Now most code is designed to have at least the workspace in RAM at >8300, which means the speed up isn't that dramatic, but sometimes you want to use memory elsewhere, and then it's really important.

Link to comment
Share on other sites

There are (at least) two different kinds of MIPS.
MIPS which translates to how fast does the CPU spin it's wheels cycles instructions, and Dhryston MIPS which is a benchmark.
Dhryston MIPS is a pretty decent comparison of processor speed... in a single category.
It's also more of a benchmark of how good a compiler is (which isn't necessarily fair on 8 bit computers),
or how much someone fine tunes a benchmark (which doesn't accurately measure typical performance)

While it is integer only, if you implement it in BASIC, it's still dependent on the floating point math library on most BASICs.
No string handling, no graphics manipulation...

I'd like to see several benchmarks run on machines rather than just one or two.

Link to comment
Share on other sites

 

Well it's certainly not the processor itself that's giving the slow results. Running the test under Cortex BASIC on a simple board with a 3 MHz 9900 running with no wait states, I get a run time of around 01:00:00, accuracy 0.0000057220458984, but the randomness various from around 16 down to as little as 6 when repeating the benchmark. Trying it on a 4 MHz 99105 gives a run time of around 00:15:00. ;-)

  • Like 2
Link to comment
Share on other sites

When you compare different models, price points must be taken into consideration as already mentioned. The TI-99/4A is an exceptional case as it started as somewhat overpriced, and due to price wars and TI exiting the market, quickly dropped in price to a point where it was very affordable, cheap even if you can overlook some of its limitations. The ZX Spectrum on the other hand entered the market at a competitive price, gradually became cheaper but never really was discounted to insanity. Rather there would arrive new, slightly (in the right sense of the word) improved versions to keep the price.

 

The BBC Micro was relatively expensive, perhaps not that much overpriced but with hardware capacities and expansion options very few regular home users would have need of. As it was designed to be used in schools who obviously had loads of cash to spend (or government grants?), it didn't need to compete on price. Those who could afford the Beeb probably bought it because it would be compatible with what they used in school, rather than it would be superior for home use/gaming. Acorn tried to launch a cut-down model, the Electron which though was somewhat overpriced given its specs and compared to the existing market.

 

So yes, you've got a 1981 TI-99/4A that was on constant sale through 1983-84, a 1982 ZX Spectrum that positioned itself at the upper half of the lower end of the market and a 1982 BBC Micro that already sold enough to schools not to have to worry about the home market. While it is perfectly OK to 35 years later pose a question how these compared, you should know back then they only to a limited part were direct competitors.

  • Like 1
Link to comment
Share on other sites

Can someone explain why the 800 was was 3x slower than the C64?

They didn't use Microsoft BASIC, and the math library was slow.

Someone's been working on an optimized version called BASIC+ which is much faster.

When used with a fast math library it beats the C64 by quite a bit.

 

Link to comment
Share on other sites

 

Well it's certainly not the processor itself that's giving the slow results. Running the test under Cortex BASIC on a simple board with a 3 MHz 9900 running with no wait states, I get a run time of around 01:00:00, accuracy 0.0000057220458984, but the randomness various from around 16 down to as little as 6 when repeating the benchmark. Trying it on a 4 MHz 99105 gives a run time of around 00:15:00. ;-)

The math library appears to be part of the speed difference there, but the 9900 was clearly capable of doing better.

The Random check seems a bit pointless since it changes every time you run it on a system unless it's not random.

Link to comment
Share on other sites

An interesting thing about the Radix-100 floating point system, specific to the TI, was that you could represent precise values where others could not, using their IEEE-754 format. This contributed to the perceived precision of the TI, but also to the bad performance.

 

For example, using the industry standard IEEE-754, you cannot represent the value 0.1 precisely. After conversion, the number has repeating decimals; the best approximation is 0x3dcccccd. In Radix-100, though, 0.1 = 10 * 100^-1. Accordingly, the floating point arithmetic achieves to produce a 1 when adding 0.1 ten times.

  • Like 3
Link to comment
Share on other sites

If the question is still whether the TI-99/4A is powerful enough to run an isometric game I would rather see a working demo than a theoretical discussion about MIPS :).

The Space 1999 game on the Oric took a long time to write. Most of the time was spent on the isometric engine, and graphics.

The isometric engine totals somewhere around 10,000 lines of code, and that's just the low level stuff for the game engine and drawing the screen..

The 9900 can probably do the same thing in about 7000 lines of code, but it's no easy task, and you still need the graphics and related data.

That's a lot of work just to prove it can be done.

Link to comment
Share on other sites

The ZX Spectrum has direct access to video memory, which makes isometric games (e.g. Knight Lore) and vector graphics games (e.g. Elite) possible.

Nice theory.

 

The MSX has no direct access to video memory, yet isometric games (e.g. Knight Lore) and vector graphics games (e.g. Elite) were possible.

 

:)

 

Link to comment
Share on other sites

The Space 1999 game on the Oric took a long time to write. Most of the time was spent on the isometric engine, and graphics.

The isometric engine totals somewhere around 10,000 lines of code, and that's just the low level stuff for the game engine and drawing the screen..

The 9900 can probably do the same thing in about 7000 lines of code, but it's no easy task, and you still need the graphics and related data.

That's a lot of work just to prove it can be done.

 

I did make this video at one point, it took about 1200 lines of code, but I was using hardware sprites which turned out to be too slow for anything more advanced.

 

 

http://atariage.com/forums/topic/237374-soft-sprites-on-9918amsx1/?do=findComment&comment=3221451

 

My point is: you need to build the screen in RAM with soft sprites and copy it to the VDP each frame. The MSX can do that about twice as fast as the TI. [Edit: and so can the Speccy because it has direct access to VDP RAM.]

  • Like 4
Link to comment
Share on other sites

So far the discussion has been about raw horsepower. That is a very legit, and common way to compare machines. But on a personal level and how you actually used each machine determined it's actual gut-level value to the owner/operator.

 

If there were two of me, each in a parallel universe, I think the TI would have won in the overall battle.

 

Both are fantastic to ease into computing and discover the value of computers in general. They both taught Basic programming and Assembly, but the TI's buy-in was painful. They both played games, however the ZX had a much larger library of titles to choose from because so many people had them early on, learned to code, and created content. On the other hand the TI did all of those things as well (at a higher price point) and was useful in business. The ability to print was a HUGE plus. At least to me.

 

This discussion is all more than academic to me now. I'm in the 'ZX Spectrum Next' Kickstarter (It was fully funded May 22) and I'll be getting a couple of these Next machines.

I almost bought a 'TImex Sinclair 1000' back in the day, but I had already bought my TI and decided to stick with it. I'd never even heard of a ZX until recently. I'm very glad that I did. Our machine was a great introduction to computing and I eventually used mine to run my small business for years, until I could afford my first PC. If the TI had been 80 columns-wide from day one, I would have stuck with it a lot longer. I was very comfortable with it. Lotus 123 finally lured me to the PC dark side.

 

When the TI was at it's cheapest I bought 5 of them, and gave them as Christmas presents to my family, Mom, Dad, and Siblings. My father learned Basic and his fear of computers vanished. He soon after got a PC and started day trading with Stocks using it to chart. Everyone in my family were early adopters of technology thereafter, and had careers steeped in computing (accounting, advertising, appraisal work, etc.).

 

It looks to me that each machine has it's advantages and faults. The TI was the first 16-bit machine available to us common folk but not cheap, until the end. But the ZX (TS1K) was the first actually affordable machine. From my perspective the TI was an easy on-ramp to computing and Basic program learning, even though it was slow. The ZX was the easiest to start Assembly and did not cost an arm and a leg.

 

After that, the number of hours you poured into each defined it's actual overall benefits to you personally.

 

Thanks for this discussion. I'll also be living in the ZX world, starting in January.

  • Like 2
Link to comment
Share on other sites

Ok this program is bogus from Creative computing as all I get in Classic99 from RXB is:

WARNING NUMERIC OVERFLOW IN 70

and

WARNING NUMERIC OVERFLOW IN 90

and it does take over 10 minutes listening to the crash sound and post was punishment.

1 OPEN #1:"CLOCK"
2 INPUT #1:A$,B$,C$
3 PRINT A$:B$:C$$
10 ! Ahl's Simple Benchmark
20 FOR N=1 TO 100 :: A=N
30 FOR I=1 TO 10
40 X=SQR(A) :: R=R+RND
50 NEXT I
60 FOR I=1 TO 10
70 A=A^2 :: R=R+RND
80 NEXT I
90 S=S+A :: NEXT N
100 PRINT ABS(1010-S/5)
110 PRINT ABS(1000-R)
120 INPUT #1:A$,B$,C$
130 PRINT A$:B$:C$

I have no idea how they made this program work without these error popping up unless they used ON WARNING NEXT

at first I thought in RXB this would be total disaster adding lines but here is result:

1 OPEN #1:"CLOCK"
2 INPUT #1:A$,B$,C$
3 PRINT A$:B$:C$$
10 ! Ahl's Simple Benchmark
20 FOR N=1 TO 100 :: A=N
30 FOR I=1 TO 10
40 X=SQR(A) :: R=R+RND
50 NEXT I
60 FOR I=1 TO 10
65 ON WARNING NEXT
70 A=A^2 :: R=R+RND
80 NEXT I
85 ON WARNING NEXT
90 S=S+A :: NEXT N
100 PRINT ABS(1010-S/5)
110 PRINT ABS(1000-R)
120 INPUT #1:A$,B$,C$
130 PRINT A$:B$:C$

RXB result: 2 minutes 9 seconds with 2.E+** and 4.571029043

 

XB result: 4 minutes 4 seconds with 2.E+** and 6.27999115

 

Now TI Basic does not have ON WARNING NEXT so I turn off the sound and ran this version for TI Basic:

1 OPEN #1:"CLOCK"
2 INPUT #1:A$,B$,C$
3 PRINT A$:B$:C$$
10 REM  Ahl's Simple Benchmark    
20 FOR N=1 TO 100
21 A=N
30 FOR I=1 TO 10
40 X=SQR(A)
45 R=R+RND
50 NEXT I
60 FOR I=1 TO 10
70 A=A^2
75 R=R+RND
80 NEXT I
90 S=S+A
95 NEXT N
100 PRINT ABS(1010-S/5)
110 PRINT ABS(1000-R)
120 INPUT #1:A$,B$,C$
130 PRINT A$:B$:C$

TI Basic results: 5 minutes 26 seconds with 2.E+** and 1.928494715

 

Now why they all end with different results is baffling at best!

Link to comment
Share on other sites

Ok this program is bogus from Creative computing as all I get in Classic99 from RXB is:

WARNING NUMERIC OVERFLOW IN 70

and

WARNING NUMERIC OVERFLOW IN 90

and it does take over 10 minutes listening to the crash sound and post was punishment.

1 OPEN #1:"CLOCK"
2 INPUT #1:A$,B$,C$
3 PRINT A$:B$:C$$
10 ! Ahl's Simple Benchmark
20 FOR N=1 TO 100 :: A=N
30 FOR I=1 TO 10
40 X=SQR(A) :: R=R+RND
50 NEXT I
60 FOR I=1 TO 10
70 A=A^2 :: R=R+RND
80 NEXT I
90 S=S+A :: NEXT N
100 PRINT ABS(1010-S/5)
110 PRINT ABS(1000-R)
120 INPUT #1:A$,B$,C$
130 PRINT A$:B$:C$

I have no idea how they made this program work without these error popping up unless they used ON WARNING NEXT

at first I thought in RXB this would be total disaster adding lines but here is result:

1 OPEN #1:"CLOCK"
2 INPUT #1:A$,B$,C$
3 PRINT A$:B$:C$$
10 ! Ahl's Simple Benchmark
20 FOR N=1 TO 100 :: A=N
30 FOR I=1 TO 10
40 X=SQR(A) :: R=R+RND
50 NEXT I
60 FOR I=1 TO 10
65 ON WARNING NEXT
70 A=A^2 :: R=R+RND
80 NEXT I
85 ON WARNING NEXT
90 S=S+A :: NEXT N
100 PRINT ABS(1010-S/5)
110 PRINT ABS(1000-R)
120 INPUT #1:A$,B$,C$
130 PRINT A$:B$:C$

RXB result: 2 minutes 9 seconds with 2.E+** and 4.571029043

 

XB result: 4 minutes 4 seconds with 2.E+** and 6.27999115

 

Now TI Basic does not have ON WARNING NEXT so I turn off the sound and ran this version for TI Basic:

1 OPEN #1:"CLOCK"
2 INPUT #1:A$,B$,C$
3 PRINT A$:B$:C$$
10 REM  Ahl's Simple Benchmark    
20 FOR N=1 TO 100
21 A=N
30 FOR I=1 TO 10
40 X=SQR(A)
45 R=R+RND
50 NEXT I
60 FOR I=1 TO 10
70 A=A^2
75 R=R+RND
80 NEXT I
90 S=S+A
95 NEXT N
100 PRINT ABS(1010-S/5)
110 PRINT ABS(1000-R)
120 INPUT #1:A$,B$,C$
130 PRINT A$:B$:C$

TI Basic results: 5 minutes 26 seconds with 2.E+** and 1.928494715

 

Now why they all end with different results is baffling at best!

 

In the line 40s you've got X=SQR(A). It should be A=SQR(A). That might be the cause of the error you're seeing.

  • Like 3
Link to comment
Share on other sites

Just remember the Spectrum may not have even been on the market a full yer of the TI's life before the TI was cancelled.
Sinclair's main competitor to the TI was the ZX-80 series.

The ZX-80 came with 1K of RAM, 4K of ROM, and only 384 bytes of RAM were usable if you used the full screen.
That's barely bigger than the keyboard buffer on a TRS-80.
You could learn simple BASIC syntax but that's about it without a RAM expansion.

Sure the ZX-80 was only 100 pounds, but the VIC20, CoCo, and Acorn Atom were also on the market,

and you got a lot more machine for the extra money.
The Atom was 170 pounds assembled, and it came with twice the RAM, twice the ROM, a real keyboard,

color, sound, and an actual power switch. Expansion was also internal.
By the time you upgrade the RAM on the ZX, it had to be close to the price of the Atom.

 

The TS-1000 came with 2K, but that's still less than most of the competition and only around 1400 bytes for code.
That's what? 100 lines of BASIC... maybe less depending on variables.

You really need around 4K of RAM before a machine becomes usable for much, and with 16K you can have some pretty

elaborate programs.

I think the first model of that series that is really usable out of the box is the TS-1500 with 16K.

 

The Spectrum is a very different beast than the ZX-80 series capability wise.

Edited by JamesD
Link to comment
Share on other sites

...

Sure the ZX-80 was only 100 pounds, but the VIC20, CoCo, and Acorn Atom were also on the market,

and you got a lot more machine for the extra money.

The Atom was 170 pounds assembled, and it came with twice the RAM, twice the ROM, a real keyboard,

color, sound, and an actual power switch. Expansion was also internal.

By the time you upgrade the RAM on the ZX, it had to be close to the price of the Atom.

...

Correction, the color board for the Atom was extra... but at least it was an option.

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...