RXB Posted October 9, 2023 Share Posted October 9, 2023 ZOOM today I was explaining the problem with RXB 2024 using the % symbol in ROM to indicate a Integer Whole Number. Like B%=10 would be Integer 10 and not like normal XB would be B=10 but 10 would be a 8 byte Floating Point number i.e. >40 >0A >00 >00 >00 >00 >00 >00 Anyway look at the code in XB ROM at line 382 you see % in the mix with other symbols until CPNIL and at line 405 you see % is CPNIL so you would think if you change CPNIL to someplace else it would go that to that address, but it never does. Why? Well at 3932 you see it just only goes to B *R7 and never gets past that point. If I change CPNIL it just crashes everthing. If you see a way to make this work let me know! SROM1.txt SROM2.txt Quote Link to comment Share on other sites More sharing options...
RXB Posted October 9, 2023 Author Share Posted October 9, 2023 I thought I should add that I have tried many times to get % symbol to work and all crash even when it is just supposed to do a lock loop like HERE JMP HERE It never gets to that line and is being intercepted before that time as I think the problem is a list of symbols on this line: 0360 0000 CPNIL EQU >00 " $ % ' ? Can not seem to extract the % from this list nor can I find where to inject a line to pre-empt the intercept of it. Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted October 9, 2023 Share Posted October 9, 2023 CPTBL is not a list of branch addresses. It is Character Property TBLle. Lines 377-390 define bit flags. CPNIL means no flag. * The CHARACTER PROPERTY TABLE * There is a one-byte entry for every character code * in the range LLC(lowest legal character) to * HLC(highest legal character), inclusive. LLC EQU >20 CPNIL EQU >00 " $ % ' ? CPDIG EQU >02 digit (0-9) CPNUM EQU >04 digit, period, E CPOP EQU >08 1 char operators(!#*+-/<=>^ ) CPMO EQU >10 multiple operator ( : ) CPALPH EQU >20 A-Z, @, _ CPBRK EQU >40 ( ) , ; CPSEP EQU >80 space CPALNM EQU CPALPH+CPDIG alpha-digit The table is used, for example, to check if a character is a digit. The characters " $ % ' ? have no special category, so their table entry is CPNIL. If anything, % and $ have a lot in common, if you want A$ and A% to be valid variable names. Excerpt: CPTBL EQU $-LLC BYTE CPSEP SPACE BYTE CPOP ! EXCLAMATION POINT BYTE CPNIL " QUOTATION MARKS BYTE CPOP # NUMBER SIGN BYTE CPNIL $ DOLLAR SIGN BYTE CPNIL % PERCENT ... BYTE CPNUM . PERIOD BYTE CPOP / SLANT BYTE CPNUM+CPDIG 0 ZERRO BYTE CPNUM+CPDIG 1 ONE BYTE CPNUM+CPDIG 2 TWO BYTE CPNUM+CPDIG 3 THREE 2 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted October 9, 2023 Share Posted October 9, 2023 At line 4144 in SROM2.txt you can make '%' a valid name character: * Names *-----------------------------------------------------------* * Replace following two lines for adding lowercase * * character set in 99/4A 5/12/81 * * CRU76 ANDI R0,CPALNM*256 Is this char alpha or digit * * JEQ CRU74 Yes, continue packing * CRU76 ANDI R0,CPULNM*256 Is this char alpha (both are * * upper and lower) or a digit? * JNE CRU78 Yes, continue packing * *-----------------------------------------------------------* * No, finish w/name packing CI R8,'$' Does name end with a $? JEQ CRU32L Yes, include it in name MOVB *R4,*R4 At an end of line? JEQ CRU79 Yes, don't back up pointer BL @BACKUP Backup for next char CRU79 B @CRU38 Jump to name/keyword check CRU82 B @CRU22 You could add CI R8,'%' JEQ CRU32L (uses 3 words.) It might be possible to get % in there without using more bytes. I see that the flag bit 01 is not used. It might be OK to change CPNIL to a 01 for the % and $ characters. Then instead of testing for the $ character only you could test for the 01 bit. Insert another equate at 383: CPVAR EQU >01 then replace BYTE CPNIL $ DOLLAR SIGN BYTE CPNIL % PERCENT with BYTE CPVAR $ DOLLAR SIGN BYTE CPVAR % PERCENT Then in the code at 4144 replace CI R8,'%' JEQ CRU32L with COC @BRKPN2+2,@CPTBL(R8) I found a word value 0001. Check if 01 bit set in CPTBL JEQ CRU32 Then it treats both $ and % as part of the variable name. Uhhh, that replaces 3 words with 4 words. Still better than +3 words. Also, this is a horrible hack. COC only operates on a word at an even address. So CPTBL+36 and CPTBL+37 result in testing the same word. In each case it does test whether CPTBL+37 has the bit 1 set. So it will jump if the char is either $ or %. (There is no such thing as a COCB instruction) This code may have undefined results on the 9980 or 9995, I'd have to check. 3 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted October 10, 2023 Author Share Posted October 10, 2023 Thanks will test it to see if it works. Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted October 10, 2023 Share Posted October 10, 2023 CRU76 ANDI R0,(CPVAR+CPULNM)*256 Is this char alpha (both are * * upper and lower) or digit or $ or % * JEQ CRUEND none of them * One way * ANDI R0,CPVAR*256 Does name end with a $ or %? * JNE CRU32L Yes, include it in name * The slower SLA saves 1 word SLA R0,8 JNC CRU78 Just Alphanum, continue packing JOC CRU32L $ or %, include $ or % in name * *-----------------------------------------------------------* * No, finish w/name packing CRUEND MOVB *R4,*R4 I found a way that fits in original size or less. Remember, all this does is to crunch a name like A% Changing the behavior to make it a 16-bit integer is a bigger job. Even bigger job to make it use just 2 bytes not 8 bytes. I see a lot of assumptions in memory allocation and garbage collection. That Numeric is 8 bytes. 2 Quote Link to comment Share on other sites More sharing options...
RXB Posted October 10, 2023 Author Share Posted October 10, 2023 41 minutes ago, FarmerPotato said: CRU76 ANDI R0,(CPVAR+CPULNM)*256 Is this char alpha (both are * * upper and lower) or digit or $ or % * JEQ CRUEND none of them * One way * ANDI R0,CPVAR*256 Does name end with a $ or %? * JNE CRU32L Yes, include it in name * The slower SLA saves 1 word SLA R0,8 JNC CRU78 Just Alphanum, continue packing JOC CRU32L $ or %, include $ or % in name * *-----------------------------------------------------------* * No, finish w/name packing CRUEND MOVB *R4,*R4 I found a way that fits in original size or less. Remember, all this does is to crunch a name like A% Changing the behavior to make it a 16-bit integer is a bigger job. Even bigger job to make it use just 2 bytes not 8 bytes. I see a lot of assumptions in memory allocation and garbage collection. That Numeric is 8 bytes. Yea considering my total free bytes in XB ROMs is like 10 bytes total. In ROM 1 and ROM 2 is 4 bytes just above >7000 and 6 bytes at >7FFA but those 6 bytes are for getting back to normal XB or it crashes from my XB ROM 3 I was hoping to figure a way to cut down the size used in XB ROMs by more than just 12 bytes. I know the place where the number is put into memory as a 8 Byte Floating Point location. The name of a Numeric Variable like X has the Address of the 8 Byte Floating Point location. When a Integer Variable like Y% will have the Address of the 2 byte value instead so I can mix and match as the XB program indicates the type of integer or FP. If you try to mix them, it will error out unless you use INT(FP variable), now this only goes one way. But you could do this YY=Y% which would make the value in Y% into a Floating Point value for use. This is what I have so far per your ideas: Spoiler * Names *-----------------------------------------------------------* * Replace following two lines for adding lowercase * * character set in 99/4A 5/12/81 * * CRU76 ANDI R0,(CPALNM)*256 Char alpha or digit * * JEQ CRU74 Yes, continue packing * CRU76 ANDI R0,(CPVAR+CPULNM)*256 Char alpha (both are * * upper and lower) or a digit? * * JNE CRU78 Yes, continue packing * JEQ CRUEND none of them * *-----------------------------------------------------------* * No, finish w/name packing * CI R8,'$' Does name end with a $? * I found a word value 0001. Check if 01 bit set in CPTBL * COC @BRKPN2+2,@CPTBL(R8) * JEQ CRU32L Yes, include it in name SLA R0,8 JNC CRU78 Just Alphanum, continue packing JOC CRU32L $ or %, include $ or % in name CRUEND MOVB *R4,*R4 At an end of line? JEQ CRU79 Yes, don't back up pointer BL @BACKUP Backup for next char CRU79 B @CRU38 Jump to name/keyword check CRU82 B @CRU22 Quote Link to comment Share on other sites More sharing options...
Tursi Posted October 12, 2023 Share Posted October 12, 2023 Good to see the progress there. FarmerPotato totally picked up on the intent and picked the ROM apart quicker than I could have 1 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted October 12, 2023 Author Share Posted October 12, 2023 Well tried FarmerPotato suggestions and it was a nice try but anything entered in Edit mode says "* SYNTAX ERROR *" So that was a bust. Good news is I can put in A=10 and it does not crash. But A%=10 is "* SYNTAX ERROR *" or A$="test" is "* SYNTAX ERROR *" PRINT is "* SYNTAX ERROR *" or SIZE is "* SYNTAX ERROR *" or anything else is "* SYNTAX ERROR *" Nice try but kind of made it worse. Would be great if I could just get out of XB ROMs and make my own routines to handle A%=10 but oddly it just refuses to exit. Guess I can insert a HERE JMP HERE into different places to see if I can find a place to see what can be done. But that is going to be very slow and time consuming to do. Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted October 12, 2023 Share Posted October 12, 2023 I probably got one of the JMP labels wrong 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted October 12, 2023 Share Posted October 12, 2023 13 hours ago, Tursi said: Good to see the progress there. FarmerPotato totally picked up on the intent and picked the ROM apart quicker than I could have I've been studying and writing parsers for many months now. The XB source was fascinating. NUD and LED are my close friends these days. 👯♂️ 2 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted October 13, 2023 Author Share Posted October 13, 2023 So made a video of what I have been doing so far. Why is it stuck in ROM 2? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 13, 2023 Share Posted October 13, 2023 8 hours ago, RXB said: So made a video of what I have been doing so far. Why is it stuck in ROM 2? I have not looked at the code closely enough to figure that out, but you are overly complicating the code at HERE. Though I see nothing wrong with that code, all you should need is HERE JMP $ because, if it gets to HERE, it is in ROM3 and nothing should change that. If the same result obtains, set a breakpoint in Classic99 at 7E0C:02 to see if it ever gets to HERE. ...lee 2 Quote Link to comment Share on other sites More sharing options...
RXB Posted October 13, 2023 Author Share Posted October 13, 2023 3 hours ago, Lee Stewart said: I have not looked at the code closely enough to figure that out, but you are overly complicating the code at HERE. Though I see nothing wrong with that code, all you should need is HERE JMP $ because, if it gets to HERE, it is in ROM3 and nothing should change that. If the same result obtains, set a breakpoint in Classic99 at 7E0C:02 to see if it ever gets to HERE. ...lee Thanks Lee it does get to ROM 3 and using Classic99 breakpoint and it does get to ROM3 but step past the breakpoint it goes back to ROM 2 but I did nothing to do that? So my thinking is Interrupts are being activated and that sends it back to ROM 2, I have no idea what else could be causing this to happen. Quote Link to comment Share on other sites More sharing options...
apersson850 Posted October 16, 2023 Share Posted October 16, 2023 But when working properly an interrupt does just that, interrupt and does what it's supposed to do, then return to the code running when the interrupt occurred and continue there, just like that interrupt never happened. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted October 17, 2023 Author Share Posted October 17, 2023 On 10/10/2023 at 12:13 PM, FarmerPotato said: CRU76 ANDI R0,(CPVAR+CPULNM)*256 Is this char alpha (both are * * upper and lower) or digit or $ or % * JEQ CRUEND none of them * One way * ANDI R0,CPVAR*256 Does name end with a $ or %? * JNE CRU32L Yes, include it in name * The slower SLA saves 1 word SLA R0,8 JNC CRU78 Just Alphanum, continue packing JOC CRU32L $ or %, include $ or % in name * *-----------------------------------------------------------* * No, finish w/name packing CRUEND MOVB *R4,*R4 I found a way that fits in original size or less. Remember, all this does is to crunch a name like A% Changing the behavior to make it a 16-bit integer is a bigger job. Even bigger job to make it use just 2 bytes not 8 bytes. I see a lot of assumptions in memory allocation and garbage collection. That Numeric is 8 bytes. Luckily there is not garbage collection in the upper 24K RAM of XB, only in VDP and it ignores FP numbers by just moving the entire memory of the variables in one block. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted October 17, 2023 Share Posted October 17, 2023 (edited) 18 hours ago, apersson850 said: But when working properly an interrupt does just that, interrupt and does what it's supposed to do, then return to the code running when the interrupt occurred and continue there, just like that interrupt never happened. Yes, but... If bank 3 of the rom is selected when the interrupt routine starts up and the interrupt writes to >6002, then bank 2 will be selected. Returning from the interrupt will not go back to bank 3 unless the code specifically tells it to do that. I doubt this problem is caused by the interrupt routine. To my knowledge, the bank cannot change unless you tell it to do so. If bank 3 is selected and the bank suddenly changes to bank 2, it is because somewhere the code has written to >6002. The Classic99 debugger can be a big help in finding where this is happening. Set a break point to >6002 and Classic99 will break when >6002 is written to - i.e. when bank 2 is selected. Edited October 17, 2023 by senior_falcon clarity 3 Quote Link to comment Share on other sites More sharing options...
apersson850 Posted October 18, 2023 Share Posted October 18, 2023 14 hours ago, senior_falcon said: Yes, but... If bank 3 of the rom is selected when the interrupt routine starts up and the interrupt writes to >6002, then bank 2 will be selected. That's why I wrote when the interrupt is working properly. If what you describe happens it's not. Quote Link to comment Share on other sites More sharing options...
RXB Posted October 20, 2023 Author Share Posted October 20, 2023 Well found the location of where it determines if a Numeric like A=10 or a String like A$="test" Value has to to be on the VDP stack and in FAC 1725 ************************************************************ 1726 * Test arguments on both the stack and in the FAC 99/4 ASSEMBLER PARSES2 PAGE 0038 1727 * Both must be of the same type 1728 * CALL: 1729 * BL @ARGTST 1730 * JEQ If string 1731 * JNE If numeric 1732 ************************************************************ 1733 6B6E C1A0 ARGTST MOV @VSPTR,R6 Get stack pointer 6B70 836E 1734 6B72 05C6 INCT R6 1735 6B74 D7E0 MOVB @R6LB,*R15 Load 2nd byte of stack address 6B76 83ED 1736 6B78 1000 NOP Kill some time 1737 6B7A D7C6 MOVB R6,*R15 Load 1st byte of stack address 1738 6B7C 1000 NOP Kill some time 1739 6B7E 9820 CB @XVDPRD,@CBH65 String in operand 1? 6B80 8800 6B82 65A7 1740 6B84 1606 JNE ARGT10 No, numeric 1741 6B86 9820 CB @FAC2,@CBH65 Yes, is other the same? 6B88 834C 6B8A 65A7 1742 6B8C 1306 JEQ ARGT20 Yes, do string comparison 1743 6B8E 0460 ARGT05 B @ERRT Data types don't match 6B90 630C 1744 NUMCHK 1745 6B92 9820 ARGT10 CB @FAC2,@CBH65 2nd operand can't be string 6B94 834C 6B96 65A7 1746 6B98 13FA JEQ ARGT05 If so, error 1747 6B9A 045B ARGT20 RT Ok, so return with status 1748 * VPUSH followed by a PARSE 1749 6B9C 05C9 PSHPRS INCT R9 Get room on stack 1750 6B9E 0289 CI R9,STKEND Stack full? 6BA0 83BA 1751 6BA2 1B41 JH VPSH27 Yes, error 1752 6BA4 C64B MOV R11,*R9 Save return on stack 1753 6BA6 020B LI R11,P05 Optimize for the parse 6BA8 648A 1754 * Stack VPUSH routine 1755 6BAA 0200 VPUSH LI R0,8 Pushing 8 byte entries 6BAC 0008 1756 6BAE A800 A R0,@VSPTR Update the pointer 6BB0 836E 1757 6BB2 C060 MOV @VSPTR,R1 Now get the new pointer 6BB4 836E 1758 6BB6 D7E0 MOVB @R1LB,*R15 Write new address to VDP chip 6BB8 83E3 1759 6BBA 0261 ORI R1,WRVDP Enable the write 6BBC 4000 1760 6BBE D7C1 MOVB R1,*R15 Write 1st byte of address 1761 6BC0 0201 LI R1,FAC Source is FAC 6BC2 834A 1762 6BC4 D831 VPSH15 MOVB *R1+,@XVDPWD Move a byte 6BC6 8C00 1763 6BC8 0600 DEC R0 Decrement the count, done? 1764 6BCA 15FC JGT VPSH15 No, more to move 1765 6BCC C00B MOV R11,R0 Save the return address 1766 6BCE 9820 CB @FAC2,@CBH65 Pushing a string entry? 6BD0 834C 99/4 ASSEMBLER PARSES2 PAGE 0039 6BD2 65A7 1767 6BD4 160E JNE VPSH20 No, so done 1768 6BD6 C1A0 MOV @VSPTR,R6 Entry on stack 6BD8 836E 1769 6BDA 0226 AI R6,4 Pointer to the string is here 6BDC 0004 1770 6BDE C060 MOV @FAC,R1 Get the string's owner 6BE0 834A 1771 6BE2 0281 CI R1,>001C Is it a tempory string? 6BE4 001C 1772 6BE6 1605 JNE VPSH20 No, so done 1773 6BE8 C060 VPSH19 MOV @FAC4,R1 Get the address of the string 6BEA 834E 1774 6BEC 1302 JEQ VPSH20 If null string, nothing to do 1775 6BEE 06A0 BL @STVDP3 Set the backpointer 6BF0 18AA 1776 6BF2 C060 VPSH20 MOV @VSPTR,R1 Check for buffer-zone 6BF4 836E 1777 6BF8 C16 EQU $+2 1778 6BF6 0221 AI R1,16 Correct by 16 6BF8 0010 1779 6BFA 8801 C R1,@STREND At least 16 bytes between stac 6BFC 831A 1780 * and string space? 1781 6BFE 1236 JLE VPOP18 Yes, so ok 1782 6C00 05C9 INCT R9 No, save return address 1783 6C02 C640 MOV R0,*R9 on stack 1784 6C04 06A0 BL @COMPCT Do the garbage collection 6C06 73D8 1785 6C08 C019 MOV *R9,R0 Restore return address 1786 6C0A 0649 DECT R9 Fix subroutine stack pointer 1787 6C0C C060 MOV @VSPTR,R1 Get value stack pointer 6C0E 836E 1788 6C10 0221 AI R1,16 Buffer zone 6C12 0010 1789 6C14 8801 C R1,@STREND At least 16 bytes now? 6C16 831A 1790 6C18 1229 JLE VPOP18 Yes, so ok 1791 6C1A 0200 VPSH23 LI R0,ERROM No, so MEMORY FULL error 6C1C 0103 1792 6C1E 06A0 VPSH25 BL @SETREG In case of GPL call 6C20 1E7A 1793 6C22 0460 B @ERR 6C24 6652 1794 6C26 0460 VPSH27 B @ERRSO STACK OVERFLOW 6C28 6468 1795 * Stack VPOP routine 1796 6C2A 0202 VPOP LI R2,FAC Destination in FAC 6C2C 834A 1797 6C2E C060 MOV @VSPTR,R1 Get stack pointer 6C30 836E 1798 6C32 8801 C R1,@STVSPT Check for stack underflow 6C34 8324 1799 6C36 121B JLE VPOP20 Yes, error 1800 6C38 D7E0 MOVB @R1LB,*R15 Write 2nd byte of address 6C3A 83E3 1801 6C3C 0200 LI R0,8 Popping 8 bytes 6C3E 0008 1802 6C40 D7C1 MOVB R1,*R15 Write 1st byte of address 99/4 ASSEMBLER PARSES2 PAGE 0040 1803 6C42 6800 S R0,@VSPTR Adjust stack pointer 6C44 836E 1804 6C46 DCA0 VPOP10 MOVB @XVDPRD,*R2+ Move a byte 6C48 8800 1805 6C4A 0600 DEC R0 Decrement the counter, done? 1806 6C4C 15FC JGT VPOP10 No, finish the work 1807 6C4E C00B MOV R11,R0 Save return address 1808 6C50 9820 CB @FAC2,@CBH65 Pop a string? 6C52 834C 6C54 65A7 1809 6C56 160A JNE VPOP18 No, so done 1810 6C58 04C6 CLR R6 For backpointer clear 1811 6C5A C0E0 MOV @FAC,R3 Get string owner 6C5C 834A 1812 6C5E 0283 CI R3,>001C Pop a temporary? 6C60 001C 1813 6C62 13C2 JEQ VPSH19 Yes, must free it 1814 6C64 06A0 BL @GET1 No, get new pointer from s.t. 6C66 6C9E 1815 6C68 C801 MOV R1,@FAC4 Set new pointer to string 6C6A 834E 1816 6C6C 0450 VPOP18 B *R0 And return 1817 6C6E 0200 VPOP20 LI R0,ERREX * SYNTAX ERROR 6C70 0403 1818 6C72 10D5 JMP VPSH25 So Tursi suggest a new token for INTEGER like >C9 as >65 is for a STRING and >00 is for Floating Point. Thus need to figure out where to pluck the % token for a variable and the >C9 as the flag for a Integer. 3 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.