RXB Posted February 18, 2017 Share Posted February 18, 2017 (edited) Here is a quote from from the TI Extended Basic GPL Source code talking about Assembly sections: [0703] * MVUP WAS USED TO TRANSFER DATA FROM CPU RAM TO ERAM [0704] * SINCE IT WAS NOT KNOWN AT FIRST THAT THE MOVE [0705] * INSTRUCTION COULD TRANSFER FROM CPU RAM TO ERAM The reason I think XB ROMs are a mess is duplication of purpose that just wasted space. The GPL MOVE command can move any type of Memory to any type of memory in the TI, but TI has routines in XB ROMs that make no sense. GVWITE = move GRAM to VDP VGWITE = move VDP to GRAM (note that no GRAM exists in the XB CART?) MVUP = move VDP RAM to RAM MVDN = move RAM to VDP RAM GREAD = move RAM to RAM GREAD1 = move VDP to VDP Example in GPL to move VDP to RAM MOVE #BYTES,V@SOURCE,@RAMADDRESS * (and this command takes 7 bytes memory) Example in GPL to call XB ROM routine GREAD DST RAMADDRESS,@DDD1 * 4 bytes memory DST SOURCE, @FFF1 * 4 bytes memory DST #BYTES, @EEE1 * 4 bytes memory XML GREAD * 2 bytes memory So GREAD takes 14 bytes to do what MOVE does in 7 bytes and is no faster at all. Actually it is slower as GPL has to do much more set up just to call GREAD to use it. I would estimate 1/4 of the ROM is XB are just wasted duplicated commands totally useless and slower. Also note for years I have stated that the GPL people and Assembly people apparently never talked much between them. Competition maybe or bad management???? Unknown??? Whatever took place it was a hot mess of conflicts when completed. Edited February 18, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted February 18, 2017 Share Posted February 18, 2017 The comments at the top of your post are interesting! As far as speed goes, you are only seeing part of the story: MOVE #BYTES,V@SOURCE,@RAMADDRESS * (and this command takes 7 bytes memory) You see 7 bytes of code. I see the 2 pages of assembly code that the GPL interpreter needs to do the MOVE instruction. (Pages 23 and 24 of INTERN) If you really want to know which of your examples above is faster you can make equivalent programs to test both ways. Try moving blocks of ram within VDP using GPL MOVE and XML GREAD1. Try 10 bytes, 100 bytes and 1000 bytes. You would have to loop a bunch of times so a human with a stop watch can time it. If I were a gambling man I would bet on XML, but who knows - the TI has been surprising me since 1983! Plus the GPL interpreter runs on the 16 bit bus. Quote Link to comment Share on other sites More sharing options...
RXB Posted February 19, 2017 Share Posted February 19, 2017 The comments at the top of your post are interesting! As far as speed goes, you are only seeing part of the story: MOVE #BYTES,V@SOURCE,@RAMADDRESS * (and this command takes 7 bytes memory) You see 7 bytes of code. I see the 2 pages of assembly code that the GPL interpreter needs to do the MOVE instruction. (Pages 23 and 24 of INTERN) If you really want to know which of your examples above is faster you can make equivalent programs to test both ways. Try moving blocks of ram within VDP using GPL MOVE and XML GREAD1. Try 10 bytes, 100 bytes and 1000 bytes. You would have to loop a bunch of times so a human with a stop watch can time it. If I were a gambling man I would bet on XML, but who knows - the TI has been surprising me since 1983! Plus the GPL interpreter runs on the 16 bit bus. Well first test: *********************************************************** * GTEST FOR GPL MOVE AND RTEST FOR ROM GVWITE * RAM TO RAM TESTS GTEST DATA RTEST STRI 'GTEST' DATA $+2 DST 1024,@FAC * COUNTER VALUE GTEST1 MOVE 768,@0,@>C000 * GPL MOVE 768 BYTES,0 TO C000 DDEC @FAC * COUNTER-1 BR GTEST1 * ZERO? B LDRET2 * BACK TO XB RTEST DATA >0000 STRI 'RTEST' DATA $+2 DST 1024,@FAC * COUNTER VALUE RTEST1 DST 768,@FFF1 * BYTE COUNT DST >0000,@DDD1 * SOURCE ADDRESS DST >C000,@EEE1 * DESTINATION XML GVWITE * ROM MOVE 768 BYTES, 0 TO C000 DDEC @FAC * COUNTER-1 BR RTEST1 * ZERO? B LDRET2 * BACK TO XB *************************************************************** GPL MOVE 23 or 24 seconds ROM GVWITE 23 or 24 seconds You Notice I had to load the values each time in both, but 3 more GPL commands of DST are needed to load the Count, Source and Destination for ROM. This also costs more space and kind of destroys the advantage of XML ROM routines for each call as more GPL is needed just to call and use them. Second test changed the count to 9999 for both and could not see a difference after close to 4 minutes. They were almost exactly the same, maybe GPL MOVE was a second faster by a second after 4 minutes but would have to do it an hour to see any real change. Next test was MVDN: *********************************************************** * GTEST FOR GPL MOVE AND RTEST FOR ROM GVWITE * RAM TO RAM TESTS GTEST DATA RTEST STRI 'GTEST' DATA $+2 DST >FFFF,@FAC * COUNTER VALUE GTEST1 MOVE 768,V@>820,V@0 * GPL MOVE 768 BYTES,V>0820 TO V>0 DDEC @FAC * COUNTER-1 BR GTEST1 * ZERO? B LDRET2 * BACK TO XB RTEST DATA >0000 STRI 'RTEST' DATA $+2 DST >FFFF,@FAC * COUNTER VALUE RTEST1 DST 768,@ARG * BYTE COUNT DST >0820,@VARB * SOURCE ADDRESS DST >0000,@VAR0 * DESTINATION XML MVDN * ROM MOVE 768 BYTES,V>0820 TO v>0 DDEC @FAC * COUNTER-1 BR RTEST1 * ZERO? B LDRET2 * BACK TO XB *************************************************************** ROM XML MVDN 13.43 seconds hands down winner. GPL MOVE IS INSANELY SLOW in comparison more then 3 time slower for moving VDP to VDP. Definitely a good game plan to move all STRINGS and DATA STACK out of VDP and into SAMS RAM. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted February 19, 2017 Share Posted February 19, 2017 Very interesting! I do have a few questions though. In the first test: MOVE 768,@0,@>C000 * GPL MOVE 768 BYTES,0 TO C000 (both addresses in CPU RAM) then for the XML part XML GVWITE * ROM MOVE 768 BYTES, 0 TO C000 but in post #601 you say "GVWITE = move GRAM to VDP" Shouldn't that be "GREAD = move RAM to RAM" in order to do the equivalent operation? Likewise in the second test: MOVE 768,V@>820,V@0 * GPL MOVE 768 BYTES,V>0820 TO V>0 (both addresses in VDP RAM) then for the XML part XML MVDN * ROM MOVE 768 BYTES,V>0820 TO v>0 but in post #601 you say "MVDN = move RAM to VDP RAM" Shouldn't that be "GREAD1 = move VDP to VDP" in order to do the equivalent operation? This code had me scratching my head: RTEST1 DST 768,@FFF1 * BYTE COUNT DST >0000,@DDD1 * SOURCE ADDRESS DST >C000,@EEE1 * DESTINATION until I realized that FFF1, DDD1, and EEE1 were labels and not hexadecimal addresses. Quote Link to comment Share on other sites More sharing options...
RXB Posted February 19, 2017 Share Posted February 19, 2017 (edited) Very interesting! I do have a few questions though. In the first test: MOVE 768,@0,@>C000 * GPL MOVE 768 BYTES,0 TO C000 (both addresses in CPU RAM) then for the XML part XML GVWITE * ROM MOVE 768 BYTES, 0 TO C000 but in post #601 you say "GVWITE = move GRAM to VDP" Shouldn't that be "GREAD = move RAM to RAM" in order to do the equivalent operation? Likewise in the second test: MOVE 768,V@>820,V@0 * GPL MOVE 768 BYTES,V>0820 TO V>0 (both addresses in VDP RAM) then for the XML part XML MVDN * ROM MOVE 768 BYTES,V>0820 TO v>0 but in post #601 you say "MVDN = move RAM to VDP RAM" Shouldn't that be "GREAD1 = move VDP to VDP" in order to do the equivalent operation? This code had me scratching my head: RTEST1 DST 768,@FFF1 * BYTE COUNT DST >0000,@DDD1 * SOURCE ADDRESS DST >C000,@EEE1 * DESTINATION until I realized that FFF1, DDD1, and EEE1 were labels and not hexadecimal addresses. There is a routine called GREAD and GREAD1 but they are not the same as GVWITE or VGWITE. The freaking names TI picked make zero sense at all. MVUP and MVDN are RAM to VDP and VDP to RAM, So a very asinine way to pick names with no reference to what kind of memory they handle. Yea I got the functions wrong when I posted them originally I was guessing in my notes at the time. There are variables DDD1 (FAC10), EEE1 (FAC6) and FFF1 (FAC12) but FFF (FAC4) and CCC (FAC4) and BBB (FAC6) and EEE (FAC6) also. Another really nutty system for naming variables. I wanted to keep the original TI code but you can see it is pretty insane. Edited February 19, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted February 20, 2017 Share Posted February 20, 2017 I've been looking at the XB rom code you posted in another thread and that plus your post #601 brings up another question: Just what the heck is ERAM? Quote Link to comment Share on other sites More sharing options...
RXB Posted February 20, 2017 Share Posted February 20, 2017 I've been looking at the XB rom code you posted in another thread and that plus your post #601 brings up another question: Just what the heck is ERAM? LOL good question! So far it appears to be RAM like in VDP, and almost make sense. You know Erasable RAM? But also it mean 32K RAM? EXAMPLE: [0896] * Add symbol and its address - stopped in field - to the [0897] * routine entry table. It is put at the end of the table [0898] * (the end of the table is towards the low end of memory) [0899] * Since the table is searched from the end first, if there [0900] * are any duplicate labels the last one entered will have [0901] * precedence over the early one(s). [0902] C16A 97,0A DDECT @FREEND Set to address field [0903] * Load address (stored in field in CPU RAM) into routine [0904] * Name table which is in expansion RAM [0905] C16C BF,16,83 DST FIELD,@VARB Source C16F 11 [0906] C170 BD,00,0A DST @FREEND,@VAR0 Destination [0907] C173 BF,5C,00 DST 2,@ARG # bytes to move C176 02 [0908] C177 0F,89 XML MVUP CPUR RAM to ERAM This is the GPL code I am using to try and figure out XB ROMs. You can see the headache it can create saying EXPANSION RAM means VDP. Quote Link to comment Share on other sites More sharing options...
RXB Posted February 20, 2017 Share Posted February 20, 2017 (edited) Ok I am really going to need some help here. And it benefits everyone to get this complete. This is what I have so far on the source code of the XB ROM's and any help would be appreciated. XBROM SOURCE.zip Edited February 20, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted February 20, 2017 Share Posted February 20, 2017 Here is a quote from from the TI Extended Basic GPL Source code talking about Assembly sections: [0703] * MVUP WAS USED TO TRANSFER DATA FROM CPU RAM TO ERAM [0704] * SINCE IT WAS NOT KNOWN AT FIRST THAT THE MOVE [0705] * INSTRUCTION COULD TRANSFER FROM CPU RAM TO ERAM So this is starting to make a little bit of sense. ERAM must stand for Expansion RAM as you suggested a couple of posts back. Because GPL was probably created before the 32K expansion was available there evidently was some question about whether MOVE could work with the 32K expansion. Quote Link to comment Share on other sites More sharing options...
RXB Posted February 20, 2017 Share Posted February 20, 2017 (edited) So this is starting to make a little bit of sense. ERAM must stand for Expansion RAM as you suggested a couple of posts back. Because GPL was probably created before the 32K expansion was available there evidently was some question about whether MOVE could work with the 32K expansion. Yea you are right but then we see them say RAM or ERAM? Maybe RAM is scratch pad and ERAM is 32K? [0734] *********************************************************** [0735] * FLAGS USED IN EXECUTION MODE: this needs to be checked [0736] * @FLAG BIT RESET SET [0737] * 0 [0738] * 1 Warning PRINT PRINT off 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0013 EQUATES EXEC-359 [0739] * 2 Warning NEXT STOP [0740] * 3 Not in UDF Executing a UDF [0741] * 4 TRACE mode Normal mode [0742] * 5 [0743] * 6 BREAK allowed BREAK not allowed [0744] * 7 No LST/EDT protect LIST/EDIT protected [0745] *********************************************************** [0746] * ON WARNING {NEXT | STOP | PRINT} [0747] * ON WARNING NEXT - Causes warning messages to be ignored [0748] * and execution to continue as if a [0749] * warning never occurred [0750] * ON WARNING STOP - Causes a warning to be treated as an [0751] * error - i.e. the message is displayed [0752] * and execution is halted [0753] * ON WARNING PRINT - Causes the default warning handling to [0754] * be in effect, i.e. any warning [0755] * messages are printed and execution [0756] * continues [0757] *********************************************************** [0758] A1AA 0F,79 ONWARN XML PGMCHR GET OPTION [0759] A1AC D6,42,9C CEQ PRINTZ,@CHAT If print [0760] A1AF 41,B7 BR GA1B7 [0761] A1B1 B2,45,F9 AND >F9,@FLAG Turn on print and contiue [0762] A1B4 05,A1,CF B ONWRN5 [0763] A1B7 D6,42,98 GA1B7 CEQ STOPZ,@CHAT [0764] A1BA 41,C4 BR GA1C4 [0765] A1BC B2,45,FD AND >FD,@FLAG Turn on print [0766] A1BF B6,45,04 OR >04,@FLAG Turn on stop [0767] A1C2 41,CF BR ONWRN5 [0768] A1C4 D6,42,96 GA1C4 CEQ NEXTZ,@CHAT * SYNTAX ERROR [0769] A1C7 4D,BA BR ERRSYN [0770] A1C9 B6,45,02 OR >02,@FLAG Turn off print [0771] A1CC B2,45,FB AND >FB,@FLAG Turn off stop [0772] A1CF 0F,79 ONWRN5 XML PGMCHR Check for EOS [0773] A1D1 06,6A,78 ONWRN7 CALL CHKEND Error if not EOS [0774] A1D4 4D,BA BR ERRSYN If not EOS [0775] A1D6 87,22 DCLR @ERRCOD [0776] A1D8 0F,75 XML CONT Continue [0777] *********************************************************** [0778] * ON ERROR {line number | STOP} [0779] * ON ERROR line number - causes the error routine to build [0780] * an error stack entry and pass [0781] * control to the line specified in [0782] * the most-recently executed [0783] * on-error-statement [0784] * ON ERROR STOP - causes the default error handling [0785] * conditions to be in effect. i.e. any [0786] * errors that occur cause execution to halt [0787] * an a message to be displayed [0788] *********************************************************** [0789] A1DA 0F,79 ONERR XML PGMCHR Get option [0790] A1DC D6,42,C9 CEQ LNZ,@CHAT If line # then find the line [0791] A1DF 42,0E BR GA20E [0792] A1E1 0F,79 XML PGMCHR Get upper byte [0793] A1E3 BC,4A,42 ST @CHAT,@FAC [0794] A1E6 0F,79 XML PGMCHR Get lower byte [0795] A1E8 BC,4B,42 ST @CHAT,@FAC1 [0796] A1EB BD,4C,32 DST @ENLN,@FAC2 [0797] A1EE A7,4C,00 DSUB 3,@FAC2 Pointing to 1st line # A1F1 03 [0798] * Consider both ERAM and RAM cases to get line # from the <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< [0799] * line number table. Also reset the break bit. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< [0800] A1F2 06,80,2E ONERR2 CALL GRSUB3 Get 2 bytes from either RAM/ERAM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< [0801] A1F5 4C BYTE FAC2 * FAC2 has the address 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0014 EQUATES EXEC-359 [0802] A1F6 D5,4A,58 DCEQ @EEE1,@FAC If found [0803] A1F9 62,06 BS ONERR4 [0804] A1FB C5,4C,30 DCH @STLN,@FAC2 Not found [0805] A1FE 4D,E6 BR ERRLNF [0806] A200 A7,4C,00 DSUB 4,@FAC2 Goto next line A203 04 [0807] A204 41,F2 BR ONERR2 [0808] A206 95,4C ONERR4 DINCT @FAC2 [0809] A208 BD,A3,8A DST @FAC2,V@ERRLN A20B 4C [0810] A20C 42,16 BR GA216 [0811] A20E D6,42,98 GA20E CEQ STOPZ,@CHAT * SYNTAX ERROR [0812] A211 4D,BA BR ERRSYN [0813] A213 87,A3,8A DCLR V@ERRLN Back to default error handlin [0814] A216 41,CF GA216 BR ONWRN5 Finish up same as ON WARNING [0815] *********************************************************** Edited February 20, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted February 20, 2017 Share Posted February 20, 2017 Based on all of the documentation I've read, ERAM is indeed, Expansion RAM. Quote Link to comment Share on other sites More sharing options...
RXB Posted March 4, 2017 Share Posted March 4, 2017 (edited) List of things found to fix in RXB 2015E 1. deleted from this post. 2. Add LALPHA like XB2 or Cortex Basic for ACCEPT AT(row,col) ALPHA:X$ to allow Lower Case characters only. 3. Add HEX to VAL(">FFFC") = -4 or VAL(">11") =33 the > indicates to interpeter that a HEX value is being used. 4. Upgrade routines EAPGM and EALR and repace with a single command CALL EA or CALL EA("DSK#.FILE") that figures out if you are loading a EA5 or EA3 program automatically. (CALL EA just switches to EA Cartridge, if it sees a ( then it knows a EA5 or EA3 follows and then looks at program to see if a EA5 or EA3 and decides where to go.) 5. Replace CALL XBPGM("DSK#.FILE") with CALL XB("DSK#.FILE"), also add CALL RUN("DSK#.FILE") (CALL XB just restarts XB, or looks for a ( and knows a XB program is to be loaded, also like the old XBPGM you can use CALL XB("DSK#.FILE",2) ! 2 is a CALL FILES(2) added) 6. Replace the old GKXB scrolls GKSCRL, GSSCL2, GKSCL1 with the ROM XML SCROLL which is faster and much more memory intensive. 7. CALL AMSINIT stops SIZE from working properly CALL ? Eliminate CALL AMSINIT entirely as not needed really. 8. CALL FCOPY is totally broken in RXB 2015E for some reason and needs to be repaired. Some how did not catch this. 9. A bank error results in CALL AMSBANK fix is DST @FAC6,@>2000 A. BASIC version of PRINT works differently then RXB or XB does. Example: PRINT from Basic results in a different response then RXB for a PRINT. Fix: CALL MOVES("VV',736,32,0) :: CALL HCHAR(24,1,31,2,24,3,32,28,24,31,31,2) ! This restores a duplicate of how Basic works Alternate Fix: Duplicate the Basic PRINT into RXB but would require a call to do this so not a good fix idea. B. CALL EAED("DSK#.FILE') no longer works need to be repaired, I removed the branch in EA for this so needs a fix. Edited March 5, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 4, 2017 Share Posted March 4, 2017 FWIW: Disagree with #1. Bad argument when asked for the ASCII value of nothing sounds correct to me. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 4, 2017 Share Posted March 4, 2017 FWIW: Disagree with #1. Bad argument when asked for the ASCII value of nothing sounds correct to me. I agree. If a user really wants an ASCII value that cannot be represented with a printable character, the CHR$ mechanism is available. The null string has no characters to which to assign an ASCII value. The string B$ in the example below has NUL as the first character, the value for which is 0: 100 B$ = CHR$(0) & "ABC" 110 A = ASC(B$) 120 PRINT A Line 120 will print “0”. ...lee Quote Link to comment Share on other sites More sharing options...
Casey Posted March 4, 2017 Share Posted March 4, 2017 I was curious about how ASC("") was handled in some other BASICs. We know TI BASIC produced BAD ARGUMENT for this. Commodore BASIC 2.0 (VIC/64), and 4.0 (PET) also flag this as an error (illegal quantity error). Interestingly, Commodore BASIC 3.5 (Plus/4) and 7.0 (128) return 0 for this. IBM ROM BASIC, and most of the various others I was able to try via emulation return error messages rather than 0. Atari BASIC curiously return 44... Quote Link to comment Share on other sites More sharing options...
RXB Posted March 4, 2017 Share Posted March 4, 2017 (edited) FWIW: Disagree with #1. Bad argument when asked for the ASCII value of nothing sounds correct to me. This started when I got several questions on why TI Basic and XB have this bug. Tell me what should the logically result of this line be: 10 PRINT LEN(ASC("")) Logically the answer should be 0 (zero), BAD ARGUMENT makes no sense as an empty string has 0 (zero) length. Here is another that created this issue. 10 X$="" 20 PRINT SEG$("TEST",LEN(ASC(X$)),2) This returns BAD ARGUMENT, but should return the error BAD VALUE as 0 is the bad value. Which makes more sense for an error? To back up my argument almost every other BASIC supports what I am saying: https://msdn.microsoft.com/en-us/library/zew1e4wc(v=vs.90).aspx http://www.readybasic.com/referencemanual/commands/ASC.html I have used as many as 50 different BASIC version and have manuals on many. Thus a empty string should logically have zero length, not be a BAD ARGUMENT. Also this makes debugging much more sensible for the User. Why should TI XB be the exception to the rule? Really why? Edited March 4, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 4, 2017 Share Posted March 4, 2017 It makes no sense to me to take the length of a number—that is for strings. ASC(X$) gives the value of the first character in X$. If X$ is not empty, LEN(ASC(X$)) should return the error, “STRING-NUMBER MISMATCH”, which it does. Of course, if X$ is the null string, it has no ASCII value and returns “BAD ARGUMENT” because ASC(X$) is evaluated first. Flagging an actual error is not a bug. BTW, your first reference (MSDN) supports my position. ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 4, 2017 Share Posted March 4, 2017 Tell me what should the logically result of this line be: 10 PRINT LEN(ASC("")) Logically the answer should be 0 (zero), BAD ARGUMENT makes no sense as an empty string has 0 (zero) length. It makes perfect sense. The error occurred before LEN executed. The error was raised by ASC which executes first. Quote Link to comment Share on other sites More sharing options...
RXB Posted March 4, 2017 Share Posted March 4, 2017 (edited) It makes no sense to me to take the length of a number—that is for strings. ASC(X$) gives the value of the first character in X$. If X$ is not empty, LEN(ASC(X$)) should return the error, “STRING-NUMBER MISMATCH”, which it does. Of course, if X$ is the null string, it has no ASCII value and returns “BAD ARGUMENT” because ASC(X$) is evaluated first. Flagging an actual error is not a bug. BTW, your first reference (MSDN) supports my position. ...lee Which version of MSDN verson of BASIC as some support it and some do not, by the way Cortex Basic supports it. And Argument Exception sets a flag you can use to generate a error or ignore the Exception. https://msdn.microsoft.com/en-us/library/system.argumentexception(v=vs.90).aspx By the way if I do it your way Lee nothing changes, but logically a empty string should be 0 not BAD ARGUMENT. I have a hard time dealing with EMPTY STRING = BAD ARGUMENT by that logic PRINT "" should return BAD ARGUMENT (Do you see how inconsistent this becomes?) Edited March 4, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 4, 2017 Share Posted March 4, 2017 I have a hard time dealing with EMPTY STRING = BAD ARGUMENT by that logic PRINT "" should return BAD ARGUMENT (Do you see how inconsistent this becomes?) That is not in the least Inconsistent. “EMPTY STRING” does not equal “BAD ARGUMENT”. Your saying it does not make it so. PRINT "" properly prints nothing because the string is empty. But, ASC() requires an actual character as its argument. The empty string contains no characters; therefore, the empty string is a bad argument for ASC(). ...lee 1 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted March 5, 2017 Share Posted March 5, 2017 This started when I got several questions on why TI Basic and XB have this bug. Tell me what should the logically result of this line be: 10 PRINT LEN(ASC("")) Logically the answer should be 0 (zero), BAD ARGUMENT makes no sense as an empty string has 0 (zero) length. Here is another that created this issue. Those links don't all support your theory. Returning 0 is silly, even if it is supported by other languages, especially when a string may contain character code 0. That is, A$=CHR$(0)::PRINT ASC(A$) will return 0. A negative value might have some worth versus tossing an error, but not a zero in my opinion. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted March 5, 2017 Share Posted March 5, 2017 That is not in the least Inconsistent. “EMPTY STRING” does not equal “BAD ARGUMENT”. Your saying it does not make it so. PRINT "" properly prints nothing because the string is empty. But, ASC() requires an actual character as its argument. The empty string contains no characters; therefore, the empty string is a bad argument for ASC(). ...lee There are two versions of this in BASIC and your view does not make you right anymore then my version, after all there is more then one version of Basic that support this. A empty string has zero length, not BAD ARGUMENT. There is no way a empty string should not report zero length but instead report BAD ARGUMENT. We are only talking about one Subroutine ASC so basically only one routine requires this exception to how it works, none of this applies to any other use of strings. Thus your view is only ASC requires special exception to how a string has zero length. Quote Link to comment Share on other sites More sharing options...
RXB Posted March 5, 2017 Share Posted March 5, 2017 (edited) Those links don't all support your theory. Returning 0 is silly, even if it is supported by other languages, especially when a string may contain character code 0. That is, A$=CHR$(0)::PRINT ASC(A$) will return 0. A negative value might have some worth versus tossing an error, but not a zero in my opinion. Hmm how does your argument work as your example A$=CHR$(0) has a length of 1. Negative value for what? Maybe you misunderstand the change is that a empty string has zero length unless ASC is used them magically it is now a BAD ARGUMENT? ANY OTHER TIME A EMPTY STRING IS FINE, only in ASC is it a ERROR? You guys are the ones insisting on INCONSISTENCY when it comes to strings. Edited March 5, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
RXB Posted March 5, 2017 Share Posted March 5, 2017 PRINT SEG$("",1,255) ! ERROR as there is no first character and length does not matter at all with a empty string (my chage would have no effect) PRINT SEG$("TEST",ASC(""),255) ! ERROR as zero is not a first character of a string (my change would have no effect) PRINT LEN(ASC("")) ! BAD ARGUMENT, actually it should factually report BAD VALUE, not BAD ARGUMENT (my change would report o for length and be correct) Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted March 5, 2017 Share Posted March 5, 2017 (edited) Hmm how does your argument work as your example A$=CHR$(0) has a length of 1. Negative value for what? Maybe you misunderstand the change is that a empty string has zero length unless ASC is used them magically it is now a BAD ARGUMENT? ANY OTHER TIME A EMPTY STRING IS FINE, only in ASC is it a ERROR? You guys are the ones insisting on INCONSISTENCY when it comes to strings. I believe you are trying to fix a problem that isn't a problem. Yes, A$=CHR$(0) implies A$ has a length of 1. I agree. Remember, 0 is a valid ASCII value. A null string has no ASCII value. The two are NOT equal. My earlier suggestion is that returning a negative number (such as -1) for a null string might allow some wiggle room. However, programmers should already account for (and anticipate) a null string prior to using ASC(string$), so in practice, your problem is a non-issue. You cannot write LEN(ASC("")); LEN is a string length operation. Did you intend to write LEN(CHR$(ASC(""))) ? If so, this is still a problem. Let's assume you changed ASC(""). We now run into a different problem: IF ASC("") = 0 then CHR$(ASC(""))="0" then [edit: the 0 here represents ascii 0, not the number 0] LEN(CHR$(ASC(""))) = 1 and a null string of length 0 cannot also be of length 1. So you still need to check the length of the original string, just like we do 'today'. I suppose you could modify LEN to compute the special case of LEN(ASC("")) but what would be the point? It would be like "fixing" A$=A to no longer generate a string-number mismatch. Some rules are meant to be. PRINT LEN(ASC("")) ! BAD ARGUMENT, actually it should factually report BAD VALUE, not BAD ARGUMENT (my change would report o for length and be correct) Bad Value may make more sense. However, you are again mixing two functions that have no business being used together, and that programmers would NEVER use together. You are creating a solution to a problem that does not exist. Edited March 5, 2017 by InsaneMultitasker 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.