Programing the NES in Pascal and p-code?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Programing the NES in Pascal and p-code?
by on (#147029)
In my other thread about programming languages and games, I was positively surprised to hear that the Pascal programming language was often used to program games back in the day. I do not need to remember the disadvantages of using assembly, so I'd ask myself if the NES is a suitable target for the Pascal language.

The main theoretical advantages of using Pascal over it's concurrent, C, are:
  • The language enforces a stronger disciplines when it comes to array sizes, etc..
  • The language can be compiled to p-code and be interpreated, which means porting it to 6502 is much easier as it doesn't need rewriting part of a compiler
  • The usage of sub-range types makes it easier to store things on 8-bits while documenting the intent clearly (i.e. don't have to use "chars" for numbers that are not chars)
  • It also means that code density can be increased, you can have more code in a ROM bank, thus less ROM banks in total
  • Widely used and standardized language (as opposed to, Acheron VM and PLASMA for instance)

It appears that the most popular one was UCSD Pascal, and it was ported on the Apple II, which also had a 6502, meaning it is probably theoretically feasible on the NES, if it is stripped from it's I/O part.

The problems are: Where can we found a cross compiler that transform Pascal sources into p-codes (not need to be compatible with the original UCSD)? The requirements are:
  • Can run on a PC (cross-development), do NOT require a 6502 machine or an emulator for compiling the sources
  • Should be on a permissive licence, should allow at least commercial but non-profit usage (i.e. selling carts that were developed with it for non-profit should be allowed)
  • The p-codes should be documented (not necessary compatible with the UCSD originals), and an example of implementation on any system (not necessary 6502) should be provided
  • It should be possible to call assembly from Pascal. If Pascal can be called from Assembly then it's even better
  • Should use a standardized version of Pascal (or Modula, pretty much the same thing). Floating point support is not necessary. No incompatibilities with other major Pascal compilers.

The most interesting solutions seems to be FreePascaland GNU-Pascal (both are GPL desipte the name). Unfortunately they seem to emit machine code directly and don't use p-codes, which means porting to 6502 would be a very complex process.

G-Pascal seems nice, but does not support cross-compilation.

The most promising seems to be this, but I cannot manage to build it on neither Cygwin or Linux.
Re: Programing the NES in Pascal and p-code?
by on (#147030)
Bregalad wrote:
The main theoretical advantages of using Pascal over it's concurrent, C, are:
  • The language can be compiled to p-code and be interpreated, which means porting it to 6502 is much easier as it doesn't need rewriting part of a compiler

Theoretically, C can also be compiled to an interpreted language. For example, Emscripten compiles C to JavaScript. But practically, on the NES, any game using an "interpreter" is probably going to have to be turn-based.
Re: Programing the NES in Pascal and p-code?
by on (#147031)
You mustn't use the interpreter all the time, that's why I said
Quote:
It should be possible to call assembly from Pascal.


Of course if your game is turn-based it helps a lot as more content can be left without being rewritten in assembly.

Quote:
Theoretically, C can also be compiled to an interpreted language.

Yes, however, I cannot find anything good with Google (the result should be easily interpretable with the NES, which means a conceptually simple byte code).

EDIT: I could compile ucsd-psystem-xc-0.13 under linux after making some changes to png.cc. Let's play with it!
Re: Programing the NES in Pascal and p-code?
by on (#148234)
You could probably get some good insight by looking over the source code to batari BASIC.
http://bataribasic.com/download.html

It goes from BASIC to 6502 assembly.
Re: Programing the NES in Pascal and p-code?
by on (#148274)
Be aware that the Apple II had a native Pascal compiler that you could retarget to NES with some effort. I/O and memory maps would be different but I think it can create relocatable code. The more vexing issue is BCD mode, I'd imagine. ;)
Re: Programing the NES in Pascal and p-code?
by on (#148275)
slobu wrote:
It goes from BASIC to 6502 assembly.

Uh, no thanks. BASIC is terrible, as soon as you want to do something more complicated than print "Hello World" it becomes spaghetti, and anyway there is so many largely incompatible and non-standardized dialects that it's not really a language.
Quote:
Be aware that the Apple II had a native Pascal compiler that you could retarget to NES with some effort. I/O and memory maps would be different but I think it can create relocatable code. The more vexing issue is BCD mode, I'd imagine. ;)

Yes, this is what I had in mind. But I made a thread about it on 6502.org.
Re: Programing the NES in Pascal and p-code?
by on (#158285)
When looking at Sweet16, I saw/found/rediscovered/reinvented some cool tricks for making bytecode interpreters. That language is very simple and is effectively a very primitive VM. You could use a text-to-byte-code method like the BASICs used, and then run your interpreted code using a bytecode engine. The techniques are still useful to know, but I agree that actually using BASIC (especially old 8-bit dialects) is a non-starter.
Re: Programing the NES in Pascal and p-code?
by on (#158299)
Regarding VMs on 6502; PLASMA is to most interesting VM I've found so far for 6502. Might be an interesting read even though it's not pascal :)

https://github.com/dschmenk/PLASMA
http://schmenk.is-a-geek.com/PLASMA.html
Re: Programing the NES in Pascal and p-code?
by on (#158303)
Let's just imagine that you're coming up with a bytecode interpreter, and want to start out simple. You first need to create a table of functions that return (static JMP or RTS), once they run. This is the same code that you'd '#inline' in macros (or call) if compiling/macro assembling it. If you had 16 instructions, and 16 address modes (say, various pushes/pulls/registers/memory), then you'd be able to have a wrapper for the instruction code. The wrapper calls the address-mode logic, which loads registers/pushes to stack/uses ZP to send data in, and then on function completing, it writes to destination. Once it runs the instruction and in/out address-mode logic, it increments the VM's PC, assuming the 'exit' instruction wasn't run.

On some CPU's like 6502, you can AND with #$F0 or #$0F to get the instruction and address mode, and then use indexed addressing or self-modifying code to run the emulated instructions. It might be possible to build up branches (nested if statements) but on a 6502 this is a waste of memory and cycles. BTW, this is one of the most cache-breaking problems on modern CPU's, without very careful coding. Imagine: The cache has a (n-1)/n chance of guessing wrong based on previous branch. So only about 1/16th of time would be correct on a 16-instruction machine using that indexed code.

There are all kinds of optimizations and tradeoffs to the above approach. If you look at Sweet16's instruction set, you'll notice that it's not quite the same encoding as above. The disassembly for it is nice, hehe. It should be noted that if you're willing to do self-modifying code, then you can have many instruction sets, tailored to a specific class of problems/programs. If you go to playing with GPU's, this might come in handy. ;)

Oh yeah, PLASMA is awesome. I forgot to mention it - thanks for reminding me!
Re: Programing the NES in Pascal and p-code?
by on (#158305)
Those last 3 posts are completely off topic and have nothing to do with the subject I brang up. I already knew about virtual machine and other available solutions, and they were not directly suitable for me for various reasons. Again, I already talked about this again and again on 6502.org.

I was more interested into Pascal and p-code, most notably because those were the solutions that were already available in the 80s, and such working with them do not make any sort of "anachronism". I also am much less interested in anything that is not a widely spread standardised programing language, and definitely not interested in anything non-GNU.
Re: Programing the NES in Pascal and p-code?
by on (#158308)
At the risk of being told to "put up or shut up", hacking together a basic Pascal -> p-code compiler is almost a weekend project with modern tooling. The hard part would be writing an efficient enough interpreter for the NES.
Re: Programing the NES in Pascal and p-code?
by on (#158363)
adam_smasher wrote:
At the risk of being told to "put up or shut up", hacking together a basic Pascal -> p-code compiler is almost a weekend project with modern tooling. The hard part would be writing an efficient enough interpreter for the NES.

Really ?!
Anyway such a project already exists, and is in GNU, the only problem being that the author passed away.
Re: Programing the NES in Pascal and p-code?
by on (#158374)
Niklaus Wirth, who designed Pascal, is some kind of a genius when it comes to Keeping It Simple (his current project is Oberon, a complete computing system designed to be so simple and small that a single person could understand the whole thing). Pascal is by design the poster child for a programming language that's easy to parse and compile.

Anyway, that said, yes, it'd probably be best to use an existing compiler if you can get it to work.
Re: Programing the NES in Pascal and p-code?
by on (#158411)
Death of author - ouch! Not that it is a shock given age of these tools. Sigh...

So yeah, no stuff invented after September, 1993, or running on a PC, haha. In theory, the Apple II compilers CAN be shoehorned into working with NES memory map and hardware, if you really want to only use tools available during NES's peak period. You have to create new libraries and tell the compiler how to work with your mapper, as you mentioned. It would be easier to write from scratch but if you want 'old tools modified to work', then this would be one way to go.