Jump to content

Photo

XB Game Developers Package


369 replies to this topic

#301 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Tue Aug 7, 2018 9:14 PM

I feel like a pain...

I am getting an assembler error SYMBOL TRUNCATION. While compiling XB256.  I am only using DISPLY so far in this app.

 

I tried shrinking variable size, but I still get the error. If I remove the DISPLY lines, it compiles in normal XB no errors.

 

I searched for the error in the docs and in this tread, but didn't get a hit.

You're not being a pain at all! But  I don't believe your problem is with DISPLY. I compiled this program and it worked the same in XB and compiled, with no errors and no problems:

3 CALL CLEAR
5 XTR=3
10 CALL LINK("DISPLY",10,1,"EXTRA"):: CALL LINK("DISPLY",11,1,STR$(XTR))

The "SYMBOL TRUNCATION' should be accompanied by a line number. That number refers to the line of the source code created by the compiler, not the line number in the XB program.

Take a look at the source code and you should be able to find out what the XB line number is. (Line 200 compiles to L200) See if you can see a problem in that line. If you can't find it, send me a copy of the XB program and I will have a look.

 

 


#302 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Tue Aug 7, 2018 10:11 PM

(RXB in post 298)

Example in XB (from 1980gamer)

XTR=3

DISPLAY AT(10,1):"EXTRA" :: DISPLAY AT(11,1):XTR

vs

CALL LINK("DISPLY",10,1,EXTRA) :: CALL LINK("DISPLY",11,1,XTR)

 

Looks like a SCREEN offset problem to me. I cannot imagine why this would look like a screen offset problem to anyone!

I could be wrong, (you are) I do not use XB256 as it is not compatible with RXB just XB.(It is, just not with the new features.)

 

Sorry you know the Title is XB Game Development Package, I guess it should be titled:  XB256 Game Development Package ONLY.

Rather misleading that anyone with anything else can be involved. People can chime in with whatever they want. But you seem to respond to virtually every post involving BASIC or XB with a list of RXB features which are frequently not relevant in solving the problem being discussed. 

 

This happens often in other threads that get off topic, but I never complained when it happened to me, now why is that? Threads always get off topic. That's fine and to be expected. I get it - you are proud of RXB and rightly so! I'm just saying that before responding to a post try asking yourself: is my response actually relevant to the question asked, or is it just another advertisement for RXB. For example, if the post is about MiniMemory, it is not likely that a solution requiring RXB would be useful.


Edited by senior_falcon, Tue Aug 7, 2018 10:11 PM.


#303 RXB OFFLINE  

RXB

    River Patroller

  • 3,426 posts
  • Location:Vancouver, Washington, USA

Posted Tue Aug 7, 2018 10:55 PM

Hmm TI Basic, Mini Memory and XB all have GPL which is a thread they all have in common, and XB256 is using that as a base to build upon.

So getting ideas from other strictly unlike sources is how anything is created or discovered.

 

And though may not be relevant to you personally I doubt you speak for everyone everywhere.

Thus I defer to you on this forum post. 



#304 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Wed Aug 8, 2018 5:22 AM

The error was in line one.   That is the name of the file.

 

I was saving as NECXB256  I changed to NEC256 and it worked fine.

 

So it looks like 7 chars is to big.  I didn't try 6 yet.  I used to only use 4 in the older version.  IE NEC1-C would be the end result.

But with the new version and the File name auto passed through, I was less concerned with making the file name changes at every step.

 

Thanks for the help!   I need to XB256 the rest of the program now.  That is remove the call sounds I was using to slow things down and use DELAY instead etc.

It had been to long since I last worked on anything.  It is coming back to me now....


  • RXB likes this

#305 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Wed Aug 8, 2018 5:44 AM

The error was in line one.   That is the name of the file.

 

I was saving as NECXB256  I changed to NEC256 and it worked fine.

 

So it looks like 7 chars is to big.  I didn't try 6 yet.  I used to only use 4 in the older version.  IE NEC1-C would be the end result.

But with the new version and the File name auto passed through, I was less concerned with making the file name changes at every step.

 

Thanks for the help!   I need to XB256 the rest of the program now.  That is remove the call sounds I was using to slow things down and use DELAY instead etc.

It had been to long since I last worked on anything.  It is coming back to me now....

I don't see why that would matter. You should be able to have 10 byte long file names (15 if you count the DSK1.) Can you post the first few lines?

 

For what it's worth, I don't like DELAY. The computer does nothing when it is DELAYing. If it is part of a game loop it is much better if you can use CALL KEY or something else that is useful. 


Edited by senior_falcon, Wed Aug 8, 2018 5:49 AM.

  • RXB likes this

#306 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Wed Aug 8, 2018 3:16 PM

Attached are the 2 files.  Working and Non-working.

 

The Delay is only used in NON-Action points.  I am using Call sound to pause now.  But it is easy to just set the duration.

 

I only changed the file name.

 

nec256 works necXB256 does not.

 

Attached Files



#307 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Wed Aug 8, 2018 9:53 PM

Here is the source code for two compiled programs. On the left is my 256DEMO and on the right is your NECXB256.

Why are they so very different from each other?? What is NECXB256.T doing at the top of the right hand one? Some possibilities are:

1 - You are not setting up the game developer's package as described in the docs.

2 - The docs do not properly describe how to set it up. (But when I follow them it works fine.)

3 - Something about Windows 10 is messing up the file when you save it, or is messing up the proper execution of Classic99.

4 - something else...

Start with a small program: 10 PRINT "HELLO WORLD" and experiment until you find a combination that produces source code like you see on the left.

I have never had problems like this and so do not have any more ideas. Until you do this I don't think it can ever work as designed.

 

gallery_34177_1100_47128.jpg


Edited by senior_falcon, Wed Aug 8, 2018 9:55 PM.


#308 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Thu Aug 9, 2018 4:44 AM

Okay,  So, the only thing I did was save to DSK1 vs DSK2.  Also the name from NEC256 to NEC25 to tell them apart.

It is formatted properly.

 

       DEF RUNEA,RUN,RUNV,CON
RUNEA  B @RUNEA5
FRSTLN
L10
       DATA CLEAR
L20
       DATA SCREEN,NC1
L30
L110
       DATA RESTOR,L40
FOR1
       DATA FOR,NV1,NC2,NC3,ONE,0,0
       DATA READ,NV2,NV3,NV4
       DATA COLOR,NV2,NV3,NV4
       DATA NEXT,FOR1+2
 



#309 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Thu Aug 9, 2018 4:54 AM

So, in DSK2  I have V9T9 Headers and No Long Filenames.  The file names may be the truncation piece?

 

Anyway,  I copied the Classic99 folder, all setting etc.  from my prior laptop.  I never had issues in the past.

I did move from V9T9 way back when. Actually, I used a different EMU before classic99...  Can't remember the name,  99Siim or something like that.

 

The crazy thing is, before the longer file name, my compiling worked fine, even though it was structured so differently.

( That is, After fixing the WIN10 security settings )



#310 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Thu Aug 9, 2018 8:22 AM

When I read it, what you have posted as NEC256.TXT begins like this:

NEC256.TXT##�##�P�##############################################################################################################
DEF RUNEA,RUN,RUNV,CON#RUNEA B @RUNEA5#FRSTLN#L10# DATA
CLEAR#L20# DATA SCREEN,NC1#L30#L110# DATA
RESTOR,L40#FOR1# DATA FOR,NV1,NC2,NC3,ONE,0,0# DATA
READ,NV2,NV3,NV4# DA

This is not the same as what you get in post #308. Somehow what you have posted as NEC256 will assemble, but I sure don't know how it can.

I think the problem is that you are saving using V9T9 format. All my files Use TIFILES and in the manual Tursi says:  "Classic99 considers the V9T9 file format to be deprecated." Use FIAD and TIFILES for everything. I'm not sure if the .TXT extension means that you need to enable long filenames but it won't hurt.
 



#311 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Thu Aug 9, 2018 6:03 PM

Well, that theory is disproved. I just checked and found that if you check "Write V9T9 headers" the results seem no than when using "TI files headers".

I also tried using a long file name, 10 characters in length plus the .TXT extension with V9T9 checked and it too compiled properly

I am out of ideas as to why your results are different than mine.

Download the NECXB256 that you posted above and look at it with a text editor. Does it look normal or does it look like it does in post #307 above.

 

 

See below.


Edited by senior_falcon, Thu Aug 9, 2018 9:11 PM.


#312 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Thu Aug 9, 2018 8:16 PM

I was finally able to duplicate the results you are getting by checking "Write V9T9 headers", unchecking "Write DV80 as windows text" and unchecking "Enable long filenames."

Classic99 will only save in windows format if you have checked "Write DV80 as windows text". Adding the .TXT extension will not save in windows format. When you want to open the file, the TXT extension helps windows know what program is needed to open it.

So it looks like the problem was with the documentation.

 

Any disk that will be used by the compiler must be set just like DSK1 as described in Using XBGDP. 

 

gallery_34177_1100_5880.jpg

 



#313 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Fri Aug 10, 2018 4:41 PM

Wow, that is investigating above and beyond the call...

I have added a new DSK with the recommended config.  I'll eventually migrate everything over to the correct formatting.

 

Also, I am amazed how much faster your IRND is over RND  Very Impressive.



#314 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Fri Aug 10, 2018 7:57 PM

There was a big discussion a few years back regarding the relative speeds of RND in BASIC and XB, with XB being dramaticly slower. (I remember it being around 5x slower!) Rich modified RXB so it would use the faster TI BASIC random number generator. KALEIDOSCOPE runs much faster with the faster random number generator. As I recall it was 2-3x faster. This program makes very heavy use of RND and most would not benefit so much, but nevertheless, the speed increase is surprising.

After finding this out (thank you Rich!) I developed IRND to generate random numbers they way you would in XB with INT(RND*6) but done entirely in assembly. To minimize the overhead you can generate up to 8 random numbers per CALL LINK("IRND")

The main benefit comes when running in XB256. Because they both use the same random number generator, in a compiled program IRND probably doesn't have much speed advantage over RND


Edited by senior_falcon, Fri Aug 10, 2018 8:01 PM.


#315 RXB OFFLINE  

RXB

    River Patroller

  • 3,426 posts
  • Location:Vancouver, Washington, USA

Posted Fri Aug 10, 2018 11:06 PM

Thank you.



#316 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Sat Aug 11, 2018 7:56 PM

I didn't time RND vs IRND just the eye test....

 

But I need to get 15 distinct random numbers to build a slide puzzle.  It is certainly much faster.  XB256 and compiled.

 

1 thing I didn't consider until now...  Distinct numbers. Maybe IRND doesn't repeat values as often as RND?  I test for uniqueness after each value.

 

Whatever the reason... I really like it. If the puzzle is not solvable, I rebuild it.  It makes a big difference.


  • RXB likes this

#317 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Wed Aug 15, 2018 6:50 PM

In xb256, does DISPLY support USING? 

I see I can rotate the display even diagonal,  But when I use numeric values, it is treated like a string.

 

If a number is declining, this doesn't work so well.  DISPLY  the value 10 and decrement by 1.  It displays 90.

 

I am certain I could pad the text and work around it, But if this is out of the box, no need to reinvent the wheel.

 

Thanks!

 

I did a search with no luck...  Maybe my search was bad...  I'll try again.



#318 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Wed Aug 15, 2018 7:51 PM

CALL LINK("DISPLY") works as described in the docs. It prints a string starting in any row/column position. With an optional parameter you can print to the right, left, up, down, or diagonally. With a second parameter you can print the string repeatedly. 

DISPLAY USING will work in XB256, but if you wish to compile the program, remember that USING is not supported in compiled code.

 

f a number is declining, this doesn't work so well.  DISPLY  the value 10 and decrement by 1.  It displays 90.

 

This displays 9 just like it is supposed to. It just doesn't clear the 0 left over from printing the 10.

While not as neat as USING the following code should do what you want. Line 7 concatenates the right number of leading spaces with the string (Remember that you need to convert numbers into strings with STR$.)

 

4 CALL CLEAR
5 FOR I=15 TO -15 STEP -1
6 N$=STR$(I)
7 N$=RPT$(" ",3-LEN(N$))&N$
10 CALL LINK("DISPLY",10,10,N$)
20 NEXT I


#319 RXB OFFLINE  

RXB

    River Patroller

  • 3,426 posts
  • Location:Vancouver, Washington, USA

Posted Wed Aug 15, 2018 8:12 PM

In XB DISPLAY USING is one of the most complicated sections of XB code. 

The code in GPL for PRINT is mostly USING clause:

***********************************************************
*                    PRINT ROUTINE
* MAIN-HANDLER FOR ALL PRINT-FUNCTIONS
***********************************************************
PRINT  CALL INITKB            Initialize keyboard I/O
       CEQ  NUMBEZ,@CHAT      Could still be anything
       BR   PRINZ1
       CALL CHKFN             Check if default or open chan
       DCZ  @FAC              Default intended
       BS   PRNZ10
       CALL CHKCON            Check and convert expression
       BR   ERRFE             Error if PAB not in system
* PRINT allowed in output, append or update modes
*       Not allowed in input mode
       CLOG >04,V@FLG(@PABPTR)
       BS   G8288
       CLOG >02,V@FLG(@PABPTR)
       BS   ERRFE
G8288  CEQ  CZREAD,V@COD(@PABPTR)
       BR   G8293
       CLR  V@OFS(@PABPTR)    Unpend pending INPUTs
G8293  ST   CZWRIT,V@COD(@PABPTR) uncomplete PRINTs
       CALL PRINIT            Initialize some variables
* Next character has to be either EOL, COMMA, or COLON
       CALL CHKEND
       BS   EOLEX              exit on end of statement
       CALL PARREC            Parse possible record clause
       BS   PRINZ0            found "," but no REC clause
PRNZ10 CALL CHKEND
       BS   EOLEX             Exit on end of statement for
*                       "PRINT #0" or "PRINT file position"
       CEQ  COMMAZ,@CHAT
       BR   G82BE
       XML  PGMCHR            Get next in line
PRINZ0 CZ   @PABPTR           For "PRINT #0"
       BS   USING
*         Interal type of file?
       CLOG >08,V@FLG(@PABPTR)
       BR   ERRFE
       BR   USING             Execute USING clause
G82BE  XML  SPEED             Must be at a
       BYTE SYNCHK          *   colon at this point
       BYTE COLONZ          *     and error off on others
       BR   CONPRT            Make it a short branched ELSE
PRINZ1 CEQ  USINGZ,@CHAT
       BS   USING             End standard initialization
* Test standard separators
CONPRT CALL TSTSEP            Test separator character
       CEQ  TABZ,@CHAT        Handle TABs
       BS   PRTAB
* At this point we've checked TAB and ; , :
* The only remaining print items have to be expressions
*  All expressions are being handled below.
* If the result of the expression is a numeric, the string
* is transformed into a string and printed. Strings are
* printed "as is".
*  The code for strings and converted numerics cannot be ma
* common, since numerics may require an extra space behind
* the item, depending upon the current position in the reco
*  Either way, the string is chunked up into little pieces
* it won't fit in an empty record.
       XML  PARSE             Evaluate the expression
       BYTE COLONZ
* Special code for INTERNAL file handling
*  Translate numeric datums into string format and indicate
* length 8. Then check to see if the item fits within the
* current record. If not, it is an error, since each item
* has to fit.
       CALL TSTINT            Test for internal files
       BS   OTHEZ1            Nope, something different
       CEQ  STRVAL,@FAC2      Change numerics
       BS   G82EC
       ST   8,@FAC12          To string length 8
       MOVE 8,@FAC,@ARG       Save in ARG
       ST   ARG,@FAC11        And use this as source
       CALL RSTRING           Reserve some string space
G82EC  ST   @RECLEN,@ARG      Compute remaining space to EO
       SUB  @CCPPTR,@ARG       for space checking
       INC  @ARG              Make it real space
       CHE  @ARG,@FAC7        Not enough!!!!!
       BS   ERRFE
* The = check includes length byte
       ST   @FAC7,V*CCPADR    Prestore string length
       DINC @CCPADR           Update actual RAM address
       INC  @CCPPTR            and internal column pointer
       BR   OTHEZ0
OTHEZ1 CEQ  STRVAL,@FAC2      Print the string result
       BR   G830D
OTHEZ0 CALL OSTRNG            Output the string to the reco
       BR   CHKSEP
G830D  CLR  @FAC11            Select standard BASIC format
       XML  XCNS              Convert number to string
       CALL RSTRING           Reserve and copy string
       CALL OSTRNG            Output the string
* Possibly add an extra space if we're not at the end of th
* current record.
       CHE  @CCPPTR,@RECLEN   Enough space left
       BR   CHKSEP
       ST   SPACE,V*CCPADR    Add trailing space
       ADD  @DSRFLG,V*CCPADR  Take care of screen I/O
       DINC @CCPADR           Update current column address
       INC  @CCPPTR            and base 1 pointer
CHKSEP CALL TSTSEP            Check for legal delimiter
       BR   ERRSYN            Illegal delimiter. SYNTAX ERR
*                              Unconditional branch
* PRTAB - Print TAB as part of PRINT command
PRTAB  CALL TSTINT            Watch out for INTERAL file ty
       BR   ERRFE             They can't handle TABs
       XML  PGMCHR            Skip TAB keyword
       CEQ  LPARZ,@CHAT
       BR   ERRSYN
       XML  PARSE             Parse TAB expression
       BYTE RPARZ
       CALL CNVDEF            Check and convert to integer
       ST   @RECLEN,@FAC2     Set modulo number
       CALL COMMOD            Compute remainder
       CH   @FAC1,@CCPPTR     Position on next output recor
       BR   G834F
       CALL OUTREC            Output current record - no pe
       BS   CHKSEP             react on SIZE block!!!
G834F  CEQ  @FAC1,@CCPPTR     Stay here
       BS   CHKSEP
       ST   @FAC1,@MNUM+1     Fill with spaces
       XML  IO                OK, go ahead... fill'r up
       BYTE FILSPC
       BR   CHKSEP            And check separator again
* Comma is similar to TAB, except that it generates at leas
* one space. The exact number of spaces generated depends
* upon the current position within the record. If the next
* fixed tab-position is outside the record, the record, the
* current record is output and the column pointer is reset
* to column 1 of the next record.
PRTCOM ST   @CCPPTR,@MNUM+1   Compute initial # of spaces
       DEC  @MNUM+1           Decrecment for 0 origin
       CLR  @MNUM             Clear high byte of double
       DIV  14,@MNUM          TABs are 14 spaces apart
       INC  @MNUM             Compute next TAB-stop
       MUL  14,@MNUM           and actual position
       CH   @MNUM+1,@RECLEN   Within this record
       BR   PRCOL
       INC  @MNUM+1           Convert to real position
       XML  IO                Fill spaces to new location
       BYTE FILSPC
       BR   PRSEM             Outside current record
* The ":" (colon) separator is used to output the current
* record, and proceed to position 1 of the next record.
PRCOL  CALL OUTREC            Output the current record
* The ";" (semi-colon) generates the null string. Since all
* print items should be separated by a separator, this one
* has been introduced to separate without moving to another
* position. Notice that all separators join up here.
PRSEM  XML  PGMCHR            Skip the separator
       CALL CHKEND            Exit on end of line
       BR   CONPRT            Continue if not end of line
PRSMZ1 CZ   @DSRFLG           For screen output continue
       BS   PREXIT
       CLOG >08,@PABPTR       Check SIZE clause
       BS   PREXIT
       CALL OUTREC            Output current record (blank
       ST   @CCPADR+1,@CCPPTR Compute correct value for CCP
       SUB  >E1,@CCPPTR       Subtract current screen base
       BR   PREXIT             and exit form this command
* End of line exit routine for PRINT statement
EOLEX  CZ   @DSRFLG           I/O - remove blocks if
       BS   G83A1
       CLOG >04,@PABPTR        " AT" clause unused
       BR   G83A1
       AND  >E7,@PABPTR        remove flag 3 (SIZE used)
G83A1  CALL OUTREC            Output pending record
* Continue here if record remains pending
PREXIT CZ   @DSRFLG           Regular file/device I/O
       BR   G83B1
       DEC  @CCPPTR           Back to actual offset
       ST   @CCPPTR,V@OFS(@PABPTR) Save for next statement
       XML  CONT              Continue with next statement
*                              End external I/O handling
* Reset of code is for internal I/O handling (VDP)
G83B1  CLOG >04,@PABPTR       Is not used
       BR   G83BB
       ST   @CCPPTR,@XPT      Save current value of pointer
       INCT @XPT              CCPPTR: 1-28
G83BB  CLOG >02,@PABPTR       Used BEEP clause
       BS   G83C3
       CALL TONE1             ---------- BEEP ------------
G83C3  XML  CONT              Continue in PARSE routine
* TSTINT - test for INTERAL type files, set COND if file
*          is NOT INTERNAL
TSTINT CZ   @DSRFLG           Couldn't possibly be INTERNAL
       BR   RTC
       CLOG >08,V@FLG(@PABPTR) Set COND according to bit 3
       RTNC                   Return without changing COND
********* PRINT / DISPLAY USING SECTION *******************
* Arrive here after the keyword "USING" has been rejected.
USING  XML  SPEED
       BYTE SYNCHK          * Get first character of format
       BYTE USINGZ          *  after (double) checking USIN
       CEQ  LNZ,@CHAT         Pick up the line number
       BR   G8430
       XML  PGMCHR            Get high address
       ST   @CHAT,@FAC
       XML  PGMCHR             and low address
       ST   @CHAT,@FAC1
       XML  PGMCHR              get next program character
       DST  @EXTRAM,@FAC2        in SEETWO : EXTRAM value w
*                                 changed
       XML  SPEED
       BYTE SEETWO          *  Find the line # in the progr
       DEX  @EXTRAM,@FAC2      result in SEETWO is in EXTRA
*                               and restore EXTRAM value
       BR   USNGZ1               has to match exactly
       DINCT @FAC2            Move up to the pointer field
       DST   @DATA,@FAC8      Save DATA pointer for READ fi
       CALL GRSUB2            Read 2 bytes of data from ERA
       BYTE FAC2           *  @FAC2 : Source address on ERA
       DST  @EEE1,@DATA       @EEE1 : Destination addr. on
*                              Put it in @DATA
       ST   IMAGEZ,@FAC2      Search for an IMAGE token
       CALL SEARCH             at beginning of an statement
       BS   USNGZ1            Error if not found on this li
       CALL GETGFL            Get first part of format stri
       CALL CHKSTR            Prepare data for string assig
       DST  @FAC6,@BYTES      Copy actual string length in
       DST  @FAC8,@DATA       Restore original DATA pointer
       CALL CTSTR             Create a temporary string
       DCZ  @FAC6
       BS   G842E
       CZ   @RAMTOP           Data from RAM
       BR   G8423
       MOVE @FAC6,V*TEMP5,V*SREF
       BR   G842E
G8423  DST  @FAC6,@FFF1       FFF1 : byte count
       DST  @TEMP5,@DDD1      DDD1 : source address in ERAM
       DST  @SREF,@EEE1       EEE1 : destination address on
       XML  GVWITE            Write data from ERAM to VDP
G842E  BR   G8438
G8430  XML  PARSE             Parse up to the ending ":"
       BYTE COLONZ
       CEQ  STRVAL,@FAC2      * IMAGE ERROR *
       BR   USNGZ1
G8438  CEQ  COLONZ,@CHAT      Probably no variable list
       BS   G8448
       CALL CHKEND            We better check that through
       BR   ERRSYN             something sneaky sneaked in
       CZ   @FAC7             End of line exit
       BS   EOLEX
       BR   G8463             Look for format item
G8448  CZ   @FAC7             Exclude null strings
       BS   USNGZ1
       DST  @FAC4,@ARG        Get start address for string
       ST   @FAC7,@ARG2       Get format string length
USNGZ0 CEQ  >23,V*ARG         Found no format item yet
       BS   G8460
       DINC @ARG              Try next address
       DEC  @ARG2             Update address
       BR   USNGZ0            Try up to the end of the stri
USNGZ1 BR   ERRIM             * IMAGE ERROR
* Now we're sure that we have at least one legal format ite
* (anything with a "#" in it)
G8460  ST   COMMAZ,@CHAT      Fake comma seperator for prin
G8463  XML  VPUSH             Current string might be tempo
       DST  @FAC6,@BYTES      Create a workstring for outpu
       INC  @BYTES+1          Create space for end of strin
       CARRY                  String would be too long
       BS   USNGZ1
       XML  GETSTR            Length whold equal format str
       DST  @SREF,@CURLIN     Create a temporary string
       DADD @FAC6,@SREF       Compute last position in stri
       CLR  V*SREF            Set end of string indicator
USNGZ3 DST  V@4(@VSPTR),@FAC4 Update FAC4 area in case garb
       MOVE @FAC6,V*FAC4,V*CURLIN Copy format
       DST  @CURLIN,@FAC4     Complete preps for VPUSH
       DST  >001C,@FAC        SREF = >001C
       DINC @FAC6             Include 0 in string length
       XML  VPUSH             Make the string temporary
       DST  V@4(@VSPTR),@CURLIN Update current line pointer
USNGZ4 CEQ  >23,V*CURLIN      Try to locate the next format
       BS   G84C3
       CZ   V*CURLIN          Not end of string yet
       BS   G84A2
       DINC @CURLIN           Update pointer if not found
       BR   USNGZ4             and continue searching
G84A2  CEQ  COMMAZ,@CHAT      Stop on last variable
       BR   USNGZ9
       XML  VPOP              Restore original workstring d
       ST   @FAC7,@BYTES      Pring the current format stri
       DEC  @BYTES            Don't count the last "0"
       ST   1,@MNUM+1         Indicate direct output withou
       CALL CHKRZ0            Copy string to output record
       CALL OUTREC            Also output current record
* FAC still contains the right data, however it is easier j
* to copy the original string again.
       DST  @FAC4,@CURLIN     Reconstruct CRULIN
       XML  VPOP              Copy original string info
       XML  VPUSH             Without actually removing it
       DSUB @FAC6,@CURLIN     Reconstruct start address
       BR   USNGZ3            Continue for the next variabl
G84C3  DCEQ V@4(@VSPTR),@CURLIN Avoid "#" as count
       BS   USNZ42
       DDEC @CURLIN           Backup to the sign
       CEQ  >2E,V*CURLIN      Used ".#####"
       BR   G84DB
       DCEQ V@4(@VSPTR),@CURLIN
       BS   USNZ42
       DDEC @CURLIN           Avoid checking count bit
G84DB  CEQ  >2D,V*CURLIN      Check for minus
       BS   USNZ42
       CEQ  >2B,V*CURLIN      Check for plus
       BS   USNZ42
       DINC @CURLIN           It's neither, so we undo
* Check for availability of variables
USNZ42 CEQ  COMMAZ,@CHAT      Exit if no more pt item
       BR   USNGZ9
       XML  PGMCHR            Get next expression
       DSUB V@4(@VSPTR),@CURLIN Make CURLIN offset for
*                                garbage collection
       XML  PARSE             Parse up to ";" or ","
       BYTE SEMICZ
       DADD V@4(@VSPTR),@CURLIN Reconstruct new CLN after
*                                garbage collection
       DCLR @FAC8             Start with clean sheet for co
       DCLR @FAC11
       CLR  @FAC13
       DST  @CURLIN,@VAR4     Now start checking process
       CEQ  >2E,V*CURLIN
       BS   USNGZ5
       CEQ  >23,V*CURLIN      Has to be "+" or "-"
       BS   G8527
       CEQ  >2D,V*CURLIN
       BR   G851B
       OR   >02,@FAC11        Set explict sign flag for CNS
G851B  CEQ  >2B,V*CURLIN
       BR   G8527
       OR   >02,@FAC11        Set explict sign flag for CNS
       OR   >04,@FAC11        Set positive sign flag for CN
G8527  CALL ACCNM             Accept first character plus "
       ST   @FAC9,@FAC12      Set up FAC12 for CNS
       CEQ  >2E,V*VAR4        Found decimal point
       BR   G8540
USNGZ5 CLR  @FAC9             Prepare for use as counter of
*                              of # sign after decimal poin
       CALL ACCNM             Accept some more "#"'s
       ST   @FAC9,@FAC13      Set up FAC13 for CNS
       ADD  @FAC12,@FAC9      FAC9 now contains the total n
*                              of "#" sign, decimal point a
*                              maybe a sign bit
       DEC  @FAC9             Exclude the decimal point
G8540  DCEQ >5E5E,V*VAR4      Attempt to decode  ^^
       BR   USNZ55
       DINCT @VAR4            Update address
       DCEQ  >5E5E,V*VAR4
       BR   G8562
       DINCT @VAR4            Update address
       OR   >08,@FAC11        Set E-format bit for CNS
       CEQ  >5E,V*VAR4
       BR   USNZ55
       DINC @VAR4             Update end address
       OR   >10,@FAC11        Set extended E-format bit for
       BR   USNZ55
G8562  DDECT @VAR4            Correct for previous errors
* At this point, CURLIN is pointing at the first item of th
* format, VAR4 is pointing at the character following the i
USNZ55 CHE  >64,@FAC2         Detected numerical argument
       BS   G8596
       CLOG >02,@FAC11        Exclude the sign count
       BS   G8570
       DEC  @FAC9             FAC9 : Number of significant
G8570  CLOG >08,@FAC11        If E-format is used
       BS   G857C
       CGT  >0A,@FAC9         More than 10 significant digi
       BS   ERRIM
       BR   G8581
G857C  CGT  14,@FAC9          More than 14 significant digi
       BS   ERRIM
G8581  OR   >01,@FAC11        Set fixed format output it fo
       XML  XCNS    1          Convert number to fixed forma
* FAC11 points to the beginning of the string after supress
* leading 0's, FAC12 contains the length of the string
       ST   @FAC11,@FAC13     FAC13 now point to beginning
*                              the string
       CLR  @FAC11            Clear high byte
       MOVE @FAC11,*FAC13,V*CURLIN Copy the result string f
*                                   temporary
       DST  @VAR4,@CURLIN     Move pointer behind print fie
       BR   USNGZ4            Continue after printing
G8596  DST  @VAR4,@FAC10      Compute total length
       DSUB @CURLIN,@FAC10
       CH   @FAC11,@FAC7      String exceeds limits
       BR   G85B1
       ST   >2A,@VAR0         Prepare a "*****.." string
G85A4  ST   @VAR0,V*CURLIN    Fill the remainder of field
       DINC @CURLIN           Up to the end
USNZ67 DCEQ @VAR4,@CURLIN     Which is stored in VAR4
       BR   G85A4
       BR   USNGZ4
G85B1  DCZ  @FAC6
       BS   USNZ68
       MOVE @FAC6,V*FAC4,V*CURLIN Copy result string
       DADD @FAC6,@CURLIN     And update address in string
USNZ68 ST   SPACE,@VAR0       Fill remainder with spaces
       BR   USNZ67
USNGZ9 XML  VPOP              Temporary string back out
       ST   @CURLIN+1,@BYTES  Output up to the current
*                              position
       SUB  @FAC5,@BYTES      Create one byte result
       BS   USNZ95            Avoid empty strings
       ST   1,@MNUM+1         Prevent skip if field too sma
       CALL CHKRZ0            Preform all nomal I/O stuff
USNZ95 XML  VPOP              Remove source format string
       CALL CHKEND            Check for end of line exit
       BS   EOLEX             Take end of line exit
       XML  SPEED
       BYTE SYNCHK          * Then it HAS to be a ";"
       BYTE SEMICZ
       CALL CHKEND            Now - must be EOS
       BS   PRSMZ1            Supressed end of record, make
*                              it a pending record
       BR   ERRSYN            SYNTAX ERROR
* Collect string of "#"'s
ACCNM  INC  @FAC9             Update item count
       DINC @VAR4              and item address
       CEQ  >23,V*VAR4        Decode as many "#"'s as
*                              possible
       BS   ACCNM
       RTN                    Return from duty
***********************************************************
*                    INPUT ROUTINE
* First check for file or screen I/O. If file I/O then chec
* for pending output and print that. If screen I/O then
* check for input prompt:
* Next collect the INPUT variable list on the V-stack. Get
* enough input form either file or keyboard, and compare
* types with entries on V-stack. After verification and
* approval, assign the values.
***********************************************************
INPUT  CALL INITKB            Assume keyboard INPUT
       CEQ  NUMBEZ,@CHAT      Might be #0 or #1-255
       BR   G875A
       CALL CHKFN             Check for default #0
       DCZ  @FAC              If luno #0
       BR   G860B
       DST  @PGMPTR,V@INPUTP  Save PGMPTR for "try again"
       DINC V@INPUTP          Pass the ":" for the
*                              "prompt" code handler
*                              later, (using #0 will not
*                              take care the prompt in
*                              INPUT)
       CALL INPUZ2            #0 is equivalent to no #
       BR   INPZ2
G860B  CALL INSU1             Get info about file
* INTERNAL files get special treatment
       CLOG >08,V@FLG(@PABPTR) INTERNAL file
       BS   G86AD
       CZ   V@OFS(@PABPTR)    Fresh start
       BR   G861E
INTRZ0 CALL IOCLZ1            Get a new record through
*                              the DSR
G861E  ST   V@OFS(@PABPTR),@VARA+1 Regain possible offset
       CLR  @VARA             Make that a two byte constant
       DST  V@BUF(@PABPTR),@TEMP5 Get first address
       DADD @VARA,@TEMP5      Compute actual address
*                              within record
INTRZ1 CALL BUG01             Get the symbol table entry
* Above call fixes bug, of the given variable
       XML  VPUSH             And save it on the stack
       DCLR @BYTES            Assume no data available
       CHE  V@CNT(@PABPTR),@VARA+1 Pick up data
       BS   G8643
       ST   V*TEMP5,@BYTES+1  Length byte first
       DINC @TEMP5            Update both actual address
       INC  @VARA+1            and offset
G8643  CEQ  >65,@FAC2         Has to be string variable
       BR   G8650
       DST  @BYTES,@FAC6      Set length of string
       CALL CTMPST            Create temporary string
       BR   G867E
G8650  CEQ  >08,@BYTES+1      * FILE ERROR
       BR   ERRFE
       MOVE @BYTES,V*TEMP5,@FAC  Copy value
       DCZ  @FAC              Watch out for non-scaled stuf
       BS   G867C
       ST   FAC7,@ARG         Test for legal numeric
G8661  CH   99,*ARG           * FILE ERROR
       BS   ERRFE
       DEC  @ARG              Next digit for test
       CEQ  FAC1,@ARG
       BR   G8661
       DST  @FAC,@ARG         Copy in ARG for some testing
       DABS @ARG              Be sure we're positive
* If first byte after expon. byte=0 : incorrect
* normalization has occured : FILE ERROR
* Or >99 : illegal numeric  : FILE ERROR
       DEC  @ARG1             0 would cause underflow here
       CH   98,@ARG1
       BS   ERRFE
       BR   G867E
G867C  DCLR @FAC2             Be sure FAC2 = 0 (no strings)
G867E  DADD @BYTES,@TEMP5     Update address and
       ADD  @BYTES+1,@VARA+1   offset again
       XML  ASSGNV            Assign value to variable
       CLR  V@OFS(@PABPTR)    Undo allocated offsets
       CEQ  COMMAZ,@CHAT
       BR   G86AB
       XML  PGMCHR            Get next text character
       CALL CHKEND            Check for end of statement
       BS   INTRZ2            OK, EOS is fine
       CHE  V@CNT(@PABPTR),@VARA+1
       BS   INTRZ0
       BR   INTRZ1            Still something left
INTRZ2 CHE  V@CNT(@PABPTR),@VARA+1
       BS   G86AB
       ST   @VARA+1,V@OFS(@PABPTR) Save value of offset
G86AB  XML  CONT              And CONTINUE
G86AD  CALL GETVAR            Collect variable list on stac
       DST  @STADDR,@CURLIN   Save it in temp
       DST  CRNBUF,@RAMPTR    Initialize crunch buffer poin
       CLR  @RECLEN           Initialize field counter
       ST   CZREAD,V@COD(@PABPTR) Select READ operation
       CZ   V@OFS(@PABPTR)
       BR   INPZ31
       BR   INPZ3             Adjust for used record usage
G86C6  ST   COMMAZ,V@-1(@RAMPTR) Fake legal separator
INPZ3  CALL IOCLZ1            Get next input record
       CLR  V@OFS(@PABPTR)    Reset offset within record
       CALL RECENT
       ST   V@CNT(@PABPTR),@VARA Get record length
G86DB  CZ   @VARA
       BS   INPZ31
       ADD  OFFSET,V*VARW     Add video offset for normal
       DINC @VARW             Screen-type crunch - proceed
       DEC  @VARA              for entire record
       BR   G86DB
INPZ31 CALL RECENT            Compute actual record entry
       ST   V@CNT(@PABPTR),@VARA+1  Compute end of record
       CLR  @VARA             Make that a double byte
       DADD V@BUF(@PABPTR),@VARA  Add buffer start addr
       DDEC @VARA             Point to last position in rec
       CLR  @VAR6             Assume no values input
       XML  CRUNCH            Scan data fields as in DATA s
       BYTE 1               * Indicate input stmt crunch
       DCZ  @ERRCOD           If some crunch error
       BR   ERRINP
       INC  @VAR6             Get correct # of fields (one
       ADD  @VAR6,@RECLEN     Update # of fields up to now
       CHE  @VAR5,@RECLEN     OK, THAT'S ENOUGH!!!!
       BR   G86C6
       DDECT @PGMPTR          Backup program pointer
       XML  PGMCHR            Re-inspect last token before
       CALL RECENT            Precompute record entry
       CLR  V@OFS(@PABPTR)    Assume no pending record
       CEQ  COMMAZ,@CHAT      Make record pending
       BR   G8752
       CEQ  @VAR5,@RECLEN     Enough left pending
       BS   G8752
       SUB  @VAR5,@RECLEN     Compute remaining # of fields
       SUB  @RECLEN,@VAR6     # of fields used in last reco
INPZ32 CEQ  >82,V*VARW        +OFFSET
       BR   G873A             Skip quoted strings
G872E  DINC @VARW
       CEQ  >82,V*VARW        +OFFSET
       BR   G872E
       DINC @VARW
       BR   INPZ32            Search for Nth data item
G873A  DINC @VARW             Update pointer
       CEQ  >8C,V@-1(@VARW) * ","+OFFSET = >8C
       BR   G873A
       DEC  @VAR6             Commas denote end of field
       BR   INPZ32            Continue until done
       DSUB V@BUF(@PABPTR),@VARW Compute current offset
       ST   @VARW+1,V@OFS(@PABPTR) Store for next round
G8752  ST   @VAR5,@VAR6       Copy # of variables for check
       DST  @CURLIN,@STADDR   Restore from temp
       BR   G8786
G875A  CALL INITKB            Initialize some variables for
       DST  @PGMPTR,V@INPUTP  Save for "try agian" case
       DST  @CCPPTR,V@CPTEMP  Save CCPPTR, RECLEN for "try
*                         Entry point for "try again" case
INPZ33 CALL INSUB1            Put out prompt
INPZ2  CALL GETVAR            Get variable list on V-stack
INPUZ3 CALL INSUB2            Read from the screen
       CLR  @VAR6             Assume no values input
       XML  CRUNCH            Crunch the input line
       BYTE 1               * Indicate input stmt scan
       DST  @CURLIN,@STADDR   Restore from temp
       DCZ  @ERRCOD           If got some crunch error
       BR   WRNINP
       XML  SCROLL            Scroll up after crunching
       ST   3,@XPT            Reset XPT too - pending recor
       INC  @VAR6             # fields = # of commas + 1
       CEQ  @VAR6,@VAR5       # of variables wrong
       BR   WRNINP
* Once we're here, all information should be availiable
* After type verification for input and variables, push
* all value entries on the V-stack.
* VAR6 = VAR5 = number of variables
G8786  DST  @DATA,@CURLIN     Save current DATA pointer
       DST  CRNBUF,@DATA      Get crunch entry
       DST  @VAR4,@MNUM       Get entry in V-stack before P
INPUZ4 DADD 8,@MNUM           Point to first symbol table e
       DST  V*MNUM,@CCPPTR    Get immedediate result
       CALL GETRAM            Get value descriptor from RAM
       CLOG >80,V*CCPPTR      Numerical value
       BR   G87CF
       CALL CHKNUM            Check entered value against n
       BR   INPUZ5            Found error
       CZ   @DSRFLG           Do not check overflow in file
*                              supply machine infinity with
*                              appropriate sign and continu
       BS   INPUZ6
       CZ   V@CSNTP1          Watch out for overflow in scr
       BS   INPUZ6
       DST  @CURLIN,@DATA     Restore DATA pointer
       BR   WRZZ5             Ask for input re-enter
INPUZ5 CZ   @DSRFLG           FILE I/O IS FATAL
       BS   ERRINP
       DST  @CURLIN,@DATA     Restore DATA pointer on error
WRNINP CALL WARNZZ            Go here for simple warnings t
       BYTE 32              * INPUT ERROR - TRY AGAIN
WRZZ5  CALL SCRZ              Scroll the screen and reset C
       DST  V@INPUTP,@PGMPTR  Restore ptr to "prompt" if an
       DST  V@CPTEMP,@CCPPTR  Restore CCPPTR, RECLEN, for t
       DST  @VAR4,@VSPTR      Restore original stack ptr
       BR   INPZ33
G87CF  CALL CHKSTR            Check string input
       BS   INPUZ5            ERROR ... CHECK I/O TYPE
INPUZ6 CALL GETRAM            Get separation character (RAM
       CEQ  COMMAZ,@VAR0+1
       BS   G87E6
       DEC  @VAR6             Has to be end of data
       BR   INPUZ5            If not ... ERROR
       CZ   @VAR0+1
       BR   INPUZ5
       BR   G87EA
G87E6  DEC  @VAR6             Count number of value entries
       BR   INPUZ4            Continue
* Assign cycle - assign values to variables because it resc
* the program line, this code can not be udes for inperativ
* statements , since the crunch buffer get's destroyed on
* input. The rescan is necessary because subscripts should
* evaluated AFTER all previous values have been assigned. i
*        INPUT I,A(I)      with values 2,3
* Should assign value 3 to A(2) !!!!!!!!!
* No error-checking is done here, since types are already
* validated. We might get subscripts out of range though!!!
G87EA  DST  CRNBUF,@DATA      Prepare for input rescan
       DST  @STADDR,@PGMPTR   Restore token pointer for res
       DDEC @PGMPTR           Backup on token
       DST  @VAR4,@VSPTR      Restore original stack pointe
INPZ65 XML  PGMCHR            Get next program characters
       CALL CHKEND            Might have , before EOS
       BS   INPUZ7
       CALL BUG01             Rescan variable name
* Above call fixes bug.       Get correct entry for arrays
       XML  VPUSH             Save on stack for ASSGNV
       CALL GETRAM            Get first token of input valu
       CEQ  STRVAL,@FAC2      Numerical case
       BS   G880F
       CALL CHKNUM            Check for numerical value
       BS   INPZ67            COND should be set (valid num
G880F  CALL CHKSTR            Get the correct string value
       DST  @FAC6,@BYTES      Length for temporary string
       CALL CTMPST            Create temporary string
INPZ67 XML  ASSGNV            Assign value to variable
       CALL GETRAM            Skip separator (already check
       CALL CHKEND            Check for end to statement
       BR   INPZ65            Found it
INPUZ7 DST  @CURLIN,@DATA     Restore DATA pointer
       XML  CONT              Contiue in PARSE
RECENT ST   V@OFS(@PABPTR),@VARW+1  Get record offset
       CLR  @VARW             Double byte value required
       DADD V@BUF(@PABPTR),@VARW   Got it
       RTN                    AND NOW, THE END IS NEAR...
CHKRM  DCH  SCRNBS+29,@CCPADR Not enough room for "?"
       BR   G8840
SCRZ   XML  SCROLL            Scroll one line for "?"
       DST  SCRNBS+2,@CCPADR   and update CCPADR accordingl
G8840  RTN

As you can see supporting this in Assembly would be insanely complicated and take up a ton of space.



#320 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Thu Aug 16, 2018 4:27 AM

Great!  I was think along the same lines for a solution.

I was just hoping I missed a documented piece.

 

I had no Idea how much code it takes in XB to do the USING piece.  That is insane.

 

Thank you!



#321 RXB OFFLINE  

RXB

    River Patroller

  • 3,426 posts
  • Location:Vancouver, Washington, USA

Posted Thu Aug 16, 2018 1:59 PM

Great!  I was think along the same lines for a solution.

I was just hoping I missed a documented piece.

 

I had no Idea how much code it takes in XB to do the USING piece.  That is insane.

 

Thank you!

Yep, and that does not even include the XB command IMAGE

 

(That takes up 4 pages in the XB manual, do not even want post that code...you could imagine the results.)



#322 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Fri Aug 17, 2018 9:48 PM

Here is the latest version of XBGDP. "Frappato" does not have any huge changes, but there are some useful improvements:

 

XB256 and XB have been altered so you can tell whether autosave is active. When it it active there is a light pixel in the center of the cursor. The cursor becomes solid black when autosave is no longer active.
XB256 has been altered so it will try to modify the XB grom starting at >6000. If you have enabled gram at >6000, this can addresses some stability issues that  arise when using cpu overdrive.
XB256HM is gone. Instead, XB256 is modified so you can merge an XB program with the XB256 loader, making a nice neat package.
A bug in XB32 that interfered with garbage collection has been found and fixed. This would only cause trouble if you put the runtime routines in low memory and tested in XB. 
Plus the usual improvements to the docs.
 

Attached Files



#323 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Sat Aug 18, 2018 12:15 PM

great timing...

I had a problem running a compiled xb256 program last night.  Saw this and Boom, compiled and ran fine!

 

Didn't even have a chance to ask another question!  LOL



#324 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • Topic Starter
  • 1,277 posts
  • Location:Lansing, NY, USA

Posted Sat Aug 18, 2018 1:02 PM

great timing...

I had a problem running a compiled xb256 program last night.  Saw this and Boom, compiled and ran fine!

 

Didn't even have a chance to ask another question!  LOL

I'm curious to know what did not work earlier. Were you were putting the runtime routines in low memory and testing in XB? That would probably have failed with the previous version.



#325 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Sat Aug 18, 2018 4:59 PM

I was following all defaults.  So, Low Memory is No by default correct?  And 24K  Also the default.

 

The problem...  It assembled and compiled without errors.

When I executed the -X file, the emulator would make weird noises and hang the emulator.  Forcing me to close the emulator.

 

Tried it twice with the same result.  Then went to bed.  When I got up, saw the new version and gave it a try.

Worked like a charm. 

 

Sorry I cannot offer more info.  I can send you the program if you want to try the same process.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users