Post Reply 
SATURN BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
05-03-2015, 05:50 PM (This post was last modified: 04-21-2023 09:19 AM by HrastProgrammer.)
Post: #1
SATURN BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Note: SATURN BASIC was initially called HRAST BASIC but I decided to rename it because this name suits the interpreter better as it really is the "BASIC for SATURN CPU" and was never planned for any other architecture. This name change happened after the release so I kept "HRAST" in filenames and URLs to avoid breaking the existing links.

***

It makes me very happy to announce the availability of my SATURN BASIC high-level programming language, interpreter and development environment for HP-48G/G+/GX, HP-49G and HP-49G+/50G calculators. This isn't really an ordinary BASIC as used to be on various home and pocket computers. It is inspired by BASIC but in many aspects it is more like Pascal, C, COMAL or Forth (internally). I've been working on it for quite some time and I have now come to the point where it is stable enough to be released to the public for the first time. This is the culmination of my work as far as HP/calculator development is concerned and I must admit that I am very proud of it. The final result is "the BASIC as I always wanted it to be" because I was never really satisfied with the choice of development tools available on HP calculators.

As far as I know, this is the first and only BASIC interpreter made for any HP calculator after HP-71B released in 1983. And this is the first and only BASIC interpreter developed outside Hewlett-Packard for any HP calculator ever. Those facts make me even more proud and happy Smile

The first version was SATURN BASIC 32K because it should work on the basic HP-48G with 32K RAM only and after installing the emulator you can still (although barely) allocate a reasonable 8K of RAM for BASIC program and data. The feature set is fixed and no new features will be implemented for 32K version because I want it to stay under 20K. The final version is SATURN BASIC 48K which needs at least 48K of free RAM for normal work. Although I consider 48K version finished as well, there are still a few non-essential things left to be implemented if/when time permits.

Three main goals during the development were to make it as powerful as possible, to make it as fast as possible and to use as little memory as possible. Those goals don't usually go very well together so every time I had to choose between speed and memory - I choosed speed. Furthermore, I wanted everything to be limited by the available memory only - there is no fixed expression stack, no fixed GOSUB/FOR/NEXT and PROC/FUNC stack, expressions can be as complex as you want, you can call subprograms/procedures/functions as deeply as you want, you can have as many nested control structures as you want, etc, etc. This system is very complex but works great and the result is very powerful and fast BASIC interpreter, exceeding the speed and feature-set of even the most powerful home computers like, for example, Acorn BBC B which is well known for its great and very fast BASIC. And it is definitely much faster and much more powerful than all other BASICs on pocket computers and calculators. I made a lot of benchmarks and I will present some results here. The first benchmark is "8-Queens" problem as described on the following site:

http://www.hpmuseum.org/cgi-sys/cgiwrap/...i?read=700

SATURN BASIC running on HP-48GX finishes this benchmark in 16.4 seconds.
SATURN BASIC running on HP-49G+ finishes this benchmark in 7.2 seconds.

This makes it much faster than all other BASICs on this page except QBasic, Power, Turbo and Quick BASIC running on HP-200LX. The benchmark program is here, so you can get a picture how an optimized program for SATURN BASIC looks like (various strange details from this program will be explained throughout the manual):

Code:

CALL QUEEN,8
PROC QUEEN(INTEGER N) INTEGER A[N+1],D,S=1,X,Y A[1]=N
FOR X=2 TO N S> A[X]=N FOR Y=X-1 D=A[X]-A[Y]
IF NOT D OR X-Y=ABS D@ A[X]< WHILE NOT A[X]@ X< A[X]< ENDWHILE S> Y=X
NEXT NEXT ? A[1],A[2],A[3] ? A[4],A[5],A[6] ? A[7],A[8]

A little slower but more clear version of the same benchmark:

Code:

CALL QUEEN,8
PROC QUEEN(INTEGER N)
INTEGER A[N+1],D,S=1,X,Y: A[1]=N
FOR X=2 TO N: S=S+1: A[X]=N
FOR Y=X-1: D=A[X]-A[Y]
IF D=0 OR X-Y=ABS D@ {
_ A[X]=A[X]-1
_ WHILE NOT A[X]@ X=X-1: A[X]=A[X]-1: ENDWHILE
_ S=S+1: Y=X
}
NEXT: NEXT
? A[1],A[2],A[3]
? A[4],A[5],A[6]
? A[7],A[8]

I also executed all PCW home computer benchmarks (slightly modified for SATURN BASIC):

http://www.geocities.ws/peterochocki/com...pcwbm.html
http://www.geocities.ws/peterochocki/com...lcbms.html

REAL results for BM1..BM8 on HP-48GX are: 0.24s, 2.78s, 9.09s, 8.82s, 9.33s, 11.85s, 19.75s, 27.43s, Average = 11.16s

INTEGER results for BM1..BM8 on HP-48GX are: 0.24s, 1.78s, 5.58s, 5.64s, 6.14s, 8.66s, 15.83s, 26.64s, Average = 8.81s

REAL results for BM1..BM8 on HP-49G+ are: 0.07s, 1.97s, 6.03s, 6.08s, 6.41s, 7.75s, 11.70s, 17.92s, Average = 7.24s

INTEGER results for BM1..BM8 on HP-49G+ are: 0.07s, 0.73s, 2.37s, 2.49s, 2.81s, 3.99s, 7.49s, 16.83s, Average = 4.60s

Not bad for an ancient 4-bit CPU and the emulation of an ancient 4-bit CPU Smile

One of the reasons for such performance is because I avoided dynamic/heap memory allocation, fragmentation and garbage collection at all costs. Dynamic memory allocation needs copying/moving and copying/moving kills speed and performance. I hate garbage collectors, they are totally unpredictable. And if you don't leave garbage than you don't have to collect it, do you? That's why SATURN BASIC works a lot like FORTH internally. Actually, at first I intended to develop SATURN FORTH but I decided not to do it because I concluded that a more high-level language would be much more appropriate for practical use. FORTH is a great language but a little cumbersome to work with various data types: floating point numbers, complex numbers, strings, arrays, matrices, etc. But a lot of code I developed for SATURN FORTH made it into SATURN BASIC.

SATURN BASIC has no connection to the so-called HP BASIC available in HP-49G and HP-49G+/50G which is not BASIC at all, just an awkward algebraic wrapper over UserRPL. Furthermore, the interpreter doesn't use RPL operating system except some SysRPL code during the initialization and machine language math routines - there is really no need to reinvent the wheel here.

Please, keep in mind that SATURN BASIC is not a free software. I put a lot of my own time, knowledge and energy into this project, so I am expecting some compensation for those efforts. That's why I am releasing SATURN BASIC as donation-ware. It is not crippled or limited in any way and you can use it freely for 32 days. If you decide to use it after 32 days you have to make a donation in EUR to my PayPal account (it is the same as my e-mail address). This amount covers the installation of both 32K and 48K versions on as many calculators as you want. It doesn't cover commercial or group usage (a single donation for the whole classroom, for example) - contact me by mail and we'll arrange something. SATURN BASIC is not a commercial product and I don't have a business which can sell it to you. So, I accept PayPal donations only - if this is not OK with you then, please, don't donate and don't use SATURN BASIC.

As with all my software, SATURN BASIC has that "HrastProgrammer's" way-of-working and look-and-feel which is not appealing to everyone because I developed it for myself in the first place. The feature set is fixed and I will not change anything in this regard, no matter how some features could look strange or quirky at first sight. I am sharing SATURN BASIC in the current form because such development tool/environment didn't exist before and it could possibly be helpful to someone else as well. But, if you don't like it or it doesn't work for you for whatever reason and don't want to use it after (or before) 32 days then just delete it, simple as that. Donations cannot be returned so think twice before donating. I didn't protect this software in any way and I will rely on the honesty of the users only Smile

OK, SATURN BASIC download is here:

32K version ... https://www.hrastprogrammer.com/hrastbas/hrast32k.zip

48K version ... https://www.hrastprogrammer.com/hrastbas/hrast48k.zip

The installation is very simple and is the same for all calculators. First, send the appropriate HRAST file (HRAST48, HRAST49 or HRAST50) containing the interpreter to the calculator and store it to a variable. Then send the appropriate RAMH file (RAMH48 for HP-48G/G+/GX and RAMH49 for HP-49G and HP-49G+/50G) to the calculator and store it to (another) variable. Put the number of BASIC kilobytes (BTW, no "kibibytes" and similar crap, please) needed and execute RAMH. This will create SATURN BASIC environment in form of an character string object of the required size (for example, 8 RAMH to create an 8K environment, minimum is 2K). Store this environment to the HRAM variable and start the interpreter by executing the variable where HRAST file has been stored. The interpreter will look for the HRAM variable in the current directory and (if it finds one and it was not already initialized) will initialize it and continue execution. If it doesn't find the HRAM variable an "Object Not in Port" error will be reported and the interpreter will abort execution.

Please, note that bugs are inevitable in such a complex piece of software, especially in such early state and under various "borderline" conditions, so watch for them and report them to me if you find any. I just hope I didn't make such a terrible mistakes like typing x=18.9 on Atari ST BASIC causing "function not yet done System error #%N, please restart" error ... So far, The interpreter has been tested on the following calculators: HP-48GX ROM version R, HP-49G ROM version 1.19-5, HP-49G+ ROM versions 1.23/2.15 and HP-50G ROM version 2.15. If you have problems running on other ROM versions report them to me as well and I will investigate. I reserve the right to mark a particular bug as "feature" or "by design" if I judge that something isn't really a bug or even if it is a bug but could somehow be useful. I also reserve the right to fix some bugs in 48K version only, due to the lack of space in 32K version.

In order to save space the interpreter is using an unsupported ROM font table entry on HP-48G/G+/GX. On HP-49G and HP-49G+/50G the system font table stored in RAM is used but I don't have any experience with alternate fonts on those calculators. So, in both cases there is a slight possibility that something can go wrong with different ROM versions or different calculator configurations. If something like this occurs then, please, report this to me.

The manual is here:

https://www.hrastprogrammer.com/hrastbas/SATURN BASIC.pdf

It still leaves a few things to desire and I will update it when needed. This is a reference manual, not a book teaching BASIC language - the reader is expected to have a good programming knowledge in order to use SATURN BASIC and to understand the content of this manual. Please, report all errors to me so I can correct them. Also note that english is not my native language, so I will appreciate very much all corrections in regard to grammar, spelling, etc.

Enjoy Smile

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-03-2015, 06:22 PM
Post: #2
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Thanks a lot Ž!

Chapeau, once more.

Now let's take that B&W 48GX and give this a try... ;)

Greetings,
    Massimo

-+×÷ ↔ left is right and right is wrong
Visit this user's website Find all posts by this user
Quote this message in a reply
05-03-2015, 08:27 PM
Post: #3
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Well, I didn't expect to do anything in Basic again but now I'll have to have a look. After all, the way Massimo praises your programming skills & the trail of programmes you've left over the years have convinced me.
Find all posts by this user
Quote this message in a reply
05-03-2015, 09:30 PM
Post: #4
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
This is really great. I have just been getting back into basic after a long absence. I tried to install it on my 50G but it didn't work. Then I read your directions again and I was rewarded with the BASIC prompt!

Thanks a lot. Your PayPal money is on its way!
Find all posts by this user
Quote this message in a reply
05-04-2015, 05:28 AM (This post was last modified: 05-05-2022 11:35 AM by HrastProgrammer.)
Post: #5
RE: HRAST-BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Thank you very much Smile

Although I developed HRAST-BASIC for myself in the first place, it is always a great pleasure to see when other people start to use my software.

Among the other things, it puts a new life into my crappy CN33* HP-49G+ which is almost unusable for any real work because of missing keystrokes, no matter if old or new firmware is installed etc. But with keyboard handling code I developed for my emulators I can now actually work without any missing keystrokes and without looking at the screen to confirm that a key has been registered.

I have a long term plans for this because I am using it by myself as well. The current priority is to exterminate as much bugs as possible. After that a 32K version will be left as it is, so it can be used on HP-48G, and I will start working on 48K version. The first thing I will develop would be the support for more programs in memory because this is, more or less, essential for serious work but didn't fit into 32K version because I wanted it to stay under 20K. Then I will proceed with other features as described in chapter 9 of the manual ...

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-04-2015, 05:58 AM
Post: #6
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Congratulations, you're definitely a very prolific and knowledgeable developer :-).
Haven't tried it yet but already have a couple of questions:
- does this basic interact with objects or is it running as a separate shell?
- what is the benefit of basic vs rpl? Asking this question because one of the reason I preferred the 50g to the prime was precisely that I found rpl more convenient than basic for a calculator.
Find all posts by this user
Quote this message in a reply
05-04-2015, 06:43 AM (This post was last modified: 05-05-2022 11:36 AM by HrastProgrammer.)
Post: #7
RE: HRAST-BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Thanks!

It has it's own environment and doesn't interact with RPL in any way, it's completely independent system (which I will probably rewrite for some other architectures in the future, like x86 or ARM). I wanted it to be as fast as possible and RPL doesn't really fit into this. The only ROM-thing I currently use are low-level math routines to save space (although I plan to use high-level matrix routines for matrix operations in future 48K version).

BASIC vs. RPL? Well, it's on you to decide Smile I never push my software over anything else and never try to convince anyone that my software is better than something else. I just develop something (usually for myself and because I enjoy it) and make it available so anyone can make some use out of it and decide if it works for him or not. What works for me surely won't work for everyone, that's a fact of life.

I never really gelled with RPL and I always wanted something more convenient and classic-like for everyday work but never really haven't enough time to do it until now. Furthermore, I never liked that slow RPL editor etc. But I liked the interactive interpreter nature of the RPL system because edit-compile cycle doesn't really work for me as far as calculators are concerned. So, I decided to take all features I like and make my own interpreter.

Another advantage is speed because it is generally much faster than UserRPL. Look at that 8-queens benchmark ... 16.6 seconds vs. 54 seconds on HP-49G or 7.2 seconds vs. 22 seconds on HP-49G+/50G speaks for itself.

And it is much more convenient for me to write:

(2*6+11+^(6+8*(100/50+3)-7-35)/2+100+(2+4*^3-18)/4+(100*10-^8)-44/11)/12

... instead of something like that (SysRPL example):

% 2 % 6 %* % 11 %+ % 100 % 50 %/ % 3 %+ % 8 %* % 6 %+ % 7 %- % 35 %- DUP %* % 2 %/ %+
% 100 %+
% 3 DUP %* % 4 %* % 2 %+ % 18 %- % 4 %/ %+
% 100 % 10 %* % 8 DUP %* %- % 44 % 11 %/ %- %+
% 12 %/ DROP

(BTW, I know I can use algebraic expressions in most cases but it just doesn't seem native to use them with RPL)

And HRAST-BASIC programs consume less memory than RPL because internal tokens are 1 byte instead of 2.5 bytes words.

But, again, it's just on you to decide Wink

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-05-2015, 01:01 PM
Post: #8
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-04-2015 06:43 AM)HrastProgrammer Wrote:  And it is much more convenient for me to write:

(2*6+11+^(6+8*(100/50+3)-7-35)/2+100+(2+4*^3-18)/4+(100*10-^8)-44/11)/12

Off topic: Please forgive my ignorance, but why would anyone need to write something like the above?

I really appreciate your efforts, but isn't BASIC a step back in time comparing it to RPL?

Best regards,
Find all posts by this user
Quote this message in a reply
05-05-2015, 01:20 PM
Post: #9
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-05-2015 01:01 PM)RMollov Wrote:  Off topic: Please forgive my ignorance, but why would anyone need to write something like the above?

I really appreciate your efforts, but isn't BASIC a step back in time comparing it to RPL?

Sorry, I cannot answer your question, I can only answer questions regarding the interpreter itself - technical questions, usage, bug reports, etc.

I am a developer, I presented my work here, I said what I had to say about it (in the first post and in the manual), and I am certainly not forcing anyone to use it, as I never did with any of my software presented on MoHPC during the years.

It's up to you to decide if it is a step back or forward or whatever.

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-05-2015, 01:31 PM
Post: #10
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-04-2015 06:43 AM)HrastProgrammer Wrote:  And HRAST BASIC programs consume much less memory than RPL because internal tokens are 1 byte instead of 2.5 bytes words.

Cool, reminds me also of BASIC in the ZX81 and Spectrum, where ASCII characters above 127 were the actual BASIC commands. It's extremely compact and also speed-efficient. Good design decision.

Claudio.
Find all posts by this user
Quote this message in a reply
05-05-2015, 01:54 PM
Post: #11
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-05-2015 01:31 PM)Claudio L. Wrote:  Cool, reminds me also of BASIC in the ZX81 and Spectrum, where ASCII characters above 127 were the actual BASIC commands. It's extremely compact and also speed-efficient. Good design decision.

Claudio.

Yes, statement tokens have bit 7 set but function tokens, operators and variables haven't, so the interpreter can easily distinguish between the beginning of an statement and the expression(s) as part of the statement. This speeds up many things a lot. And that's why a colon separator isn't needed in most cases (but the programmer is responsible to put it where needed). I really like those features and missed them until now ...

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-06-2015, 05:45 AM (This post was last modified: 05-06-2015 07:46 AM by HrastProgrammer.)
Post: #12
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
New 32K version uploaded with one critical bugfix (possible crash/freeze if HRAST48/HRAST49/HRAST50 code object has been moved around in memory, due to the bug in my internal code relocator) and some optimizations (~180 bytes saved).

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-06-2015, 11:35 AM
Post: #13
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Very nice project and interesting optimization capabilities. I've updated the list with the HRAST BASIC results. Thank you for testing.

Calculator Benchmark
Find all posts by this user
Quote this message in a reply
05-06-2015, 12:22 PM
Post: #14
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
Thank you very much Smile

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-06-2015, 01:26 PM
Post: #15
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-06-2015 11:35 AM)xerxes Wrote:  Very nice project and interesting optimization capabilities. I've updated the list with the HRAST BASIC results. Thank you for testing.

He also deserves credit not just for a relatively fast implementation, but for the shortest solution of all: only 5 lines of code!
Talk about code compactness.
Find all posts by this user
Quote this message in a reply
05-06-2015, 01:56 PM
Post: #16
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-06-2015 01:26 PM)Claudio L. Wrote:  He also deserves credit not just for a relatively fast implementation

Giving that it is an interpreter it couldn't go faster without overcomplicating the tokenizer and using much more memory, and/or without removing various internal checks (free memory, for example) thus reducing stability.

(05-06-2015 01:26 PM)Claudio L. Wrote:  but for the shortest solution of all: only 5 lines of code!
Talk about code compactness.

Smile

I could even make it 4-liner because lines 3 and 4 can be concatenated. But this would be overkill.

The size of this program is 263 bytes. Without display statements at the end it is 207 bytes. And if we short the procedure name to 1 letter it is 197 bytes. I think this is really great size/speed ratio for a high-level interpreter.

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-06-2015, 02:13 PM
Post: #17
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-06-2015 01:56 PM)HrastProgrammer Wrote:  I think this is really great size/speed ratio for a high-level interpreter.

Gene: I certainly agree with that! Kudos!
Find all posts by this user
Quote this message in a reply
05-06-2015, 03:01 PM (This post was last modified: 05-06-2015 03:04 PM by HrastProgrammer.)
Post: #18
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
(05-06-2015 02:13 PM)Gene Wrote:  Gene: I certainly agree with that! Kudos!

Not that a few bytes mean anything these days Smile

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-08-2015, 01:48 PM (This post was last modified: 05-08-2015 02:40 PM by HrastProgrammer.)
Post: #19
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
I started to work on the 48K version and the first iteration is ready for download:

http://www.hrastprogrammer.com/hrastbas/hrast48k.zip

A few highlights:

(*) The ability to have an unlimited number of programs in memory.
(*) Additional program mode editor commands: swap lines, duplicate line and merge lines.
(*) New statements for multiple programs support (PROGRAM, NEW, NAME, PURGE and CAT), RANDOM statement, SHF function and alternate STR function (which returns uppercase string if called with a string argument).

Please, refer to the updated manual for more info on new statements and functions.

48K version can use HRAM file created with 32K version but vice versa is not recommended.

For some stupid reason the name of the default program in 32K version was reversed ("MARGORP") so execute NAME to correct this after you start 48K version on the old HRAM file.

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
05-27-2015, 05:11 PM (This post was last modified: 06-11-2015 10:41 AM by HrastProgrammer.)
Post: #20
RE: HRAST BASIC for HP-48G/G+/GX, HP-49G and HP-49G+/50G
New 48K version 1.5 has been uploaded.

Highlights compared to the previous version:

(*) MAT statement for matrix operations
(*) CLOCK/DATE/TIME functions
(*) TIMER & SLEEP statements
(*) LOAD/SAVE statements
(*) ARRAY statement
(*) RANDOM statement
(*) SHF function
(*) TEN renamed to ALOG
+ a few bugfixes.

More info in the manual.

Some bugfixes in 32K version as well. Both 32K and 48K versions should now work correctly with all 8-pixels high user fonts on HP-49G and HP-49G+/50G.

Matrix support is quite experimental because I developed internal RPL <=> BASIC interpreter interface so I could use various SysRPL matrix routines, etc. Space saving and the development speed were the main keys here. This internal RPL interface creates it's own RPL environment inside free BASIC memory, so the free memory left to the HP OS is not important, only free memory inside HRAM is what matters.

https://www.hrastprogrammer.com/hrastwood/
https://hrastprogrammer.bandcamp.com/
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)