https://www.gammon.com.au/forum/?id=11203 Home Downloads Search Forum --------------------------------------------------------------------- Skip to main content Log on Register forum user name Search FAQ Gammon Forum Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link. Due to spam on this forum, all posts now need moderator approval. Entire forum Programming General GPascal - a blast from the past --------------------------------------------------------------------- GPascal - a blast from the past It is now over 60 days since the last post. This thread is closed. Refresh page --------------------------------------------------------------------- Pages: 1 2 Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Sat 25 Jun 2011 05:22 AM (UTC) Date Amended on Sat 25 Jun 2011 11:33 PM (UTC) by Nick Gammon [GPascal] Commodore 64 manual cover ------------------------------------------------------------- Quite a few years ago (1978) I started working with microprocessors, in particular the Motorola 6800 evaluation board. Subsequently I made a "tiny" Pascal compiler for it, which was entirely stored in EEPROM (eraseable ROM). Later it was converted to run on the Apple II, and later again the Commodore 64. Andrew Stuart from Supercoders in Melbourne has put together a lengthy blog post which describes (with images and PDF files) the history of this project: http://www.supercoders.com.au/blog/nickgammongpascal.shtml ------------------------------------------------------------- I managed to dig up the old ads, "GPascal News" issues, and magazine reviews about GPascal. Also, with a large stroke of luck, the source listing of the original (Commodore 64 version) compiler - in assembler. Message [GPascal] Snapshot of GPascal source Full source: http://www.gammon.com.au/GPascal/source/ ------------------------------------------------------------- Andrew has assembled those into a nice read, with links to the various articles and images that I sent him. So if you want to know what I was doing with computers 30 years ago take a read of that! You can even grab a copy of the compiler, and a Commodore 64 emulator, and try it out! Thanks, Andrew, for motivating me to dig out all this archival material. Another 10 years and the DVD with the source backed up on it might have been lost. ------------------------------------------------------------- [GPascal] Apple II manual cover ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted by Fiendish USA (2,535 posts) Bio Global Moderator Date Reply #1 on Sat 25 Jun 2011 06:48 PM (UTC) That's a wicked piece of work, Nick. Stellar writeup. :) Message -------------------------------------------------------- https://github.com/fiendish/aardwolfclientpackage Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Reply #2 on Sun 26 Jun 2011 12:30 AM (UTC) Date Amended on Sun 26 Jun 2011 06:07 AM (UTC) by Nick Gammon Thanks, Fiendish! To explain the source (http://www.gammon.com.au/GPascal/ source/) a bit, a lot of work was put into fitting it into the available memory. One approach I used was to tokenise things like error messages. Message tokens This was done by putting bytes with the high-order bit set inside messages, and then expanding them out at display time. This is a table I extracted of the various tokens, in hex, (from PAS1.ASM lines 1754+): B0 = P-codes B1 = full B2 = Constant B3 = Identifier B4 = expected B5 = missing B6 = Illegal B7 = Incorrect B8 = string BA = compiler BB = literal BC = mismatch BD = Error BE = zero BF = source file C0 = of C1 = or C2 = to C3 = ended at C4 = Symbol C6 = Stack C7 = Instruction C8 = table C9 = Type CA = list CC = Number CD = Line CE = Gambit CF = Games D2 = Version 3.1 Ser# 5001 D3 = Copyright 1983 D4 = ompile D5 = yntax D6 = Written by Nick Gammon D7 = uit D8 = Range D9 = Parameter DA = dit, DB = < Error messages The error messages, in decimal, once the tokens are expanded, are (from PAS1.ASM lines 1222+): 1: Memory full 2: Constant expected 3: = expected 4: Identifier expected 5: , or : expected 6: bug 7: *) expected 8: Incorrect string 9: . expected 10: ; expected 11: Undeclared Identifier 12: Illegal Identifier 13: := expected 14: literal string of zero length 15: compiler limits exceeded 16: THEN expected 17: ; or END expected 18: DO expected 19: Incorrect Symbol 20: bug 21: Use of procedure Identifier in expression 22: ) expected 23: Illegal factor 24: Type mismatch 25: BEGIN expected 26: "of " expected 27: Stack full 28: TO or DOWNTO expected 29: string literal too big 30: Number out of Range 31: ( expected 32: , expected 33: [ expected 34: ] expected 35: Parameters mismatched 36: Data Type not recognised 37: Symbol table full 38: Duplicate Identifier Source tokens When the source was being processed it was turned into "tokens" (eg. numbers, symbols, reserved words, identifieds, etc.). This made it easy to do comparisons in the compiler proper, because rather than having to do string compares, you simply checked a single byte. The source tokens, in hex, are (from PAS1.ASM line 559+): 81 = get 82 = const 83 = var 84 = array 85 = of 86 = procedure 87 = function 88 = begin 89 = end 8A = or 8B = div 8C = mod 8D = and 8E = shl 8F = shr 90 = not 91 = mem 92 = if 93 = then 94 = else 95 = case 96 = while 97 = do 98 = repeat 99 = until 9A = for 9B = to 9C = downto 9D = write 9E = read 9F = call A1 = char A2 = memc A3 = cursor A4 = xor A5 = definesprite A6 = plot A7 = getkey A8 = clear A9 = address AA = wait AB = chr AC = hex AD = spritefreeze AE = close AF = put DF = sprite E0 = positionsprite E1 = voice E2 = graphics E3 = sound E4 = setclock E5 = scroll E6 = spritecollide E7 = groundcollide E8 = cursorx E9 = cursory EA = clock EB = paddle Message EC = spritex ED = joystick EE = spritey EF = random F0 = envelope F1 = scrollx F2 = scrolly F3 = spritestatus F4 = movesprite F5 = stopsprite F6 = startsprite F7 = animatesprite F8 = abs F9 = invalid FA = load FB = save FC = open FD = freezestatus FE = integer FF = writeln Notice that the "message tokens" in the range 0xB0 to 0xDB are not in the list. This is so that the output routine can convert back tokens which are either messages or reserved words without clashes. This makes the snippet of source in the earlier post more understandable: 1800 * REPEAT 1801 * 9734: 20 02 90 1802 REPEAT JSR PSHPCODE 9737: 20 49 80 1803 REP1 JSR GTOKEN 973A: 20 63 93 1804 JSR STMNT 973D: A5 16 1805 LDA TOKEN 973F: C9 3B 1806 CMP #';' 9741: F0 F4 1807 BEQ REP1 9743: A9 99 1808 LDA #$99 9745: A2 0A 1809 LDX #10 9747: 20 34 80 1810 JSR CHKTKN 974A: 20 40 90 1811 JSR GETEXPR 974D: 20 55 80 1812 JSR PULWRK 9750: 20 51 90 1813 JSR WRK:OPND 9753: A9 3D 1814 LDA #61 9755: 4C 88 80 1815 JMP GENRJMP The code calls GTOKEN (get token) and processes a statement. Then it checks if we got a ";" token, and if so, gets another statement. When the statements separated by semicolons run out, it checks for token 0x99 (which is "until" from the above table) and if it doesn't get it outputs error 10 which is "; expected" from the earlier table). P-codes This is the meanings of the P-codes (pseudo machine codes): Code Function Description ---- ---------- ------------------------------------ 00 = LIT Load constant 01 = DEF:SPRT DEFINESPRITE 02 = NEG Negate (sp) 03 = HPLOT PLOT 04 = ADD Add (sp) to (sp - 1) 05 = TOHPLOT PLOT (not used) 06 = SUB Subtract (sp) from (sp - 1) 07 = GETKEY GETKEY 08 = MUL Multiply (sp) * (sp - 1) 09 = CLEAR CLEAR 0A = DIV Divide (sp - 1) / (sp) 0B = MOD Modulus (sp - 1) MOD (sp) 0C = ADRNN Address of integer 0D = ADRNC Address of character 0E = ADRAN Address of integer array 0F = ADRAC Address of character array 10 = EQL Test (sp - 1) == (sp) 11 = FINISHD Stop run (end program) 12 = NEQ Test (sp - 1) != (sp) 13 = CUR Cursor position 14 = LSS Test (sp - 1) < (sp) 15 = FREEZE:S SPRITEFREEZE 16 = GEQ Test (sp - 1) >= (sp) 17 = INH Input hex number 18 = GTR Test (sp - 1) > (sp) 19 = LEQ Test (sp - 1) <= (sp) 1A = ORR OR (sp - 1) | (sp) 1B = AND AND (sp - 1) & (sp) 1C = INP Input number 1D = INPC Input character 1E = OUT Output numbher 1F = OUTC Output character 20 = EOR Not (sp) (logical negate) 21 = OUH Output hex number 22 = SHL Shift left (sp) bits 23 = OUS Output string 24 = SHR Shift right (sp) bits 25 = INS Input string into array 26 = INC Increment (sp) by 1 27 = CLL Relative procedure/function call 28 = DEC Decrement (sp) by 1 29 = RTN Procedure/function return 2A = MOV Copy (sp) to (sp + 1) 2B = CLA Call absolute address 2C = LOD Load integer onto stack 2D = LODC Load character onto stack 2E = LDA Load absolute address integer 2F = LDAC Load absolute address character 30 = LDI Load integer indexed 31 = LDIC Load character indexed 32 = STO Store integer 33 = STOC Store character 34 = STA Store integer absolute address 35 = STAC Store character absolute address 36 = STI Store integer indexed 37 = STIC Store character indexed 38 = ABSCLL Absolute procedure/function call 39 = WAIT WAIT 3A = XOR XOR (sp - 1) ^ (sp) 3B = INT Increment stack pointer 3C = JMP Jump unconditionally 3D = JMZ Jump if (sp) zero 3E = JM1 Jump if (sp) not zero 3F = SPRITE SPRITE 40 = MVE:SPRT POSITIONSPRITE 41 = VOICE VOICE 42 = GRAPHICS GRAPHICS 43 = SOUND SOUND 44 = SET:CLK SETCLOCK 45 = SCROLL SCROLL 46 = SP:COLL SPRITECOLLIDE 47 = BK:COLL GROUNDCOLLIDE 48 = CURSORX CURSORX 49 = CURSORY CURSORY 4A = CLOCK CLOCK 4B = PADDLE PADDLE 4C = SPRT:X SPRITEX 4D = JOY JOYSTICK 4E = SPRT:Y SPRITEY 4F = OSC3 RANDOM 50 = VOICE3 ENVELOPE 51 = SCROLLX SCROLLX 52 = SCROLLY SCROLLY 53 = SPT:STAT SPRITESTSTATUS 54 = MOV:SPT MOVESPRITE 55 = STOP:SPT STOPSPRITE 56 = STRT:SPT STARTSPRITE 57 = ANM:SPT ANMINATESPRITE 58 = ABS ABS (absolute value of (sp)) 59 = INVALID INVALID 5A = LOADIT LOAD 5B = SAVEIT SAVE 5C = X:OPEN OPEN 5D = FR:STAT FREEZESTATUS 5E = OUTCR Output a carriage-return 5F = X:CLOSE CLOSE 60 = X:GET GET 61 = X:PUT PUT Operations that mention (sp) refer to "whatever value is on the top of the stack", and (sp - 1) is the second value from the top. Thus for example, when you add, it pulls the stop value from the stack, and then the second top value, adds them, and pushes the result onto the stack. ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Reply #3 on Sun 17 Jul 2011 03:31 AM (UTC) Date Amended on Fri 28 Nov 2014 02:01 AM (UTC) by Nick Gammon Below is a quick demo of G-Pascal in operation, running on the VICE emulator: ------------------------------------------------------------- (Video cannot be shown because scripting is disabled) ------------------------------------------------------------- Message This demo shows entering the editor (E), listing the source program (L), compiling it (C), and then running the compiled program (R). ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Date Reply #4 on Sun 17 Jul 2011 03:35 AM (UTC) VICE emulator available here: http://vice-emu.sourceforge.net/ G-Pascal disk image available here: Message http://www.gammon.com.au/GPascal/G-Pascal_v3.0.d64 ------------------------------------------------------------ - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Reply #5 on Sun 17 Jul 2011 04:09 AM (UTC) Date Amended on Fri 28 Nov 2014 02:02 AM (UTC) by Nick Gammon Another demo, showing a slightly longer program, this time playing sounds using the inbuilt sound chip (emulated of course in this case): ------------------------------------------------------------- Message (Video cannot be shown because scripting is disabled) ------------------------------------------------------------- ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Reply #6 on Sun 17 Jul 2011 04:34 AM (UTC) Date Amended on Sun 17 Jul 2011 04:36 AM (UTC) by Nick Gammon Syntax diagrams, to help understand the code: [GPascal_Sy] [GPascal_Sy] [GPascal_Sy] [GPascal_Sy] Message [GPascal_Sy] [GPascal_Ex] These are from the Apple II manual - they doesn't include the extra functions in the Commodore 64 version. ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Cjb Australia (3 posts) Bio by Date Reply #7 on Wed 22 Feb 2012 02:25 PM (UTC) I'd just like to note that I've munged the original Merlin assembler source into something a bit more modern (cc65's assembler to be exact-- it's what I use for my 6502 SBC work), and managed to produce a byte-exact copy of the G-Pascal 3.1 release: it's available from http:// kildall.apana.org.au/~cjb/G-Pascal/ It only takes 0.16 seconds to assemble and build the entire Message program... ;) I've been telling my 6502-dev friends about G-Pascal for years! I've actually made several attempts at decompiling it over the years, so that there could be a nice programming language on the SBC projects I've been involved with... and then just a few days ago, I discovered the Supercoders interview and the SOURCE CODE! Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Date Reply #8 on Wed 22 Feb 2012 07:56 PM (UTC) Cool, thanks! Where do you get the assembler? Message ------------------------------------------------------------ - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Cjb Australia (3 posts) Bio by Date Reply #9 on Thu 23 Feb 2012 02:33 AM (UTC) >>> Where do you get the assembler? ca65 is from the CC65 6502 cross-compiler suite (www.cc65.org; ftp://ftp.musoftware.de/pub/uz/cc65/) ... There's a few choices for cross-assemblers out there, but I gravitated to ca65 for it being a no-hassle build on my Unix systems, and its native syntax resembles the 'Commodore' way of doing things a fair bit (What's all that "LABEL = *" business? :P :). It's also a fully-featured macro assembler, supports all the models of 65*02, and your get the source-- which I've used personally to add support for the Mitsubishi Message 740/50734 CPUs (a very nice 10MHz embedded 6502 clone..) I've never once thought of using "BLT" and "BGE" in place of BCC and BCS... Now that I've managed to build a normal working G-Pascal, the project for me now is to make a Generic 6502 version that will build for machines like the SYM-1, VIC20, and 50734; it shouldn't be much effort to make a ROMable GPascal either, so I can have a system that starts up into PASCAL instead of BASIC :D ... And someone I've already talked to is working at separating the IDE into a stand-alone parser and interpreter. Top --------------------------------------------------------------------- Posted Cjb Australia (3 posts) Bio by Date Reply #10 on Thu 23 Feb 2012 05:40 PM (UTC) Cjb said: Now that I've managed to build a normal working G-Pascal, the project for me now is to make a Generic 6502 version that will build for machines like the SYM-1, VIC20, and 50734 Message [...] This might scare people: http://kildall.apana.org.au/~cjb/vicpascal.png (Just a rough proof-of-concept attempt...) Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Date Reply #11 on Thu 23 Feb 2012 10:27 PM (UTC) Cjb said: ... it shouldn't be much effort to make a ROMable GPascal either, so I can have a system that starts up into PASCAL instead of BASIC :D ... And someone I've already talked to is working at separating the IDE into a stand-alone parser and interpreter. It was designed to go into ROM - that is, there is no Message modification inside program space. Also the stand-alone interpreter should be easy enough. I used to sell/give away a GPascal interpreter, which was basically just the runtime part of the code (easy enough to get at as I think that was just one of the source files). ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Deathshadow USA (4 posts) Bio by Date Reply #12 on Wed 19 Sep 2012 07:07 AM (UTC) I have a question -- it lets me save to a p-code object file; but where's the stand-alone "run time system"? Be a lot handier if there was a easy standalone -- the C64 manual mentions it, would be nice to have it. Message Though I supposed I could start tinkering with "part 4's" source code... Of course, would be a LOT nicer if it compiled to machine language, since Kyan and "super Pascal" leave a bit to be desired on the C64... but it still beats the tar out of BASIC for speed and C for ease of use. Top --------------------------------------------------------------------- Posted Nick Gammon Australia (23,140 posts) Bio Forum by Administrator Date Reply #13 on Wed 19 Sep 2012 09:55 AM (UTC) I don't know where you would get the run-time system except for a floppy disk I have here which I don't have any device to stick it into. As for compiling into machine code, that's a whole new (and Message more complicated) ball game. ------------------------------------------------------------- - Nick Gammon www.gammon.com.au, www.mushclient.com Top --------------------------------------------------------------------- Posted Deathshadow USA (4 posts) Bio by Date Reply #14 on Sat 22 Sep 2012 05:07 PM (UTC) Nick Gammon said: I don't know where you would get the run-time system except for a floppy disk I have here which I don't have any device to stick it into. Hmm... I'm planning on setting my c64 stuff back up (there's a TRS-80 Coco 1 sitting in it's spot right now) sometime over Message the coming weeks. I don't suppose you'd be willing to send that disk to someone like myself who could turn it into a .d64 file? Would be nice to be able to preserve it... assuming said disk even still works. Top --------------------------------------------------------------------- The dates and times for posts above are shown in Universal Co-ordinated Time (UTC). To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time. --------------------------------------------------------------------- 114,615 views. This is page 1, subject is 2 pages long: 1 2 [Next page] It is now over 60 days since the last post. This thread is closed. Refresh page Go to topic: [(Choose topic) ] [Go] Search the forum --------------------------------------------------------------------- [Go to top] top Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation. Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise. Home --------------------------------------------------------------------- Written by Nick Gammon - 5K profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites Marriage equality Comments to: Gammon Software support [RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/ forum.xml ) [Hosted at HostDash]