Recent Posts

Pages: 1 2 [3] 4 5 ... 10
21
Scripting Languages / Re: ScriptBasic Windows 32
« Last post by John on May 07, 2020, 10:58:01 PM »
DLLC is an extension module created by Charles Pegge in Oxygen Basic which he is the author of. Oxygen Basic is a JIT BASIC (like) compiler that generates ASM source. O2 is written in itself.

The DLLC extension module provides the following features.

  • Dynamic FF! definition and calling of DLL libraries.
  • Access and define C structures.
  • Access, create and translate OLE strings (BSTR) and wide strings (unicode)
  • Dynamically create virtual (DLL) functions from ScriptBasic with O2 JIT compiler.
  • Low level COM / GUID  functions.

I plan to demonstrate a few of DLLC's features in upcoming posts to this thread.

dllc.sbi
Code: Script BASIC
  1. '  supported types:
  2. '  b bool
  3. '  c char
  4. '  d double precision float
  5. '  f float
  6. '  h handle
  7. '  i integer (32bit)
  8. '  p pointer
  9. '  q quad (64bit) integer
  10. '  s short (16bit) integer
  11. '  z null terminated string
  12.  
  13. '  supported calling conventions
  14. '  cdecl
  15. '  stdcall
  16.  
  17. '  '*' signifies pass variable by reference, otherwise by value
  18.  
  19.  
  20.   'DIAGNOSTICS  
  21.  declare sub dllhook alias "dllhook" lib "DLLC"
  22.   declare sub dllshow alias "dllshow" lib "DLLC"
  23.   declare sub dllreco alias "dllreco" lib "DLLC"
  24.   declare sub dllsecs alias "dllsecs" lib "DLLC"
  25.   declare sub dllerrc alias "dllerrc" lib "DLLC"
  26.   declare sub dllerrs alias "dllerrs" lib "DLLC"
  27.  
  28.  'CONSOLE
  29.  declare sub dllcnsl alias "dllcnsl" lib "DLLC"
  30.   declare sub dlllnpt alias "dlllnpt" lib "DLLC"
  31.   declare sub dllprnt alias "dllprnt" lib "DLLC"
  32.   declare sub dllcmnd alias "dllcmnd" lib "DLLC"
  33.   'DLL LINKAGE
  34.  declare sub dllfile alias "dllfile" lib "DLLC"
  35.   declare sub dllproc alias "dllproc" lib "DLLC"
  36.   'DLL CALLS
  37.  declare sub dllmeth alias "dllmeth" lib "DLLC"
  38.   declare sub dllcall alias "dllcall" lib "DLLC"
  39.   declare sub dllcald alias "dllcald" lib "DLLC"
  40.   declare sub dllcalt alias "dllcalt" lib "DLLC"
  41.   declare sub dllcobj alias "dllcobj" lib "DLLC"
  42.   declare sub dllcobt alias "dllcobt" lib "DLLC"
  43.   declare sub dllclbk alias "dllclbk" lib "DLLC"
  44.   'SBCALLS
  45.  declare sub dllprog alias "dllprog" lib "dllc"
  46.   declare sub dllendp alias "dllendp" lib "dllc"
  47.   declare sub dlltran alias "dlltran" lib "DLLC"
  48.   'CHANNELS AND THREADS
  49.  declare sub dllidat alias "dllidat" lib "DLLC"
  50.   declare sub dllodat alias "dllodat" lib "DLLC"
  51.   declare sub dllclos alias "dllclos" lib "DLLC"
  52.   declare sub dllwait alias "dllwait" lib "DLLC"
  53.   'DATA
  54.  declare sub dllsptr alias "dllsptr" lib "DLLC"
  55.   declare sub dlltype alias "dlltype" lib "DLLC"
  56.   declare sub dlldimv alias "dlldimv" lib "DLLC"
  57.   declare sub dllfill alias "dllfill" lib "DLLC"
  58.   declare sub dllgetm alias "dllgetm" lib "DLLC"
  59.   declare sub dllputm alias "dllputm" lib "DLLC"
  60.   declare sub dllptrm alias "dllptrm" lib "DLLC"
  61.   declare sub dllfrem alias "dllfrem" lib "DLLC"
  62.   'STRINGS / GUIDS
  63.  declare sub dlldelo alias "dlldelo" lib "DLLC"
  64.   declare sub dllostr alias "dllostr" lib "DLLC"
  65.   declare sub dllzstr alias "dllzstr" lib "DLLC"
  66.   declare sub dllastr alias "dllastr" lib "DLLC"
  67.   declare sub dllwstr alias "dllwstr" lib "DLLC"
  68.   declare sub dllcast alias "dllcast" lib "DLLC"
  69.   declare sub dllguid alias "dllguid" lib "DLLC"
  70.  
  71. '  current limits:
  72. '  ===============
  73.  
  74. '  32   parameters per procedure
  75. '  2048 entities (total of libs+procs+types+vars)
  76.  
22
Scripting Languages / Re: ScriptBasic Windows 32
« Last post by John on May 07, 2020, 04:59:42 PM »


This is the Mini XML (mxml) library static linked to the extension  module. AIR's latest version.

MXML Include
Code: Script BASIC
  1. module mxml
  2.  
  3. declare sub     ::LoadDoc       alias "LoadDoc"       lib "mxml"
  4. declare sub     ::GetNext       alias "GetNext"       lib "mxml"
  5. declare sub     ::GetChild      alias "GetChild"      lib "mxml"
  6. declare sub     ::GetNodeValue  alias "GetNodeValue"  lib "mxml"
  7. declare sub     ::GetNode       alias "GetNode"       lib "mxml"
  8. declare sub     ::SaveDoc       alias "SaveDoc"       lib "mxml"
  9. declare sub     ::NewDoc        alias "NewDoc"        lib "mxml"
  10. declare sub     ::GetProperty   alias "GetProperty"   lib "mxml"
  11. declare sub     ::FreeDoc       alias "FreeDoc"       lib "mxml"
  12.  
  13. end module
  14.  


Code: Script BASIC
  1. include mxml.sbi
  2.  
  3. filename = "mxml_demo.xml"
  4.  
  5. doc = mxml::LoadDoc(filename)
  6.  
  7. node =  mxml::GetNode(doc,"/stufflist/stuff_test")
  8. if node then print "Test1: ", mxml::GetNodeValue(node),"\n"
  9.  
  10. node =  mxml::GetNode(doc,"/stufflist/stuff_test2")
  11. if (node) then print "Test2: ", mxml::GetNodeValue(node),"\n\n"
  12.  
  13.  
  14. node = mxml::GetNode(doc,"/stufflist/stuff_test3/painting/img")
  15. if node then
  16.         print "Image: ", mxml::GetProperty(node,"src"), "\n"
  17.         print "Alt Image: ", mxml::GetProperty(node,"alt"), "\n\n"
  18. endif
  19.  
  20.  
  21. node = mxml::GetNode(doc,"/stufflist/books")
  22. child = mxml::GetChild(node)
  23.  
  24. while child
  25.         node = mxml::GetNode(child,"id")
  26.         if node then print "ID = ", mxml::GetNodeValue(node),"\n"
  27.         node = mxml::GetNode(child,"name")
  28.         if node then print "Name = ", mxml::GetNodeValue(node),"\n"
  29.  
  30.         child = mxml::GetNext(child)
  31. wend
  32.  
  33.  
  34. if doc then mxml::FreeDoc(doc)
  35.  

mxml_demo.xml
Code: XML
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2.  
  3.  
  4. <stufflist>
  5.         <stuff_test>This is a test!</stuff_test>
  6.         <stuff_test2>And this is another test!</stuff_test2>
  7.         <stuff_test3>
  8.                 <painting>
  9.                         <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
  10.                         <caption>This is Raphael's "Foligno" Madonna, painted in
  11.                                 <date>1511</date>.
  12.                         </caption>
  13.                 </painting>
  14.         </stuff_test3>
  15.         <books>
  16.     <book>
  17.         <id>1</id>
  18.         <name>Hello, world!</name>
  19.     </book>
  20.     <book>
  21.         <id>2</id>
  22.         <name>Hello, China!</name>
  23.     </book>
  24.         </books>
  25. </stufflist>
  26.  

Output

C:\ScriptBASIC\examples>sbc mxml_demo.sb
Test1: This is a test!
Test2: And this is another test!

Image: madonna.jpg
Alt Image: Foligno Madonna, by Raphael

ID = 1
Name = Hello, world!
ID = 2
Name = Hello, China!

C:\ScriptBASIC\examples>

23
Scripting Languages / Re: ScriptBasic Windows 32
« Last post by John on May 06, 2020, 07:17:55 PM »
I was able to get the json extension module AIR created for Linux working on Windows 10.

JSON Include
Code: Script BASIC
  1. module json
  2.  
  3. ' FUNCTION DECLARATIONS
  4. declare sub     ::loadfile alias "loadfile" lib "json"
  5. declare sub     ::loadstr  alias "loadstr"  lib "json"
  6. declare sub     ::save     alias "save"     lib "json"
  7. declare sub     ::count    alias "count"    lib "json"
  8. declare sub     ::object   alias "object"   lib "json"
  9. declare sub     ::get      alias "get"      lib "json"
  10. declare sub     ::new      alias "new"      lib "json"
  11. declare sub     ::settext  alias "settext"  lib "json"
  12. declare sub     ::setnum   alias "setnum"   lib "json"
  13.  
  14. end module
  15.  


Code: Script BASIC
  1. ' SB JSON Create Entries
  2.  
  3. import json.sbi
  4.  
  5. root = json::New()
  6. json::SetText(root,"client1.name","Joe Blow")
  7. json::SetNum(root,"client1.age", 56)
  8. json::SetText(root,"client1.address.city","Tarrytown")
  9. json::SetText(root,"client1.address.state","NY")
  10. json::SetText(root,"client1.address.zip","10891")
  11.  
  12. json::SetText(root,"client2.name","John Smith")
  13. json::SetNum(root,"client2.age",86)
  14. json::SetText(root,"client2.address.city","Cupertino")
  15. json::SetText(root,"client2.address.state","CA")
  16. json::SetText(root,"client2.address.zip","N/A")
  17. json::Save("root.json")
  18.  

Output
Code: Text
  1. {
  2.     "client1": {
  3.         "name": "Joe Blow",
  4.         "age": 56,
  5.         "address": {
  6.             "city": "Tarrytown",
  7.             "state": "NY",
  8.             "zip": "10891"
  9.         }
  10.     },
  11.     "client2": {
  12.         "name": "John Smith",
  13.         "age": 86,
  14.         "address": {
  15.             "city": "Cupertino",
  16.             "state": "CA",
  17.             "zip": "N\/A"
  18.         }
  19.     }
  20. }
  21.  

Parse the above generated root.json file.

Code: Script BASIC
  1. ' SB READ IN CREATED JSON
  2.  
  3. import json.sbi
  4.  
  5. jObject = json::loadfile("root.json")
  6. for i = 0 to json::count(jObject)-1
  7.     obj = json::object(jObject,i)
  8.     print string(40,"-"),"\n"
  9.     print json::Get(obj,"name"),"\n"
  10.     print json::Get(obj,"age"),"\n"
  11.     print json::Get(obj,"address.city"),"\n"
  12.     print json::Get(obj,"address.state"),"\n"
  13.     print json::Get(obj,"address.zip"),"\n"
  14. next
  15. print string(40,"-"),"\n"
  16.  

Output

C:\ScriptBASIC\examples>sbc parse.sb
----------------------------------------
Joe Blow
56
Tarrytown
NY
10891
----------------------------------------
John Smith
86
Cupertino
CA
N/A
----------------------------------------

C:\ScriptBASIC\examples>

24
Scripting Languages / Re: ScriptBasic Windows 32
« Last post by John on May 06, 2020, 01:52:36 PM »
GMP
ŤArithmetic without limitationsť


I was able to get the gmp3 (large number library) working on Windows 10.

GMP3 Include
Code: Script BASIC
  1. module gmp3
  2.  
  3. declare sub     ::init     alias "init"     lib "gmp3"
  4. declare sub     ::init_set alias "init_set" lib "gmp3"
  5. declare sub     ::mul      alias "mul"      lib "gmp3"
  6. declare sub     ::mul_si   alias "mul_si"   lib "gmp3"
  7. declare sub     ::add      alias "add"      lib "gmp3"
  8. declare sub     ::sub      alias "sub"      lib "gmp3"
  9. declare sub     ::divide   alias "divide"   lib "gmp3"
  10.  
  11. end module
  12.  


Code: Script BASIC
  1. DECLARE SUB BI_ADD  ALIAS  "add"     LIB "gmp3"
  2. DECLARE SUB BI_SUB  ALIAS  "sub"     LIB "gmp3"
  3. DECLARE SUB BI_MUL  ALIAS  "mul"     LIB "gmp3"
  4. DECLARE SUB BI_DIV  ALIAS  "divide"  LIB "gmp3"
  5.  
  6. a = "10000000000"
  7. b = "9999999999"
  8.  
  9. PRINT "ADD: ", BI_ADD(a,b),"\n"
  10. PRINT "SUB: ", BI_SUB(a,b),"\n"
  11. PRINT "MUL: ", BI_MUL(a,b),"\n"
  12. PRINT "DIV: ", BI_DIV(a,2),"\n"
  13.  


C:\ScriptBASIC\examples>sbc gmp3test.sb
ADD: 19999999999
SUB: 1
MUL: 99999999990000000000
DIV: 5000000000

C:\ScriptBASIC\examples>


ScriptBasic supports large strings as well native.

Code: Script BASIC
  1. a = STRING(1234567890,CHR(0))
  2.            
  3. PRINT LEN(a),"\n"
  4.  


C:\ScriptBASIC\examples>sbc bigstr.sb
1234567890

C:\ScriptBASIC\examples>

25
Scripting Languages / ScriptBasic Windows 32
« Last post by John on May 06, 2020, 10:24:07 AM »
I'm in the process of building a new ScriptBasic Windows 32 release using TDM-GCC-32 9.20 and an enhanced makefile AIR initially created. I have eliminated scriba.exe and created sbc.exe (console) and sbw.exe (Windows) which both support Windows styles if running IUP forms or VB6 OCX forms.

I'm working on porting GMP3, MXML and the new JSON extension modules to Windows. DLLC will also be included. I will be using the Inno installer for the release. I will be setting up a new project in the sandbox for sbwin-dev.

I hope to include a set of examples showing how to use each of the extension modules.

I had the opportunity to work with Postgres SQL with a project I'm working on with a client. I really like the DB Server and would like to update the existing PSQL extension module to work with the current release. I'm not planning on including it in this next release but will offer it as an addon when updated and tested.
26
Open Forum / Re: RaspberryBASIC.org Forum
« Last post by John on April 19, 2020, 01:45:50 AM »
I was able to connect to my RPi 4B running Ubuntu 64 ARM via WIFI using UltraEdit from my Windows 10 laptop. I had a SSH console and SFTP load/save ability. Seamless operation.

Thanks again for the hint.
27
Interpreters / Pauls working BASIC's
« Last post by paulwratt on April 18, 2020, 11:58:22 PM »
These are not specific to RPi, and I use them (Other BASIC Interpreters):

bas-2.5 (BAS 2.4 with fixes and some extensions BIN$ AUTOEXEC.BAS)
bas-2.5-pw (BAS 2.4 with above patches and some extensions, CHAIN MERGE 256 color)
SDL2_Basic (vector graphics, standalone, not scripting)
pistol_Basic (SDL_Basic from above SDL 1.2 branch + GPIO)

they all work at console and in (X-)Windows terminal

the post at the link above has a breakdown, repo links,and others I know also work (used them in the past)

I compile for armv6, armv7, aarch64, 68000 (AtariST), 68040 (ARAnyM), and 68020-060 (MiNT)

Cheers

Paul
28
NOT BASIC / cint C/C++ Interpreter
« Last post by paulwratt on April 18, 2020, 11:45:53 PM »
Thought I would repost this here (from http://raspberrybasic.org), because its the only repo that I know of, and its not RPi specifc

I have an online copy of the last known working version of cint C/C++ Interpreter, pulled from within CERN "root-5.34.00-patches", which as of v6.0.0 now uses cling.

https://github.com/paulwratt/cint-5.34.00

patches welcome

Cheers

Paul
29
Scripting Languages / Re: Scriptbasic Build Linux
« Last post by John on April 16, 2020, 05:41:20 PM »
AIR,

Would you have time to change the ScriptBasic build make to create the extension modules last.  SBT needs libscriba to build. We would need to point SBT make to bin/lib.

This would also allow ScriptBasic to be used as the build language for extension modules and docs. The existing Perl based build system should only be used by ScriptBasic maintainers. IMO
30
Open Forum / Re: Basic & Me
« Last post by paulwratt on April 14, 2020, 10:14:29 AM »
I wonder whether computers which only run BASIC are still attractive to people, Raspberry Pi is cool, but it includes a lot's of unnecessary components.

Thats one of the reasons I ran out and converted the IchigoJam BASIC command help the day I found IchigoJam for RPi. Its also the reason why I want to use this RPi baremetal project to create a standalone version of SDL2_Basic and/or my enhanced version of BAS 2.4.

I know a couple have been done so far like Raspberry Pi BASIC, but (like a lot of other BASIC users) none of them offer dialect or functionality that I want. ItchigoJam is close, based on MSX-BASIC, graphics, sound and GPIO, but only 1K of RAM. I prefer the vector based graphics and lack of external access to any files outside of SAVE and LOAD, my RPi version of SDL_Basic, Pistol Basic, as it is more like a traditional BASIC machine, so I would love to have it as bare metal, 1 second boot up ... to BASIC.

My very first experience with a computer was a fair day at Tauranga Airport in (or around) 1976 at the age of 6. I hacked some 30+ year old guys HELLO world failure on an Atari 400, he wrote "GO TO" instead of "GOTO". Needless to say I got in trouble with my parents because I kept slipping off to watch people use it, and never got access to "my own" computer until I was 15, but  I still remember it like it was yesterday.

In the meantime I read just about every computer magazine I could get a hold of (but could not buy), my favourite was reading the One Liners in the back page of (Compute? or A+?). Later (24) I rescued a complete collection of Byte Magazine that was going to be thrown out, from which I had previously built a Parallel Port Vortrax Speech Synthesizer (age 20), and could be programed from GW-BASIC via text phonetics or phonems. Needless to say the Vortrax chip was salvaged and statically fried, but it was worth a try.

We had BMC Z80 CP/M machines at high school age 13 (case looked like an grey Apple II, but with a printer where the expansion lid was), we had A Single Density Drive with CP/M 2.2 & MBASIC, whereas the seniors had multiple Double Density Drives and some fancy basic that didn't need line numbers, had labels (which could be numeric), a full screen editor and used indents for structure and flow control, did graphics and sound. Juniors got baned not long after cos there were too many wanting to use them, and I was 15 before we were aloud to use then again, and even then it was only sometimes for Maths class. At the time my cousin was given a Apple II clone from Taiwan called Formosa which I used on and off over the next 5-6 years. The next high school I went to had New Zealand created 6809 based Poly terminals with Poly BASIC in rom, for which I the Technical Manual, which got stolen the 1st day I took it to school. Needless to say the juniors were not allowed to use the Apple IIe's and Apple III's at my new highschool, but thats hard to do when you are wave jumping your windsurfer.

Around age 16 I managed to convince Mom to buy a Spectravideo 728 with Disk Drive about 2 weeks before the portable 738 was released, after I was tracked down by the police for spending too long in an inner city Video Arcade. The same computer shop in Hamilton was the first in New Zealand to have an Atari 260ST with TOS on disk and two weeks later an Amiga 1000 which used to play "Smoke on the Water" by Dragon (MOD? no words). I used to created demos and copy type-ins for them before that, on Spectravideo 318, 328, Apple IIe, Sega SC-3000, C64, Plus 4, Atari 800XL, BBC Model B, Acorn Electron. Needless to say I had to leave them and "the family computer", 728 MSX, behind when I changed schools, but I could code Z80 from memory by then.

 My step brother had a ZX81 with 16Kb RAM pack and Warlock of Firetop Mountain, that was replaced by an Spectrum 16k on which we used to successfully fake tape loading with a microphone. Needless to say the resulting programs were always garbage, but they loaded. I got baned from the Spectrum after being blamed for a failed 48k upgrade. Later when his dad replaced it with a CPC 6128 we used to spend hours play "hack my disc" where you had to find a certain peice of info and the disc could be any of CP/M Plus 3.0, 3.1, CP/M 2.24, or Locomotive Basic (no boot sector). Needless to say I got banned for using certain hack techniques which meant I could no longer win, but that did allowed me to recover many computers since then.

I Left school before I was 17, then later I did hardware Computer Peripheral Course that was taught by the ex-manager of Wang New Zealand, and he was able to get some awesome hardware to work on, stuff that a lot of techies at the time never got their screwdriver near, like 5M Pheonix Hard Drives with 5M removable platters where we could practice Azimyth head alignments, and A Wang VS Mini Computer with multiple Z80 cards, cant remember the version of BASIC we used on that, but it could multitask and do interprocess communications. Besides winning the many hacking compitions we used to have, I used to leave "my personal development tools" in E5 directories on the campus 286 MS-DOS 3 machines . (The Wang Wiki page is rather revealing). Needless to say the course was not nationally certified until the following year after I graduated, but I did get to Pretoria, SA, to do Java Gently with Judith Bishop.

As part of the course I went to work for the newly formed Unisys, still having Buroughs Mainframes and Sperry service contracts and hardware lying around it was the first time I ever used a Unix System V machine, which I broke, forgetting what I changed the root pasword to, which upset the service technicians no end, as it was also the first time they had seen one. I did not get to program anything else there (Unisys Desktop Slices are awesome), but they did send me off to help a guy with cabling, which turned out to be the first Fibre Optic link outside New Zealand, Sydney to Auckland to Welington. Needless to say Unisys declined to hire me for the Commonwealth Games, but even they never got as many hits per second as one of my pages did.

While in South Africa, working for the biggest corporate ISP as a web developer, they asked me to  make a button to print the web page, as far as I know I was the first person in the world to work out you could hook VB for Applications with VBscript, and dynamically print from IE 3/4. I was writing search engines when Google started theirs, ran my own personal RealServer Radio Station. In a non-stop Redbull fueled 54 hour marathon, learned Perl and converted 1000 flat file HTML web pages into a multi-frame database "flash application", becoming the 1st website to use Flash 5 push technology the same week it was released, using multi-homed javascript url redirection (view source line 60), later being published in hardcopy Flash Websites Book (2001, Intekom SA, the 1st one has monarch butterly). 5 years later in Australia I came across "web gold", figuring out how to get animated GIF's (I chose moving flames) to render through transparent TTF fonts with IE 5/6/7 using transform css, so the text was still selectable. Needless to say nothing mention above made me rich, but they were definitly fun at the time.

I modified a 64 column type-in to 80 columns for MSX, never fininshed my 1st Sprite based (Summergames type) "Race for the Rice Bubble" Game. But loved MSX so much I booted directly into a customised OpenMSX development system on my first RPi B, running NestorBASIC and host folder disks. Wrote a simple listing variable and function documentor, useful for 1000+ line listings, eg :' var mX=map width. I did the same with SimCoupe and a multi-partition harddrive setup. I really like using the Apple //c, the Franklin ACE 500, and the Tandy 100 EX and HX, the Memotech MTX512, the Enterprise 128 and STOS on AtariST. Needless to say I have never owned any of that hardware, except the 4M Atari STe that mum made me throw in a dumpster, circa 1998 (along with my MSX, IBM 3720, Atari 130XL and 4x ATARi 800XL, all with disk drives) , but that is a story for another day

I prefer modern BASIC dialects to use SDL 1.2 because most platforms can run the full set of libraries (unlike SLD2), so they are easily portable to older 16/32bit systems. I've added BIN$, MERGE, CHAIN and 256 colors to BAS. I have started (but not finished) bringing 2 seperate BASIC system OS executables to Linux, one is standard uppercase BASIC commands as SH shell scripts (eg. CLS, PRINT, LOCATE, PEEK, etc), and the other replaces standard Linux shell scripts and binaries with BASIC scripted replacements (eg ls, cat, etc). I would love to have a replBASIC OS integrated shell. In BASIC (where applicable), what commands and/or functions are most commonly missing? FORK and EVAL. Needless to say they will never be made mandatory, but one can live in hope.

I believe the best looking and performing computer in the world is AtariST desktop on  baremetal, with TinyBASIC shell scripting (like SH) and OS integration (like AppleScript), running natively on ARM based SBC (especially multi-core RPi's). I am part way there with pTOS, uBASIC, TinyBASIC or BAS. Needless to say OS integration (like AppleScript) is some way off, but not impossible.

Cheers

Paul
PS all languages have a time and a place, but none are as basic as BASIC
Pages: 1 2 [3] 4 5 ... 10