lawless-legends/Docs/Tutorials/PLASMA/User Manual.md

159 lines
8.1 KiB
Markdown
Raw Normal View History

2014-05-16 18:22:45 +00:00
# PLASMA Programming User Manual
2014-05-16 05:45:21 +00:00
## ( Proto Language AsSeMbler for Apple)
## Introduction
2014-05-16 15:38:08 +00:00
PLASMA is a medium level programming language targetting the 8 bit 6502 processor. Historically, there were simple languages developed in the early history of computers that improved on the tedium of assembly language programming while still being low level enough for system coding. Languages like B, FORTH, and PLASMA fall into this category. The following will take you through the process of writing, building and running a PLASMA module.
2014-05-16 05:45:21 +00:00
2014-05-20 04:04:19 +00:00
### PLASMA Modules
To keep development compartmentalized and easily managed, PLASMA uses relatively small, dynamically loaded and linked modules. The module format extends the .REL filetype originally defined by the EDASM assembler from the DOS/ProDOS Toolkit from Apple Computer, Inc. PLASMA extends the file format through a backwards compatible extension that the PLASMA loader recognizes to locate the PLASMA bytecode and provide for advanced dynamic loading of module dependencies.
2014-05-16 15:38:08 +00:00
### Obligatory 'Hello World'
2014-05-16 05:45:21 +00:00
To start things off, here is the standard introductory program:
```
import STDLIB
2014-05-16 05:46:21 +00:00
predef puts
2014-05-16 05:45:21 +00:00
end
byte hello[] = "Hello, world.\n"
puts(@hello)
done
```
2014-05-16 15:38:08 +00:00
Three tools are required to build and run this program: **plasm**, **acme**, and **plvm**. The PLASMA compiler, **plasm**, will convert the PLASMA source code (usually with an extension of .pla) into an assembly language source file. **acme**, the portable 6502 assembler, will convert the assembly source into a binary ready for loading. To execute the module, the PLASMA portable VM, **plvm**, can load and interpret the bytecode. The same binary can be loaded onto the target platform and run there with the appropriate VM. On Linux/Unix from lawless-legends/PLASMA/src, the steps would be entered as:
2014-05-16 05:45:21 +00:00
```
./plasm -AM < hello.pla > hello.a
acme --setpc 4096 -o HELLO.REL hello.a
./plvm HELLO.REL
```
The computer will respond with:
```
Load module HELLO.REL
Hello, world.
```
2014-05-16 15:38:08 +00:00
A couple of things to note: **plasm** only accepts input from stdin and output to stdout. To build acme compatible module source, tha '-AM' flags must be passed in. The **acme** assembler needs the --setpc 4096 to assemble the module at the proper address, and the -o option sets the output file. The makefile in the lawless-legends/PLASMA/src directory has automated this process. Enter:
2014-05-16 05:45:21 +00:00
2014-05-16 15:38:08 +00:00
```
make hello
```
for the make program to automate this.
## Organization of a PLASMA Source File
### Comments
Comments are allowed throughout a PLASMA source file. The format follows that of an assembler: they begin with a `;` and comment out the rest of the line:
```
; This is a comment, the rest of this line is ignored
```
### Declarations
The beginning of the source file is the best place for certain declarations. This will help when reading others' code as well as returning to your own after a time.
2014-05-16 18:19:11 +00:00
#### Module Dependencies
2014-05-16 15:38:08 +00:00
Module dependencies will direct the loader to make sure these modules are loaded first, thus resolving any outstanding references. A module dependency is declared with the `import` statement block with predefined function and data definitions. The `import` block is completed with an `end`. An example:
```
import STDLIB
2014-05-20 03:12:32 +00:00
const reshgr1 = $0004
2014-05-16 15:38:08 +00:00
predef putc, puts, getc, gets, cls, gotoxy
end
import TESTLIB
byte testdata, teststring
word testarray
2014-05-20 03:12:32 +00:00
predef puti
2014-05-16 15:38:08 +00:00
end
```
2014-05-20 03:12:32 +00:00
The `predef` pre-defines functions that can be called throughout the module. The data declarations, `byte` and `word` will refer to data in those modules. `const` can appear in an `import` block, although not required. It does keep values associated with the imported module in a well-contained block for readability. Case is not significant for either the module name nor the pre-defined function/data labels. They are all converted to uppercase with 16 characters significant when the loader resolves them.
2014-05-16 15:38:08 +00:00
2014-05-16 18:19:11 +00:00
#### Constant Declarations
2014-05-16 15:38:08 +00:00
Constants help with the readability of source code where hard-coded numbers might not be very descriptive.
```
const MACHID = $BF98
2014-05-20 03:12:32 +00:00
const speaker = $C030
2014-05-16 15:38:08 +00:00
const bufflen = 2048
```
These constants can be used in expressions just like a variable name.
2014-05-16 18:19:11 +00:00
#### Predefined Functions
2014-05-20 03:32:24 +00:00
Sometimes a function needs to be referenced before it is defined. The `predef` declaration reserves the label for a function. The `import` declaration block also uses the `predef` declaration to reserve an external function. Outside of an `import` block, `predef` will only predefine a function that must be declared later in the source file, otherwise an error will occur.
2014-05-16 15:38:08 +00:00
```
predef exec_file, mydef
```
2014-05-16 18:19:11 +00:00
#### Global Data & Variable Declarations
2014-05-16 15:38:08 +00:00
One of the most powerful features in PLASMA is the flexible data declarations.
2014-05-16 18:19:11 +00:00
#### Native Functions
2014-05-16 15:38:08 +00:00
An advanced feature of PLASMA is the ability to write functions in native assembly language. This is a very advanced topic that is covered more in-depth in the Advanced Topics section.
2014-05-16 18:19:11 +00:00
#### Function Definitions
2014-05-20 03:32:24 +00:00
Function definitions **must** come after all other declarations. Once a function definition is written, no other global declarations are allowed.
2014-05-16 15:38:08 +00:00
2014-05-16 18:19:11 +00:00
#### Module Initialization Function
2014-05-16 15:38:08 +00:00
After all the function definitions are complete, an optional module initiialization routine follows. This is an un-named defintion an is written in-line without a definition declaration. As such, it doesn't have parameters or local variables. Function definitions can be called from within the initialization code.
2014-05-16 18:19:11 +00:00
#### Exported Declarations
2014-05-16 15:38:08 +00:00
Data and function labels can be exported so other modules may access this modules data and code. By prepending `export` to the data or functions declaration, the label will become available to the loader for inter-module resolution.
```
export def plot(x, y)
romcall(y, 0, x, 0, $F800)
end
```
2014-05-16 18:19:11 +00:00
#### Module Done
2014-05-20 03:12:32 +00:00
The final declaration of a module source file is the `done` statement. This declares the end of the source file. Anything following this statement is ignored.
## Stacks
2014-05-20 03:32:24 +00:00
The basic architecture of PLASMA relies on different stack based FIFO data structures. The stacks aren't directly manipulated from PLASMA, but almost every PLASMA operation involves one or more of the stacks. A stack architecture is a very flexible and convenient way to manage an interpreted language, even if it isn't the highest performance.
2014-05-20 03:12:32 +00:00
### Call Stack
The call stack, where function return addresses are saved, is implemented using the hardware call stack of the CPU. This makes for a fast and efficient implementation of function call/return.
### Local Frame Stack
2014-05-20 03:32:24 +00:00
Any function definition that involves parameters or local variables builds a local frame to contain the variables. Often called automatic variables, they only persist during the lifetime of the function. They are a very powerful tool when implementing recursive algorithms. PLASMA puts a limitation of 254 bytes for the size of the frame, due to the nature of the 6502 CPU. With careful planning, this shouldn't be too constraining.
2014-05-20 03:12:32 +00:00
### Evaluation Stack
All temporary values are loaded and manipulated on the evaluation stack. This is a small (16 element) stack implemeted in high performance memory/registers of the host CPU. Parameters to functions are passed on the evaluation stack, then moved to local variables for named reference inside the funtion.
2014-05-16 15:38:08 +00:00
2014-05-16 18:19:11 +00:00
## Data Types
2014-05-20 03:12:32 +00:00
PLASMA only really defines two types: `byte`, `word`. All operations take place on word sized quantities, with the exception of loads and stores to byte sized addresses. The interpretation of a value can be an interger, or an address. There are a nuber of operators to identify how a value is to be interpreted.
2014-05-20 03:23:33 +00:00
### Decimal and Hexadecimal Numbers
### Character and String Literals
2014-05-20 03:12:32 +00:00
### Bytes
Bytes are unsigned, 8 bit values, stored at an address. Bytes cannot be manipulated as bytes, but are promoted to words as soon as they are loaded ontp the evaluation stack. When stored to a byte addres, the low order byte of a word is used.
### Words
### Addresses
#### Arrays
#### Offsets
#### Pointers
## Function Definitions
2014-05-16 15:38:08 +00:00
2014-05-20 03:12:32 +00:00
### Expressions
2014-05-16 15:38:08 +00:00
2014-05-20 03:12:32 +00:00
### Control Flow
2014-05-16 05:45:21 +00:00
2014-05-20 03:32:55 +00:00
## Dynamic Heap Memory Allocation
2014-05-20 03:32:24 +00:00
2014-05-20 03:12:32 +00:00
## Advanced Topics