Jump to content
IGNORED

XB ROMs using a known symbol


RXB

Recommended Posts

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

 

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

 

  • Like 2
Link to comment
Share on other sites

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. 
 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

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. 
 

 

  • Like 2
Link to comment
Share on other sites

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

   

Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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.  :) 👯‍♂️

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

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

  • Like 2
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by senior_falcon
clarity
  • Like 3
Link to comment
Share on other sites

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.

  • Like 3
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...