mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-02-22 00:29:01 +00:00
Merge branch 'master' of https://github.com/dschmenk/PLASMA
This commit is contained in:
commit
07fdb6a31d
85
README.md
85
README.md
@ -7,7 +7,7 @@ PLASMA: **P**roto **L**anguage **A**s**S**e**M**bler for **A**pple
|
|||||||
|
|
||||||
PLASMA is a medium level programming language targeting the 8-bit 6502 processor. Historically, there were simple languages developed in the early years 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.
|
PLASMA is a medium level programming language targeting the 8-bit 6502 processor. Historically, there were simple languages developed in the early years 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.
|
||||||
|
|
||||||
PLASMA is a combination of virtual machine and assembler/compiler matched closely to the 6502 architecture. It is an attempt to satisfy a few challenges surrounding code size, efficient execution, small runtime and flexible code location. By architecting a unique bytecode that maps nearly one-to-one to the higher-level representation, the compiler can be very simple and execute quickly on the Apple II for a self-hosted environment. A modular approach provides for incremental development and code reuse. The syntax of the language is heavily influenced by assembly, Pascal, and C. The design philosophy was to be as simple as feasible while retaining flexibility and symantic clarity. You won't find any unnecessary or redundant syntax in PLASMA.
|
PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. It is an attempt to satisfy a few challenges surrounding code size, efficient execution, small runtime and flexible code location. By architecting a unique bytecode that maps nearly one-to-one to the higher-level representation, the compiler can be very simple and execute quickly on the Apple II for a self-hosted environment. A modular approach provides for incremental development and code reuse. The syntax of the language is heavily influenced by assembly, Pascal, and C. The design philosophy was to be as simple as feasible while retaining flexibility and symantic clarity. You won't find any unnecessary or redundant syntax in PLASMA.
|
||||||
|
|
||||||
Different projects have led to the architecture of PLASMA, most notably Apple Pascal, FORTH, and my own Java VM for the 6502: VM02. Each has tried to map a generic VM to the 6502 with varying levels of success. Apple Pascal, based on the USCD Pascal using the p-code interpreter, was a very powerful system and ran fast enough on the Apple II to be interactive but didn't win any speed contests. FORTH was the poster child for efficiency and obtuse syntax. Commonly referred to as a write only language, it was difficult to come up to speed as a developer, especially when using others' code. My own project in creating a Java VM for the Apple II uncovered the folly of shoehorning a large, 32-bit virtual memory environment into 8-bit, 64K hardware.
|
Different projects have led to the architecture of PLASMA, most notably Apple Pascal, FORTH, and my own Java VM for the 6502: VM02. Each has tried to map a generic VM to the 6502 with varying levels of success. Apple Pascal, based on the USCD Pascal using the p-code interpreter, was a very powerful system and ran fast enough on the Apple II to be interactive but didn't win any speed contests. FORTH was the poster child for efficiency and obtuse syntax. Commonly referred to as a write only language, it was difficult to come up to speed as a developer, especially when using others' code. My own project in creating a Java VM for the Apple II uncovered the folly of shoehorning a large, 32-bit virtual memory environment into 8-bit, 64K hardware.
|
||||||
|
|
||||||
@ -101,6 +101,8 @@ Different projects have led to the architecture of PLASMA, most notably Apple Pa
|
|||||||
|
|
||||||
# Build Environment
|
# Build Environment
|
||||||
|
|
||||||
|
## PLASMA Cross-Compiler
|
||||||
|
|
||||||
The first step in writing PLASMA code is to get a build environment working. If you have Unix-like environment, then this is a fairly easy exercise. Windows users may want to install the [Cygwin](https://www.cygwin.com/) environment to replicate a Unix-like environment under Windows. When installing Cygwin, make sure **gcc-core**, **make**, and **git** are installed under the **Devel** packages. Mac OS X users may have to install the **Xcode** from the App Store.
|
The first step in writing PLASMA code is to get a build environment working. If you have Unix-like environment, then this is a fairly easy exercise. Windows users may want to install the [Cygwin](https://www.cygwin.com/) environment to replicate a Unix-like environment under Windows. When installing Cygwin, make sure **gcc-core**, **make**, and **git** are installed under the **Devel** packages. Mac OS X users may have to install the **Xcode** from the App Store.
|
||||||
|
|
||||||
Launch the command-line/terminal application for your environment to download and build PLASMA. Create a source code directory and change the working directory to it, something like:
|
Launch the command-line/terminal application for your environment to download and build PLASMA. Create a source code directory and change the working directory to it, something like:
|
||||||
@ -110,7 +112,7 @@ mkdir Src
|
|||||||
cd Src
|
cd Src
|
||||||
```
|
```
|
||||||
|
|
||||||
## acme Cross-Assembler
|
### acme Cross-Assembler
|
||||||
|
|
||||||
There are two source projects you need to download: the first is a nice cross-platform 6502 assembler called [acme](http://sourceforge.net/p/acme-crossass/code-0/6/tree/trunk/docs/QuickRef.txt). Download, build, and install the acme assembler by typing:
|
There are two source projects you need to download: the first is a nice cross-platform 6502 assembler called [acme](http://sourceforge.net/p/acme-crossass/code-0/6/tree/trunk/docs/QuickRef.txt). Download, build, and install the acme assembler by typing:
|
||||||
|
|
||||||
@ -124,7 +126,7 @@ cd ../..
|
|||||||
|
|
||||||
Under Unix that `cp` command may have to be preceded by `sudo` to elevate the privileges to copy into `/usr/local/bin`.
|
Under Unix that `cp` command may have to be preceded by `sudo` to elevate the privileges to copy into `/usr/local/bin`.
|
||||||
|
|
||||||
## PLASMA Source
|
### PLASMA Source
|
||||||
|
|
||||||
Now, to download PLASMA and build it, type:
|
Now, to download PLASMA and build it, type:
|
||||||
|
|
||||||
@ -134,7 +136,7 @@ cd PLASMA/src
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
### Portable VM
|
#### Portable VM
|
||||||
|
|
||||||
To see if everything built correctly, type:
|
To see if everything built correctly, type:
|
||||||
|
|
||||||
@ -166,6 +168,22 @@ to run the module. You will be rewarded with `Hello, world.` printed to the scre
|
|||||||
|
|
||||||
and you should see the same screenful of gibberish you saw from the portable VM, but on the Apple II this time. Both VMs are running the exact same module binaries. To view the source of these modules refer to `PLASMA/src/samplesrc/hello.pla`, `PLASMA/src/samplesrc/test.pla`, and `PLASMA/src/samplesrc/testlib.pla`. To get even more insight into the compiled source, view the corresponding `.a` files.
|
and you should see the same screenful of gibberish you saw from the portable VM, but on the Apple II this time. Both VMs are running the exact same module binaries. To view the source of these modules refer to `PLASMA/src/samplesrc/hello.pla`, `PLASMA/src/samplesrc/test.pla`, and `PLASMA/src/samplesrc/testlib.pla`. To get even more insight into the compiled source, view the corresponding `.a` files.
|
||||||
|
|
||||||
|
## PLASMA Target Hosted Compiler
|
||||||
|
|
||||||
|
The PLASMA compiler is also self-hosted on the Apple II and III. The PLASMA system and development disks can be run on a real or emulated machine. It is recommended to copy the files to a hard disk, or similar mass storage device. Boot the PLASMA system and change the prefix to the development disk/directory. The 'HELLO.PLA' source file should be there. To compile the module, type:
|
||||||
|
|
||||||
|
```
|
||||||
|
+PLASM HELLO.PLA
|
||||||
|
```
|
||||||
|
|
||||||
|
After the compiler loads (which can take some time on an un-accelerated machine), you will see the compiler banner message. The complilation process prints out a `.` once in awhile. When compilation is complete, the module will be written to disk, and the prompt will return. To execute the module, type:
|
||||||
|
|
||||||
|
```
|
||||||
|
+HELLO
|
||||||
|
```
|
||||||
|
|
||||||
|
and just like with the cross-compiled module, you will get the `Hello, word.` message printed to the screen.
|
||||||
|
|
||||||
# Tutorial
|
# Tutorial
|
||||||
|
|
||||||
During KansasFest 2015, I gave a PLASMA introduction using the Apple II PLASMA sandbox IDE. You can play along using your favorite Apple II emulator, or one that runs directly in your browser: [Apple II Emulator in Javascript](https://www.scullinsteel.com/apple/e). Download [SANDBOX.PO](https://github.com/dschmenk/PLASMA/blob/master/SANDBOX.PO?raw=true) and load it into Drive 1 of the emulator. Start the [KansasFest PLASMA Code-along video](https://www.youtube.com/watch?v=RrR79WVHwJo?t=11m24s) and follow along.
|
During KansasFest 2015, I gave a PLASMA introduction using the Apple II PLASMA sandbox IDE. You can play along using your favorite Apple II emulator, or one that runs directly in your browser: [Apple II Emulator in Javascript](https://www.scullinsteel.com/apple/e). Download [SANDBOX.PO](https://github.com/dschmenk/PLASMA/blob/master/SANDBOX.PO?raw=true) and load it into Drive 1 of the emulator. Start the [KansasFest PLASMA Code-along video](https://www.youtube.com/watch?v=RrR79WVHwJo?t=11m24s) and follow along.
|
||||||
@ -178,11 +196,11 @@ Although the low-level PLASMA VM operations could easily by coded by hand, they
|
|||||||
|
|
||||||
## PLASMA Modules
|
## PLASMA Modules
|
||||||
|
|
||||||
PLASMA programs are built up around modules: small, self contained, dynamically loaded and linked software components that provide a well defined interface to other modules. The module format extends the .REL file type 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.
|
PLASMA programs are built up around modules: small, self contained, dynamically loaded and linked software components that provide a well defined interface to other modules. The module format extends the .REL file type 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. Modules are first-class citizens in PLASMA: an imported module is assigned to a variable which can be accessed like any other.
|
||||||
|
|
||||||
## Data Types
|
## Data Types
|
||||||
|
|
||||||
PLASMA only defines two data types: `byte` and `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 integer, an address, or anything that fits in 16 bits. There are a number of address operators to identify how an address value is to be interpreted.
|
PLASMA only defines two data types: `char`(or `byte`) and `var`(or `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 integer, an address, or anything that fits in 16 bits. There are a number of address operators to identify how an address value is to be interpreted.
|
||||||
|
|
||||||
## Obligatory 'Hello World'
|
## Obligatory 'Hello World'
|
||||||
|
|
||||||
@ -258,8 +276,8 @@ end
|
|||||||
|
|
||||||
import testlib
|
import testlib
|
||||||
predef puti
|
predef puti
|
||||||
byte testdata, teststring
|
char testdata, teststring
|
||||||
word testarray
|
var testarray
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -301,9 +319,9 @@ There is a shortcut for defining constant offsets into structures:
|
|||||||
|
|
||||||
```
|
```
|
||||||
struc t_entry
|
struc t_entry
|
||||||
word id
|
var id
|
||||||
byte[32] name
|
char[32] name
|
||||||
word next_entry
|
var next_entry
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -357,7 +375,7 @@ Strings are defined like Pascal strings, a length byte followed by the string ch
|
|||||||
//
|
//
|
||||||
// An initialized string of 64 characters
|
// An initialized string of 64 characters
|
||||||
//
|
//
|
||||||
byte[64] txtfile = "UNTITLED"
|
char[64] txtfile = "UNTITLED"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Function Definitions
|
### Function Definitions
|
||||||
@ -446,7 +464,7 @@ Values can be treated as pointers by preceding them with a `^` for byte pointers
|
|||||||
|
|
||||||
```
|
```
|
||||||
char[] hellostr = "Hello"
|
char[] hellostr = "Hello"
|
||||||
word srcstr, strlen
|
var srcstr, strlen
|
||||||
|
|
||||||
srcstr = @hellostr // srcstr points to address of hellostr
|
srcstr = @hellostr // srcstr points to address of hellostr
|
||||||
strlen = ^srcstr // the first byte srcstr points to is the string length
|
strlen = ^srcstr // the first byte srcstr points to is the string length
|
||||||
@ -456,8 +474,8 @@ Functions with parameters or expressions to be used as a function address to cal
|
|||||||
|
|
||||||
```
|
```
|
||||||
predef keyin2plus
|
predef keyin2plus
|
||||||
word keyin
|
var keyin
|
||||||
byte key
|
char key
|
||||||
|
|
||||||
keyin = @keyin2plus // address-of keyin2plus function
|
keyin = @keyin2plus // address-of keyin2plus function
|
||||||
key = keyin()
|
key = keyin()
|
||||||
@ -589,14 +607,14 @@ Here is an example using the `import`s from the previous examples to export an i
|
|||||||
```
|
```
|
||||||
predef mydef(var)
|
predef mydef(var)
|
||||||
|
|
||||||
export word[10] myfuncs = @putc, @mydef, $0000
|
export var[10] myfuncs = @putc, @mydef, $0000
|
||||||
```
|
```
|
||||||
|
|
||||||
Exporting functions is simple:
|
Exporting functions is simple:
|
||||||
|
|
||||||
```
|
```
|
||||||
export def plot(x, y)
|
export def plot(x, y)
|
||||||
romcall(y, 0, x, 0, $F800)
|
call($F800, y, 0, x, 0)
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -622,7 +640,7 @@ call(addr, aReg, xReg, yReg, statusReg) returns a pointer to a four-byte structu
|
|||||||
const xreg = 1
|
const xreg = 1
|
||||||
const getlin = $FD6A
|
const getlin = $FD6A
|
||||||
|
|
||||||
numchars = call(getlin, 0, 0, 0, 0).xreg // return char count in X reg
|
numchars = call(getlin, 0, 0, 0, 0)->xreg // return char count in X reg
|
||||||
```
|
```
|
||||||
|
|
||||||
syscall(cmd, params) calls ProDOS, returning the status value.
|
syscall(cmd, params) calls ProDOS, returning the status value.
|
||||||
@ -644,14 +662,14 @@ putc(char), puts(string), home, gotoxy(x,y), getc() and gets() are other handy u
|
|||||||
|
|
||||||
```
|
```
|
||||||
putc('.')
|
putc('.')
|
||||||
byte okstr[] = "OK"
|
char okstr[] = "OK"
|
||||||
puts(@okstr)
|
puts(@okstr)
|
||||||
```
|
```
|
||||||
|
|
||||||
memset(addr, val, len) will fill memory with a 16-bit value. memcpy(dstaddr, srcaddr, len) will copy memory from one address to another, taking care to copy in the proper direction.
|
memset(addr, val, len) will fill memory with a 16-bit value. memcpy(dstaddr, srcaddr, len) will copy memory from one address to another, taking care to copy in the proper direction.
|
||||||
|
|
||||||
```
|
```
|
||||||
byte nullstr[] = ""
|
char nullstr[] = ""
|
||||||
memset(strlinbuf, @nullstr, maxfill * 2) // fill line buff with pointer to null string
|
memset(strlinbuf, @nullstr, maxfill * 2) // fill line buff with pointer to null string
|
||||||
memcpy(scrnptr, strptr + ofst + 1, numchars)
|
memcpy(scrnptr, strptr + ofst + 1, numchars)
|
||||||
```
|
```
|
||||||
@ -719,8 +737,8 @@ predef myfunc
|
|||||||
|
|
||||||
byte smallarray[4]
|
byte smallarray[4]
|
||||||
byte initbarray[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
|
byte initbarray[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
|
||||||
byte string[64] = "Initialized string"
|
char string[64] = "Initialized string"
|
||||||
word wlabel[]
|
var wlabel[]
|
||||||
word = 1000, 2000, 3000, 4000 // Anonymous array
|
word = 1000, 2000, 3000, 4000 // Anonymous array
|
||||||
word funclist = @myfunc, $0000
|
word funclist = @myfunc, $0000
|
||||||
```
|
```
|
||||||
@ -732,14 +750,33 @@ predef myfunc(var)#0
|
|||||||
|
|
||||||
byte[4] smallarray
|
byte[4] smallarray
|
||||||
byte[] initbarray = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
|
byte[] initbarray = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
|
||||||
byte[64] string = "Initialized string"
|
char[64] string = "Initialized string"
|
||||||
word[] wlabel
|
var[] wlabel
|
||||||
word = 1000, 2000, 3000, 4000 // Anonymous array
|
word = 1000, 2000, 3000, 4000 // Anonymous array
|
||||||
word funclist = @myfunc, $0000
|
word funclist = @myfunc, $0000
|
||||||
```
|
```
|
||||||
|
|
||||||
Arrays can be uninitialized and reserve a size, as in `smallarray` above. Initialized arrays without a size specified in the definition will take up as much data as is present, as in `initbarray` above. Strings are special arrays that include a hidden length byte in the beginning (Pascal strings). When specified with a size, a minimum size is reserved for the string value. Labels can be defined as arrays without size or initializers; this can be useful when overlapping labels with other arrays or defining the actual array data as anonymous arrays in following lines as in `wlabel` and following lines. Addresses of other data (must be defined previously) or function definitions (pre-defined with predef), including imported references, can be initializers.
|
Arrays can be uninitialized and reserve a size, as in `smallarray` above. Initialized arrays without a size specified in the definition will take up as much data as is present, as in `initbarray` above. Strings are special arrays that include a hidden length byte in the beginning (Pascal strings). When specified with a size, a minimum size is reserved for the string value. Labels can be defined as arrays without size or initializers; this can be useful when overlapping labels with other arrays or defining the actual array data as anonymous arrays in following lines as in `wlabel` and following lines. Addresses of other data (must be defined previously) or function definitions (pre-defined with predef), including imported references, can be initializers.
|
||||||
|
|
||||||
|
The base array size can be used to initialize multiple variable of arbitrary size. Three, four byte values can be defined as such:
|
||||||
|
|
||||||
|
```
|
||||||
|
byte[4] a, b, c
|
||||||
|
```
|
||||||
|
|
||||||
|
All three variables will have 4 bytes reserved for them. If you combine a base size with an array size, you can define multiple large values. For instance,
|
||||||
|
|
||||||
|
```
|
||||||
|
byte[4] a[5]
|
||||||
|
```
|
||||||
|
|
||||||
|
will assign an array of five, four byte elements, for a total of 20 bytes. This may make more sense when we combine the alias for `byte`, `res` with structure definitions. An array of five structures would look like:
|
||||||
|
|
||||||
|
```
|
||||||
|
res[t_record] patient[20]
|
||||||
|
```
|
||||||
|
The result would be to reserve 20 patient records.
|
||||||
|
|
||||||
#### Type Overrides
|
#### Type Overrides
|
||||||
|
|
||||||
Arrays are usually identified by the data type specifier, `byte` or `word` when the array is defined. However, this can be overridden with the type override specifiers: `:` and `.`. `:` overrides the type to be `word`, `.` overrides the type to be `byte`. An example of accessing a `word` array as `bytes`:
|
Arrays are usually identified by the data type specifier, `byte` or `word` when the array is defined. However, this can be overridden with the type override specifiers: `:` and `.`. `:` overrides the type to be `word`, `.` overrides the type to be `byte`. An example of accessing a `word` array as `bytes`:
|
||||||
|
@ -2,16 +2,16 @@ import cmdsys
|
|||||||
//
|
//
|
||||||
// Useful values for everyone
|
// Useful values for everyone
|
||||||
//
|
//
|
||||||
const FALSE = 0
|
const _SYSVER_ = $0100 // Version built against
|
||||||
const TRUE = not FALSE
|
const FALSE = 0
|
||||||
const NULL = 0
|
const TRUE = not FALSE
|
||||||
|
const NULL = 0
|
||||||
//
|
//
|
||||||
// Machine ID values
|
// Machine ID values
|
||||||
//
|
//
|
||||||
const MACHID_CLOCK = $01
|
const MACHID_CLOCK = $01
|
||||||
const MACHID_80COL = $02
|
const MACHID_80COL = $02
|
||||||
const MACHID_MEM = $03
|
const MACHID_MEM = $03
|
||||||
const MACHID_48K = $10
|
|
||||||
const MACHID_64K = $20
|
const MACHID_64K = $20
|
||||||
const MACHID_128K = $30
|
const MACHID_128K = $30
|
||||||
const MACHID_MODEL = $C8
|
const MACHID_MODEL = $C8
|
||||||
@ -39,12 +39,23 @@ import cmdsys
|
|||||||
const modkeep = $2000
|
const modkeep = $2000
|
||||||
const modinitkeep = $4000
|
const modinitkeep = $4000
|
||||||
//
|
//
|
||||||
|
// CMD exported interface table
|
||||||
|
//
|
||||||
|
struc t_cmdsys
|
||||||
|
word sysver
|
||||||
|
word syspath
|
||||||
|
word cmdline
|
||||||
|
word modexec
|
||||||
|
byte refcons
|
||||||
|
byte devcons
|
||||||
|
end
|
||||||
|
//
|
||||||
// CMD exported functions
|
// CMD exported functions
|
||||||
//
|
//
|
||||||
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, toupper(c)#1
|
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, putb(b)#0, puth(h)#0
|
||||||
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
|
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
|
||||||
predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1, heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
|
predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1
|
||||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
predef heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
|
||||||
predef divmod(a,b)#2, isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
|
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1
|
||||||
predef modload(mod)#1, modexec(modfile)#1, modaddr(str)#1
|
predef toupper(c)#1, sext(a)#1, divmod(a,b)#2, isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
|
||||||
end
|
end
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
import conio
|
import conio
|
||||||
const NORMAL = $FF
|
const NORMAL = $FF
|
||||||
const INVERSE = $3F
|
const INVERSE = $3F
|
||||||
const FLASH = $7F
|
const FLASH = $7F
|
||||||
struc t_conio
|
struc t_conio
|
||||||
word keypressed
|
word keypressed
|
||||||
word home
|
word home
|
||||||
word gotoxy
|
word gotoxy
|
||||||
word viewport
|
word viewport
|
||||||
word texttype
|
word texttype
|
||||||
word textmode
|
word textmode
|
||||||
word grmode
|
word grmode
|
||||||
word grcolor
|
word grcolor
|
||||||
word grplot
|
word grplot
|
||||||
end
|
end
|
||||||
word conio
|
|
||||||
end
|
end
|
||||||
|
@ -49,7 +49,6 @@ import fileio
|
|||||||
word readblock
|
word readblock
|
||||||
word writeblock
|
word writeblock
|
||||||
end
|
end
|
||||||
word fileio
|
|
||||||
//
|
//
|
||||||
// Globally accessible error code
|
// Globally accessible error code
|
||||||
//
|
//
|
||||||
|
@ -112,5 +112,4 @@ struc t_fpu
|
|||||||
word randNum
|
word randNum
|
||||||
end
|
end
|
||||||
const dropX = shiftDown // Alias dropX and shiftDown
|
const dropX = shiftDown // Alias dropX and shiftDown
|
||||||
word fpu
|
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// iNet API
|
// iNet API
|
||||||
//
|
//
|
||||||
import inet
|
import iNet
|
||||||
struc t_inet
|
struc t_inet
|
||||||
word initIP
|
word initIP
|
||||||
word serviceIP
|
word serviceIP
|
||||||
@ -19,5 +19,4 @@ struc t_inet
|
|||||||
word setCallback
|
word setCallback
|
||||||
word setParam
|
word setParam
|
||||||
end
|
end
|
||||||
word iNet
|
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import longjmp
|
import longjmp
|
||||||
const t_longjmp = $0140
|
const t_except = $0140
|
||||||
predef setjmp(env), longjmp(env, retval)
|
predef except(env), throw(env, retval)
|
||||||
end
|
end
|
||||||
|
@ -142,5 +142,4 @@ struc t_sane
|
|||||||
word saveZP
|
word saveZP
|
||||||
word restoreZP
|
word restoreZP
|
||||||
end
|
end
|
||||||
word sane
|
|
||||||
end
|
end
|
||||||
|
@ -17,7 +17,7 @@ import sdFAT
|
|||||||
//
|
//
|
||||||
// Interface
|
// Interface
|
||||||
//
|
//
|
||||||
struc t_fatio
|
struc t_sdFAT
|
||||||
word getDir
|
word getDir
|
||||||
word setDir
|
word setDir
|
||||||
word newDir
|
word newDir
|
||||||
@ -41,5 +41,4 @@ import sdFAT
|
|||||||
word isDir
|
word isDir
|
||||||
word isFile
|
word isFile
|
||||||
end
|
end
|
||||||
word sdFAT // sdFAT interface
|
|
||||||
end
|
end
|
||||||
|
@ -4,5 +4,5 @@ import testlib
|
|||||||
const hex = 2
|
const hex = 2
|
||||||
const newln = 4
|
const newln = 4
|
||||||
const str = 6
|
const str = 6
|
||||||
const char = 8
|
const chr = 8
|
||||||
end
|
end
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
include "inc/cmdsys.plh"
|
include "inc/cmdsys.plh"
|
||||||
const cmdline = $01FF
|
|
||||||
|
|
||||||
def argDelim(str)
|
def argDelim(str)
|
||||||
byte n
|
byte n
|
||||||
|
|
||||||
// Strip leading spaces
|
// Skip leading spaces
|
||||||
while ^str and ^(str + 1) == ' '
|
while ^str and ^(str + 1) == ' '
|
||||||
memcpy(str + 1, str + 2, ^str - 1)
|
^(str + 1) = ^str - 1
|
||||||
^str--
|
str++
|
||||||
loop
|
loop
|
||||||
// Scan to trailing spaces (if any)
|
// Scan to trailing spaces (if any)
|
||||||
for n = 1 to ^str
|
for n = 1 to ^str
|
||||||
@ -26,9 +25,8 @@ export def argNext(str)
|
|||||||
end
|
end
|
||||||
|
|
||||||
export def argFirst
|
export def argFirst
|
||||||
// NULL terminate command line
|
^(cmdsys:cmdline + ^cmdsys:cmdline + 1) = NULL
|
||||||
^(cmdline + ^cmdline + 1) = 0
|
return argDelim(cmdsys:cmdline)
|
||||||
return argDelim(cmdline)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
done
|
done
|
||||||
|
@ -22,6 +22,9 @@ const hgr1 = $2000
|
|||||||
const hgr2 = $4000
|
const hgr2 = $4000
|
||||||
const page1 = 0
|
const page1 = 0
|
||||||
const page2 = 1
|
const page2 = 1
|
||||||
|
//
|
||||||
|
// External interface
|
||||||
|
//
|
||||||
struc t_conio
|
struc t_conio
|
||||||
word keypressed
|
word keypressed
|
||||||
word home
|
word home
|
||||||
@ -39,31 +42,9 @@ end
|
|||||||
predef a2keypressed,a2home,a2gotoxy(x,y),a2viewport(left, top, width, height),a2texttype(type)
|
predef a2keypressed,a2home,a2gotoxy(x,y),a2viewport(left, top, width, height),a2texttype(type)
|
||||||
predef a2textmode(cols),a2grmode(mix),a2grcolor(color),a2grplot(x,y)
|
predef a2textmode(cols),a2grmode(mix),a2grcolor(color),a2grplot(x,y)
|
||||||
//
|
//
|
||||||
// Screen row address arrays.
|
|
||||||
//
|
|
||||||
word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
|
|
||||||
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
|
|
||||||
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
|
|
||||||
word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
|
|
||||||
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
|
|
||||||
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
|
|
||||||
//
|
|
||||||
// Text screen parameters.
|
|
||||||
//
|
|
||||||
byte textcols = 40
|
|
||||||
byte curshpos = 0
|
|
||||||
byte cursvpos = 0
|
|
||||||
//
|
|
||||||
// Apple 3 console codes.
|
|
||||||
//
|
|
||||||
byte textbwmode[] = 2, 16, 0
|
|
||||||
byte textclrmode[] = 2, 16, 1
|
|
||||||
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
|
|
||||||
byte devcons
|
|
||||||
//
|
|
||||||
// Exported function table.
|
// Exported function table.
|
||||||
//
|
//
|
||||||
export word conio[]
|
word conio[]
|
||||||
//
|
//
|
||||||
// Function pointers.
|
// Function pointers.
|
||||||
//
|
//
|
||||||
@ -77,6 +58,27 @@ word = @a2grmode
|
|||||||
word = @a2grcolor
|
word = @a2grcolor
|
||||||
word = @a2grplot
|
word = @a2grplot
|
||||||
//
|
//
|
||||||
|
// Screen row address arrays.
|
||||||
|
//
|
||||||
|
word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
|
||||||
|
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
|
||||||
|
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
|
||||||
|
word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
|
||||||
|
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
|
||||||
|
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
|
||||||
|
//
|
||||||
|
// Text screen parameters.
|
||||||
|
//
|
||||||
|
//byte textcols = 40
|
||||||
|
//byte curshpos = 0
|
||||||
|
//byte cursvpos = 0
|
||||||
|
//
|
||||||
|
// Apple 3 console codes.
|
||||||
|
//
|
||||||
|
byte textbwmode[] = 2, 16, 0
|
||||||
|
byte textclrmode[] = 2, 16, 1
|
||||||
|
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
|
||||||
|
//
|
||||||
// Native routines.
|
// Native routines.
|
||||||
//
|
//
|
||||||
asm equates
|
asm equates
|
||||||
@ -153,8 +155,8 @@ def a1home
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
def a1gotoxy(x, y)
|
def a1gotoxy(x, y)
|
||||||
curshpos = x
|
//curshpos = x
|
||||||
cursvpos = y
|
//cursvpos = y
|
||||||
putln
|
putln
|
||||||
while x
|
while x
|
||||||
putc(' ')
|
putc(' ')
|
||||||
@ -181,13 +183,13 @@ def a2keypressed
|
|||||||
return ^keyboard >= 128
|
return ^keyboard >= 128
|
||||||
end
|
end
|
||||||
def a2home
|
def a2home
|
||||||
curshpos = 0
|
//curshpos = 0
|
||||||
cursvpos = 0
|
//cursvpos = 0
|
||||||
return call($FC58, 0, 0, 0, 0) // home()
|
return call($FC58, 0, 0, 0, 0) // home()
|
||||||
end
|
end
|
||||||
def a2gotoxy(x, y)
|
def a2gotoxy(x, y)
|
||||||
curshpos = x
|
//curshpos = x
|
||||||
cursvpos = y
|
//cursvpos = y
|
||||||
^$24 = x + ^$20
|
^$24 = x + ^$20
|
||||||
return call($FB5B, y + ^$22, 0, 0, 0)
|
return call($FB5B, y + ^$22, 0, 0, 0)
|
||||||
end
|
end
|
||||||
@ -244,18 +246,18 @@ def dev_status(devnum, code, list)
|
|||||||
end
|
end
|
||||||
def a3keypressed
|
def a3keypressed
|
||||||
byte count
|
byte count
|
||||||
dev_status(devcons, 5, @count)
|
dev_status(cmdsys.devcons, 5, @count)
|
||||||
return count
|
return count
|
||||||
end
|
end
|
||||||
def a3home
|
def a3home
|
||||||
curshpos = 0
|
//curshpos = 0
|
||||||
cursvpos = 0
|
//cursvpos = 0
|
||||||
putc(28)
|
putc(28)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
def a3gotoxy(x, y)
|
def a3gotoxy(x, y)
|
||||||
curshpos = x
|
//curshpos = x
|
||||||
cursvpos = y
|
//cursvpos = y
|
||||||
putc(24)
|
putc(24)
|
||||||
putc(x)
|
putc(x)
|
||||||
putc(25)
|
putc(25)
|
||||||
@ -269,7 +271,7 @@ def a3viewport(left, top, width, height)
|
|||||||
//
|
//
|
||||||
left = 0
|
left = 0
|
||||||
top = 0
|
top = 0
|
||||||
width = textcols
|
width = 40//textcols
|
||||||
height = 24
|
height = 24
|
||||||
fin
|
fin
|
||||||
putc(1) // Reset viewport
|
putc(1) // Reset viewport
|
||||||
@ -304,7 +306,7 @@ def a3grmode(mix)
|
|||||||
mix = 23
|
mix = 23
|
||||||
fin
|
fin
|
||||||
puts(@textclrmode)
|
puts(@textclrmode)
|
||||||
dev_control(devcons, 17, @grcharset)
|
dev_control(cmdsys.devcons, 17, @grcharset)
|
||||||
a3viewport(0, 20, 40, 4)
|
a3viewport(0, 20, 40, 4)
|
||||||
for i = 0 to mix
|
for i = 0 to mix
|
||||||
memset(txt1scrn[i], 40, $0000) // text screen
|
memset(txt1scrn[i], 40, $0000) // text screen
|
||||||
@ -315,8 +317,8 @@ end
|
|||||||
//
|
//
|
||||||
// Machine specific initialization.
|
// Machine specific initialization.
|
||||||
//
|
//
|
||||||
when MACHID & $C8
|
when MACHID & MACHID_MODEL
|
||||||
is $08 // Apple 1
|
is MACHID_I
|
||||||
conio:keypressed = @a1keypressed
|
conio:keypressed = @a1keypressed
|
||||||
conio:home = @a1home
|
conio:home = @a1home
|
||||||
conio:gotoxy = @a1gotoxy
|
conio:gotoxy = @a1gotoxy
|
||||||
@ -325,7 +327,7 @@ when MACHID & $C8
|
|||||||
conio:textmode = @a1textmode
|
conio:textmode = @a1textmode
|
||||||
conio:grmode = @a1grmode
|
conio:grmode = @a1grmode
|
||||||
break
|
break
|
||||||
is $C0 // Apple ///
|
is MACHID_III
|
||||||
conio:keypressed = @a3keypressed
|
conio:keypressed = @a3keypressed
|
||||||
conio:home = @a3home
|
conio:home = @a3home
|
||||||
conio:gotoxy = @a3gotoxy
|
conio:gotoxy = @a3gotoxy
|
||||||
@ -333,8 +335,7 @@ when MACHID & $C8
|
|||||||
conio:texttype = @a3texttype
|
conio:texttype = @a3texttype
|
||||||
conio:textmode = @a3textmode
|
conio:textmode = @a3textmode
|
||||||
conio:grmode = @a3grmode
|
conio:grmode = @a3grmode
|
||||||
devcons = modaddr("CMDSYS").5 // devcons variable from STDLIB
|
|
||||||
break
|
break
|
||||||
otherwise // Apple ][
|
//otherwise // MACHID_II
|
||||||
wend
|
wend
|
||||||
done
|
done
|
||||||
|
@ -653,16 +653,16 @@ fin
|
|||||||
//
|
//
|
||||||
// Assembly fixups
|
// Assembly fixups
|
||||||
//
|
//
|
||||||
*(@_dgrPlotPix):1 = @_dgrSetPix
|
_dgrPlotPix:1 = @_dgrSetPix
|
||||||
*(@_dgrHLinPix):1 = @_dgrSetPix
|
_dgrHLinPix:1 = @_dgrSetPix
|
||||||
*(@_dgrVLinPix):1 = @_dgrSetPix
|
_dgrVLinPix:1 = @_dgrSetPix
|
||||||
*(@_dgrBLTPix):1 = @_dgrSetPix
|
_dgrBLTPix:1 = @_dgrSetPix
|
||||||
*(@_dgrTileTile):1 = @dgrTile
|
_dgrTileTile:1 = @dgrTile
|
||||||
*(@_dgrFillTile):1 = @dgrTile
|
_dgrFillTile:1 = @dgrTile
|
||||||
*(@_dgrSetEvnEvn):1 = @evnclr
|
_dgrSetEvnEvn:1 = @evnclr
|
||||||
*(@_dgrSetEvnOdd):1 = @oddclr
|
_dgrSetEvnOdd:1 = @oddclr
|
||||||
*(@_dgrSetOddEvn):1 = @evnclr
|
_dgrSetOddEvn:1 = @evnclr
|
||||||
*(@_dgrSetOddOdd):1 = @oddclr
|
_dgrSetOddOdd:1 = @oddclr
|
||||||
// Put read AUX mem routine in scary location
|
// Put read AUX mem routine in scary location
|
||||||
memcpy($0100, @auxRead, 9)
|
memcpy($0100, @auxRead, 9)
|
||||||
done
|
done
|
||||||
|
@ -20,7 +20,7 @@ const O_READ_WRITE = 3
|
|||||||
//
|
//
|
||||||
const sysbuf = $0800
|
const sysbuf = $0800
|
||||||
//
|
//
|
||||||
// All our file I/O routines
|
// External interface
|
||||||
//
|
//
|
||||||
struc t_fileio
|
struc t_fileio
|
||||||
word getpfx
|
word getpfx
|
||||||
@ -44,9 +44,10 @@ predef a23newline(refnum, emask, nlchar), a2readblock(unit, buf, block), a2write
|
|||||||
//
|
//
|
||||||
// Exported function table.
|
// Exported function table.
|
||||||
//
|
//
|
||||||
export word fileio[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2openbuf, @a2open, @a23close
|
word fileio[]
|
||||||
word = @a23read, @a2write, @a2create, @a23destroy
|
word = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2openbuf, @a2open, @a23close
|
||||||
word = @a23newline, @a2readblock, @a2writeblock
|
word = @a23read, @a2write, @a2create, @a23destroy
|
||||||
|
word = @a23newline, @a2readblock, @a2writeblock
|
||||||
//
|
//
|
||||||
// SOS/ProDOS error code
|
// SOS/ProDOS error code
|
||||||
//
|
//
|
||||||
|
@ -22,7 +22,8 @@ predef compXY, annuityXY, randNum(pSeed)
|
|||||||
//
|
//
|
||||||
// FP6502 functions
|
// FP6502 functions
|
||||||
//
|
//
|
||||||
export word fpu = @reset
|
//export word fpu = @reset
|
||||||
|
word fpu = @reset
|
||||||
word = @setEnv, @getEnv, @testExcept, @setExcept, @enterProc, @exitProc
|
word = @setEnv, @getEnv, @testExcept, @setExcept, @enterProc, @exitProc
|
||||||
word = @constPi, @constE
|
word = @constPi, @constE
|
||||||
word = @pushInt, @pushSgl, @pushDbl, @pushExt, @pushStr
|
word = @pushInt, @pushSgl, @pushDbl, @pushExt, @pushStr
|
||||||
|
@ -4,7 +4,7 @@ end
|
|||||||
//
|
//
|
||||||
// Save environment (PLASMA ZP and stack) for below and return 0
|
// Save environment (PLASMA ZP and stack) for below and return 0
|
||||||
//
|
//
|
||||||
export asm setjmp(env)
|
export asm except(env)
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
STA SRC
|
STA SRC
|
||||||
LDA ESTKH,X
|
LDA ESTKH,X
|
||||||
@ -33,7 +33,7 @@ end
|
|||||||
//
|
//
|
||||||
// Restore environment saved above and return retval
|
// Restore environment saved above and return retval
|
||||||
//
|
//
|
||||||
export asm longjmp(env, retval)
|
export asm throw(env, retval)
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
STA SRC
|
STA SRC
|
||||||
LDA ESTKH,X
|
LDA ESTKH,X
|
||||||
|
@ -16,7 +16,8 @@ end
|
|||||||
// External interface to SANE libraries
|
// External interface to SANE libraries
|
||||||
//
|
//
|
||||||
predef fpInit(), fpDefaultHalt(pstatus), uninit0(), uninit1(op, dst), uninit2(op, dst, src), uninit3(op, dst, src, src2)
|
predef fpInit(), fpDefaultHalt(pstatus), uninit0(), uninit1(op, dst), uninit2(op, dst, src), uninit3(op, dst, src, src2)
|
||||||
export word sane = @fpInit, @fpDefaultHalt, @uninit0, @uninit1, @uninit2, @uninit3, @uninit1, @uninit2, @uninit3, @uninit0, @uninit0
|
//export word sane = @fpInit, @fpDefaultHalt, @uninit0, @uninit1, @uninit2, @uninit3, @uninit1, @uninit2, @uninit3, @uninit0, @uninit0
|
||||||
|
word sane = @fpInit, @fpDefaultHalt, @uninit0, @uninit1, @uninit2, @uninit3, @uninit1, @uninit2, @uninit3, @uninit0, @uninit0
|
||||||
//
|
//
|
||||||
// Pointer to FP6502 entry
|
// Pointer to FP6502 entry
|
||||||
//
|
//
|
||||||
@ -726,10 +727,11 @@ end
|
|||||||
def loadcode(codefile)
|
def loadcode(codefile)
|
||||||
byte ref
|
byte ref
|
||||||
word pcode, seglen
|
word pcode, seglen
|
||||||
|
byte filepath[64]
|
||||||
|
|
||||||
//puts(codefile); puts(":\n")
|
//puts(codefile); puts(":\n")
|
||||||
pcode = 0
|
pcode = 0
|
||||||
ref = fileio:open(codefile)
|
ref = fileio:open(strcat(strcpy(@filepath, cmdsys:syspath), codefile))
|
||||||
//puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln
|
//puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln
|
||||||
if ref
|
if ref
|
||||||
pcode = heapmark
|
pcode = heapmark
|
||||||
|
@ -77,7 +77,7 @@ end
|
|||||||
//
|
//
|
||||||
// String functions
|
// String functions
|
||||||
//
|
//
|
||||||
def strcat(dst, src1, src2)
|
def strcat2(dst, src1, src2)
|
||||||
memcpy(dst + 1, src1 + 1, ^src1)
|
memcpy(dst + 1, src1 + 1, ^src1)
|
||||||
memcpy(dst + 1 + ^src1, src2 + 1, ^src2)
|
memcpy(dst + 1 + ^src1, src2 + 1, ^src2)
|
||||||
^dst = ^src1 + ^src2
|
^dst = ^src1 + ^src2
|
||||||
@ -141,7 +141,7 @@ def servHTTP(remip, remport, lclport, data, len, param)
|
|||||||
url = url + 1
|
url = url + 1
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
strcat(@filename, @prefix, url)
|
strcat2(@filename, @prefix, url)
|
||||||
puts("GET:"); puts(@filename);putln
|
puts("GET:"); puts(@filename);putln
|
||||||
//
|
//
|
||||||
// Get file info
|
// Get file info
|
||||||
@ -152,9 +152,9 @@ def servHTTP(remip, remport, lclport, data, len, param)
|
|||||||
if refnum // file was opened OK
|
if refnum // file was opened OK
|
||||||
filelen = fileio:geteof(refnum) // get length of file for Content-Length
|
filelen = fileio:geteof(refnum) // get length of file for Content-Length
|
||||||
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
|
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
|
||||||
strcat(@okhdr, @httpOK, @httpContentLen)
|
strcat2(@okhdr, @httpOK, @httpContentLen)
|
||||||
strcat(@okhdr, @okhdr, @lenstr)
|
strcat2(@okhdr, @okhdr, @lenstr)
|
||||||
strcat(@okhdr, @okhdr, "\n\r")
|
strcat2(@okhdr, @okhdr, "\n\r")
|
||||||
//
|
//
|
||||||
// Content type header
|
// Content type header
|
||||||
//
|
//
|
||||||
@ -163,23 +163,23 @@ def servHTTP(remip, remport, lclport, data, len, param)
|
|||||||
// this a text file
|
// this a text file
|
||||||
//
|
//
|
||||||
//puts(@mimeTextHtml) // debug
|
//puts(@mimeTextHtml) // debug
|
||||||
strcat(@okhdr, @okhdr, @httpContentType)
|
strcat2(@okhdr, @okhdr, @httpContentType)
|
||||||
strcat(@okhdr, @okhdr, @mimeTextHtml)
|
strcat2(@okhdr, @okhdr, @mimeTextHtml)
|
||||||
else
|
else
|
||||||
//
|
//
|
||||||
// send as binary attachment
|
// send as binary attachment
|
||||||
//
|
//
|
||||||
//puts(@mimeOctetStream) // debug
|
//puts(@mimeOctetStream) // debug
|
||||||
strcat(@okhdr, @okhdr, @httpContentType)
|
strcat2(@okhdr, @okhdr, @httpContentType)
|
||||||
strcat(@okhdr, @okhdr, @mimeOctetStream)
|
strcat2(@okhdr, @okhdr, @mimeOctetStream)
|
||||||
strcat(@okhdr, @okhdr, "\n\r")
|
strcat2(@okhdr, @okhdr, "\n\r")
|
||||||
//
|
//
|
||||||
// and send filename too
|
// and send filename too
|
||||||
//
|
//
|
||||||
strcat(@okhdr, @okhdr, @httpContentAttach)
|
strcat2(@okhdr, @okhdr, @httpContentAttach)
|
||||||
// todo: get the base filename...
|
// todo: get the base filename...
|
||||||
fin
|
fin
|
||||||
strcat(@okhdr, @okhdr, @httpEnd)
|
strcat2(@okhdr, @okhdr, @httpEnd)
|
||||||
//dumpchars(@okhdr + 1, okhdr) // debug
|
//dumpchars(@okhdr + 1, okhdr) // debug
|
||||||
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client
|
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client
|
||||||
sendFile(refnum, socketHTTP, filelen) // send file data to client
|
sendFile(refnum, socketHTTP, filelen) // send file data to client
|
||||||
|
@ -3,13 +3,6 @@ include "inc/memmgr.plh"
|
|||||||
word a, b, c, d, e, memptr
|
word a, b, c, d, e, memptr
|
||||||
word memfre, memlrgst
|
word memfre, memlrgst
|
||||||
|
|
||||||
def putb(hexb)
|
|
||||||
return call($FDDA, hexb, 0, 0, 0)
|
|
||||||
end
|
|
||||||
def puth(hex)
|
|
||||||
return call($F941, hex >> 8, hex, 0, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
sbrk($3000) // Set small pool size
|
sbrk($3000) // Set small pool size
|
||||||
|
|
||||||
memfre=hmemFre(@memlrgst);puth(memfre); putc(' '); puth(memlrgst); putln
|
memfre=hmemFre(@memlrgst);puth(memfre); putc(' '); puth(memlrgst); putln
|
||||||
|
@ -3,17 +3,15 @@ include "inc/cmdsys.plh"
|
|||||||
const modkeep = $2000
|
const modkeep = $2000
|
||||||
const modinitkeep = $4000
|
const modinitkeep = $4000
|
||||||
|
|
||||||
byte cmdsys = "cmdsys"
|
|
||||||
|
|
||||||
byte[] initstr
|
byte[] initstr
|
||||||
byte = " ( )\n"
|
byte = " ( )\n"
|
||||||
byte = " )\\ ) ( /( (\n"
|
byte = " )\\ ) ( /( (\n"
|
||||||
byte = "(()/( )\\()) )\\ ) ( (\n"
|
byte = " (()/( )\\()) )\\ ) ( (\n"
|
||||||
byte = " /(_))((_)\\ (()/( )\\ )\\\n"
|
byte = " /(_))((_)\\ (()/( )\\ )\\\n"
|
||||||
byte = "(_)) ((_) /(_))_ _ ((_)((_)\n"
|
byte = "(_)) ((_) /(_))_ _ ((_)((_)\n"
|
||||||
byte = "| _ \\ / _ \\(_)) __|| | | || __|\n"
|
byte = "| _ \\ / _ \\(_)) __| | | | || __|\n"
|
||||||
byte = "| / | (_) | | (_ || |_| || _|\n"
|
byte = "| / | (_) | || (_ | |_| || _|\n"
|
||||||
byte = "|_|_\\ \\___/ \\___| \\___/ |___|\n"
|
byte = "|_|_\\\\___/ \\___| \\___/ |___|\n"
|
||||||
byte = "\n"
|
byte = "\n"
|
||||||
byte = " By Resman\n"
|
byte = " By Resman\n"
|
||||||
byte = " Artwork by Seth Sternberger\n"
|
byte = " Artwork by Seth Sternberger\n"
|
||||||
@ -40,7 +38,6 @@ const a2rndh = $4F
|
|||||||
word iobuff
|
word iobuff
|
||||||
|
|
||||||
word a3rndnum = 12345
|
word a3rndnum = 12345
|
||||||
byte devcons
|
|
||||||
|
|
||||||
def a3rnd
|
def a3rnd
|
||||||
a3rndnum = (a3rndnum << 1) + a3rndnum + 123
|
a3rndnum = (a3rndnum << 1) + a3rndnum + 123
|
||||||
@ -182,7 +179,7 @@ def dev_status(devnum, code, list)
|
|||||||
end
|
end
|
||||||
def a3keypressed
|
def a3keypressed
|
||||||
byte count
|
byte count
|
||||||
dev_status(devcons, 5, @count)
|
dev_status(cmdsys.devcons, 5, @count)
|
||||||
return count
|
return count
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -233,7 +230,6 @@ when MACHID & $C8
|
|||||||
home = @a3home
|
home = @a3home
|
||||||
gotoxy = @a3gotoxy
|
gotoxy = @a3gotoxy
|
||||||
tone = @a3tone
|
tone = @a3tone
|
||||||
devcons = modaddr(@cmdsys).5 // devcons variable from cmdsys
|
|
||||||
open = @a3open
|
open = @a3open
|
||||||
read = @a3read
|
read = @a3read
|
||||||
close = @a3close
|
close = @a3close
|
||||||
|
@ -26,6 +26,10 @@ predef digitKey(pkey)#0, pointKey(pkey)#0, opKey(pkey)#0
|
|||||||
predef enterKey(pkey)#0, copyKey(pkey)#0, chsKey(pkey)#0, memKey(pkey)#0
|
predef enterKey(pkey)#0, copyKey(pkey)#0, chsKey(pkey)#0, memKey(pkey)#0
|
||||||
predef elemsKey(pkey)#0
|
predef elemsKey(pkey)#0
|
||||||
//
|
//
|
||||||
|
// Run state
|
||||||
|
//
|
||||||
|
byte quit = FALSE
|
||||||
|
//
|
||||||
// Current input
|
// Current input
|
||||||
//
|
//
|
||||||
byte inputStr[32] = ""
|
byte inputStr[32] = ""
|
||||||
@ -395,11 +399,13 @@ def cmdKey(pkey)#0
|
|||||||
// cmdLine = gets(':'|$80)
|
// cmdLine = gets(':'|$80)
|
||||||
word d
|
word d
|
||||||
|
|
||||||
showStatus("Press 1-9 for fix point digits:")
|
showStatus("Press 1-9 for fix point digits(Q=Quit):")
|
||||||
d = getc - '0'
|
d = toupper(getc) - '0'
|
||||||
if d >= 1 and d <= 9
|
if d >= 1 and d <= 9
|
||||||
displayFix = d
|
displayFix = d
|
||||||
displayInt = displayWidth - displayFix - 1
|
displayInt = displayWidth - displayFix - 1
|
||||||
|
elsif d == 'Q' - '0'
|
||||||
|
quit = TRUE
|
||||||
fin
|
fin
|
||||||
clearStatus
|
clearStatus
|
||||||
//
|
//
|
||||||
@ -417,7 +423,7 @@ def inputKey#0
|
|||||||
byte inkey
|
byte inkey
|
||||||
word pkeys
|
word pkeys
|
||||||
|
|
||||||
while 1
|
while not quit
|
||||||
pkeys = @keypad
|
pkeys = @keypad
|
||||||
conio:gotoxy(18, 7)
|
conio:gotoxy(18, 7)
|
||||||
inkey = toupper(getc)
|
inkey = toupper(getc)
|
||||||
@ -442,7 +448,7 @@ initInput
|
|||||||
showStack
|
showStack
|
||||||
showMem
|
showMem
|
||||||
showInput
|
showInput
|
||||||
showStatus("Version 0.5")
|
showStatus("Version 0.6")
|
||||||
inputKey
|
inputKey
|
||||||
conio:gotoxy(0, 22)
|
conio:gotoxy(0, 22)
|
||||||
done
|
done
|
||||||
|
@ -297,7 +297,7 @@ iB = 4
|
|||||||
iC = -1
|
iC = -1
|
||||||
zero = 0
|
zero = 0
|
||||||
puts("SANE sanity test...\n")
|
puts("SANE sanity test...\n")
|
||||||
sane.initFP()
|
sane:initFP()
|
||||||
sane:saveZP()
|
sane:saveZP()
|
||||||
sane:op2FP(FFINT|FOZ2X, @xT, @iA) // Convert int A to ext T
|
sane:op2FP(FFINT|FOZ2X, @xT, @iA) // Convert int A to ext T
|
||||||
sane:op2FP(FFINT|FOADD, @xT, @iB) // Add int B to ext T
|
sane:op2FP(FFINT|FOADD, @xT, @iB) // Add int B to ext T
|
||||||
|
@ -5,14 +5,14 @@ include "inc/cmdsys.plh"
|
|||||||
//
|
//
|
||||||
// Module data.
|
// Module data.
|
||||||
//
|
//
|
||||||
predef puth(h)#0
|
predef puthex(h)#0
|
||||||
export word print[] = @puti, @puth, @putln, @puts, @putc
|
export word print[] = @puti, @puthex, @putln, @puts, @putc
|
||||||
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||||
byte loadstr[] = "testlib loaded!"
|
byte loadstr[] = "testlib loaded!"
|
||||||
//
|
//
|
||||||
// Define functions.
|
// Define functions.
|
||||||
//
|
//
|
||||||
def puth(h)#0
|
def puthex(h)#0
|
||||||
putc('$')
|
putc('$')
|
||||||
putc(valstr[(h >> 12) & $0F])
|
putc(valstr[(h >> 12) & $0F])
|
||||||
putc(valstr[(h >> 8) & $0F])
|
putc(valstr[(h >> 8) & $0F])
|
||||||
|
@ -449,7 +449,10 @@ void emit_moddep(char *name, int len)
|
|||||||
if (outflags & MODULE)
|
if (outflags & MODULE)
|
||||||
{
|
{
|
||||||
if (name)
|
if (name)
|
||||||
|
{
|
||||||
emit_dci(name, len);
|
emit_dci(name, len);
|
||||||
|
idglobal_add(name, len, EXTERN_TYPE | WORD_TYPE, 2); // Add to symbol table
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
|
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
|
||||||
}
|
}
|
||||||
@ -989,7 +992,6 @@ int try_dupify(t_opseq *op)
|
|||||||
{
|
{
|
||||||
if (op->code != opn->code)
|
if (op->code != opn->code)
|
||||||
return crunched;
|
return crunched;
|
||||||
|
|
||||||
switch (op->code)
|
switch (op->code)
|
||||||
{
|
{
|
||||||
case CONST_CODE:
|
case CONST_CODE:
|
||||||
@ -1005,19 +1007,16 @@ int try_dupify(t_opseq *op)
|
|||||||
case GADDR_CODE:
|
case GADDR_CODE:
|
||||||
case LAB_CODE:
|
case LAB_CODE:
|
||||||
case LAW_CODE:
|
case LAW_CODE:
|
||||||
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) ||
|
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) /*|| (op->type != opn->type)*/)
|
||||||
(op->type != opn->type))
|
|
||||||
return crunched;
|
return crunched;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return crunched;
|
return crunched;
|
||||||
}
|
}
|
||||||
|
|
||||||
opn->code = DUP_CODE;
|
opn->code = DUP_CODE;
|
||||||
crunched = 1;
|
crunched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return crunched;
|
return crunched;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1,29 +1,4 @@
|
|||||||
//
|
//
|
||||||
// Symbol table
|
|
||||||
//
|
|
||||||
//def dumpsym(idptr, idcnt)#0
|
|
||||||
// while idcnt
|
|
||||||
// prword(idptr=>idval)
|
|
||||||
// cout(' ')
|
|
||||||
// prbyte(idptr->idtype)
|
|
||||||
// cout(' ')
|
|
||||||
// prstr(@idptr->idname)
|
|
||||||
// cout('=')
|
|
||||||
// if idptr->idtype & ADDR_TYPE
|
|
||||||
// if idptr=>idval & IS_CTAG
|
|
||||||
// prword((ctag_tbl=>[idptr=>idval & MASK_CTAG] & MASK_CTAG) + codebuff)
|
|
||||||
// else
|
|
||||||
// prword(idptr=>idval + codebuff)
|
|
||||||
// fin
|
|
||||||
// else
|
|
||||||
// prword(idptr=>idval)
|
|
||||||
// fin
|
|
||||||
// crout
|
|
||||||
// idptr = idptr + idptr->idname + t_id
|
|
||||||
// idcnt--
|
|
||||||
// loop
|
|
||||||
//end
|
|
||||||
//
|
|
||||||
// Address tags
|
// Address tags
|
||||||
//
|
//
|
||||||
def new_tag(type)
|
def new_tag(type)
|
||||||
@ -564,10 +539,11 @@ end
|
|||||||
//
|
//
|
||||||
// Module dependency list
|
// Module dependency list
|
||||||
//
|
//
|
||||||
def new_moddep(strptr, strlen)#0
|
def new_moddep(nameptr, len)#0
|
||||||
if strlen > 15; strlen = 15; fin
|
if len > 15; len = 15; fin
|
||||||
memcpy(@moddep_tbl[moddep_cnt*16] + 1, strptr, strlen)
|
new_iddata(nameptr, len, EXTERN_TYPE|WORD_TYPE, 2)
|
||||||
moddep_tbl[moddep_cnt*16] = strlen
|
memcpy(@moddep_tbl[moddep_cnt*16] + 1, nameptr, len)
|
||||||
|
moddep_tbl[moddep_cnt*16] = len
|
||||||
moddep_cnt++
|
moddep_cnt++
|
||||||
if moddep_cnt > 8; parse_warn("Module dependency overflow"); fin
|
if moddep_cnt > 8; parse_warn("Module dependency overflow"); fin
|
||||||
end
|
end
|
||||||
|
@ -193,7 +193,7 @@ def strpoolalloc(size)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def strcpy(dststr, srcstr)#0
|
def strstripcpy(dststr, srcstr)#0
|
||||||
byte strlen
|
byte strlen
|
||||||
|
|
||||||
strlen = ^srcstr
|
strlen = ^srcstr
|
||||||
@ -681,7 +681,7 @@ def joinline#0
|
|||||||
byte joinstr[80], joinlen
|
byte joinstr[80], joinlen
|
||||||
|
|
||||||
if cursrow < numlines - 1
|
if cursrow < numlines - 1
|
||||||
strcpy(@joinstr, strlinbuf=>[cursrow])
|
strstripcpy(@joinstr, strlinbuf=>[cursrow])
|
||||||
joinlen = joinstr + ^(strlinbuf=>[cursrow + 1])
|
joinlen = joinstr + ^(strlinbuf=>[cursrow + 1])
|
||||||
if joinlen < 80
|
if joinlen < 80
|
||||||
memcpy(@joinstr + joinstr + 1, strlinbuf=>[cursrow + 1] + 1, ^(strlinbuf=>[cursrow + 1]))
|
memcpy(@joinstr + joinstr + 1, strlinbuf=>[cursrow + 1] + 1, ^(strlinbuf=>[cursrow + 1]))
|
||||||
@ -743,7 +743,7 @@ def editline(key)
|
|||||||
if (editkey(key))
|
if (editkey(key))
|
||||||
flags = flags | changed
|
flags = flags | changed
|
||||||
memset(@editstr, $A0A0, 80)
|
memset(@editstr, $A0A0, 80)
|
||||||
strcpy(@editstr, strlinbuf=>[cursrow])
|
strstripcpy(@editstr, strlinbuf=>[cursrow])
|
||||||
undoline = strlinbuf=>[cursrow]
|
undoline = strlinbuf=>[cursrow]
|
||||||
strlinbuf=>[cursrow] = @editstr
|
strlinbuf=>[cursrow] = @editstr
|
||||||
repeat
|
repeat
|
||||||
@ -802,7 +802,7 @@ def editline(key)
|
|||||||
fin
|
fin
|
||||||
elsif key == keyctrld
|
elsif key == keyctrld
|
||||||
if curscol < editstr
|
if curscol < editstr
|
||||||
strcpy(undoline, @editstr)
|
strstripcpy(undoline, @editstr)
|
||||||
memcpy(@editstr[curscol + 1], @editstr[curscol + 2], editstr - curscol)
|
memcpy(@editstr[curscol + 1], @editstr[curscol + 2], editstr - curscol)
|
||||||
editstr--
|
editstr--
|
||||||
cursoff
|
cursoff
|
||||||
@ -810,7 +810,7 @@ def editline(key)
|
|||||||
curson
|
curson
|
||||||
fin
|
fin
|
||||||
elsif key == keyctrlr
|
elsif key == keyctrlr
|
||||||
strcpy(@editstr, undoline)
|
strstripcpy(@editstr, undoline)
|
||||||
cursoff
|
cursoff
|
||||||
drawrow(cursy, scrnleft, @editstr)
|
drawrow(cursy, scrnleft, @editstr)
|
||||||
curson
|
curson
|
||||||
@ -918,7 +918,7 @@ def prfiles(optpath)
|
|||||||
word databuff, entry, filecnt
|
word databuff, entry, filecnt
|
||||||
|
|
||||||
if ^optpath
|
if ^optpath
|
||||||
strcpy(@path, optpath)
|
strstripcpy(@path, optpath)
|
||||||
else
|
else
|
||||||
fileio:getpfx(@path)
|
fileio:getpfx(@path)
|
||||||
puts(@path)
|
puts(@path)
|
||||||
@ -1003,7 +1003,7 @@ def cmdmode#0
|
|||||||
word cmdptr
|
word cmdptr
|
||||||
|
|
||||||
clrscrn
|
clrscrn
|
||||||
puts("PLASMA ][ EDITOR VERSION 0.99\n")
|
puts("PLASMA Editor, Version 1.0\n")
|
||||||
while not exit
|
while not exit
|
||||||
puts(@filename)
|
puts(@filename)
|
||||||
cmdptr = gets($BA)
|
cmdptr = gets($BA)
|
||||||
@ -1016,7 +1016,7 @@ def cmdmode#0
|
|||||||
if chkchng
|
if chkchng
|
||||||
inittxtbuf
|
inittxtbuf
|
||||||
numlines = 0
|
numlines = 0
|
||||||
strcpy(@filename, cmdptr)
|
strstripcpy(@filename, cmdptr)
|
||||||
readtxt(@filename)
|
readtxt(@filename)
|
||||||
if numlines == 0; numlines = 1; fin
|
if numlines == 0; numlines = 1; fin
|
||||||
flags = flags & ~changed
|
flags = flags & ~changed
|
||||||
@ -1024,7 +1024,7 @@ def cmdmode#0
|
|||||||
break
|
break
|
||||||
is 'W'
|
is 'W'
|
||||||
if ^cmdptr
|
if ^cmdptr
|
||||||
strcpy(@filename, cmdptr)
|
strstripcpy(@filename, cmdptr)
|
||||||
fin
|
fin
|
||||||
writetxt(@filename)
|
writetxt(@filename)
|
||||||
//if flags & changed; fin
|
//if flags & changed; fin
|
||||||
@ -1050,7 +1050,7 @@ def cmdmode#0
|
|||||||
is 'N'
|
is 'N'
|
||||||
if chkchng
|
if chkchng
|
||||||
inittxtbuf
|
inittxtbuf
|
||||||
strcpy(@filename, "UNTITLED")
|
strstripcpy(@filename, "UNTITLED")
|
||||||
fin
|
fin
|
||||||
break
|
break
|
||||||
otherwise
|
otherwise
|
||||||
@ -1078,7 +1078,7 @@ else
|
|||||||
fin
|
fin
|
||||||
inittxtbuf
|
inittxtbuf
|
||||||
arg = argNext(argFirst)
|
arg = argNext(argFirst)
|
||||||
if arg
|
if ^arg
|
||||||
strcpy(@filename, arg)
|
strcpy(@filename, arg)
|
||||||
puts(@filename)
|
puts(@filename)
|
||||||
numlines = 0
|
numlines = 0
|
||||||
|
@ -50,6 +50,7 @@ t_token keywords[] = {
|
|||||||
BYTE_TOKEN, 'R', 'E', 'S',
|
BYTE_TOKEN, 'R', 'E', 'S',
|
||||||
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
||||||
BYTE_TOKEN, 'C', 'H', 'A', 'R',
|
BYTE_TOKEN, 'C', 'H', 'A', 'R',
|
||||||
|
BYTE_TOKEN, 'R', 'E', 'S',
|
||||||
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
||||||
WORD_TOKEN, 'V', 'A', 'R',
|
WORD_TOKEN, 'V', 'A', 'R',
|
||||||
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
||||||
|
@ -316,7 +316,7 @@ end
|
|||||||
// Get next line of input
|
// Get next line of input
|
||||||
//
|
//
|
||||||
def nextln
|
def nextln
|
||||||
strconstptr = @strconst // Reset string constant buffer
|
strconstptr = strconstbuff // Reset string constant buffer
|
||||||
if ^scanptr == ';'
|
if ^scanptr == ';'
|
||||||
scanptr++
|
scanptr++
|
||||||
scan
|
scan
|
||||||
@ -358,7 +358,7 @@ def nextln
|
|||||||
lineno = srcline
|
lineno = srcline
|
||||||
return nextln
|
return nextln
|
||||||
else
|
else
|
||||||
*instr = 0
|
*instr = NULL // NULL terminated 0 length string
|
||||||
token = EOF_TKN
|
token = EOF_TKN
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
|
@ -366,11 +366,11 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
}
|
}
|
||||||
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
|
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
|
||||||
{
|
{
|
||||||
deref++;
|
if (type & BPTR_TYPE)
|
||||||
if (!type)
|
|
||||||
type |= scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
|
|
||||||
else if (scantoken == BPTR_TOKEN)
|
|
||||||
parse_error("Byte value used as pointer");
|
parse_error("Byte value used as pointer");
|
||||||
|
else
|
||||||
|
type = scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
|
||||||
|
deref++;
|
||||||
}
|
}
|
||||||
else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN)
|
else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN)
|
||||||
{
|
{
|
||||||
@ -396,28 +396,29 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN)
|
if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN)
|
||||||
{
|
{
|
||||||
value = constval;
|
value = constval;
|
||||||
type |= CONST_TYPE;
|
|
||||||
valseq = gen_const(NULL, value);
|
valseq = gen_const(NULL, value);
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == ID_TOKEN)
|
else if (scantoken == ID_TOKEN)
|
||||||
{
|
{
|
||||||
if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE)
|
if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE)
|
||||||
{
|
{
|
||||||
value = id_const(tokenstr, tokenlen);
|
value = id_const(tokenstr, tokenlen);
|
||||||
valseq = gen_const(NULL, value);
|
valseq = gen_const(NULL, value);
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else //if (type & (VAR_TYPE | FUNC_TYPE))
|
else
|
||||||
{
|
{
|
||||||
value = id_tag(tokenstr, tokenlen);
|
value = id_tag(tokenstr, tokenlen);
|
||||||
if (type & LOCAL_TYPE)
|
if (type & LOCAL_TYPE)
|
||||||
valseq = gen_lcladr(NULL, value);
|
valseq = gen_lcladr(NULL, value);
|
||||||
else
|
else
|
||||||
valseq = gen_gbladr(NULL, value, type);
|
valseq = gen_gbladr(NULL, value, type);
|
||||||
}
|
if (type & FUNC_TYPE)
|
||||||
if (type & FUNC_TYPE)
|
{
|
||||||
{
|
cfnparms = funcparms_cnt(type);
|
||||||
cfnparms = funcparms_cnt(type);
|
cfnvals = funcvals_cnt(type);
|
||||||
cfnvals = funcvals_cnt(type);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (scantoken == LAMBDA_TOKEN)
|
else if (scantoken == LAMBDA_TOKEN)
|
||||||
@ -427,9 +428,9 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
release_seq(uopseq);
|
release_seq(uopseq);
|
||||||
return (codeseq);
|
return (codeseq);
|
||||||
}
|
}
|
||||||
type |= CONST_TYPE;
|
value = parse_lambda();
|
||||||
value = parse_lambda();
|
|
||||||
valseq = gen_gbladr(NULL, value, FUNC_TYPE);
|
valseq = gen_gbladr(NULL, value, FUNC_TYPE);
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == OPEN_PAREN_TOKEN)
|
else if (scantoken == OPEN_PAREN_TOKEN)
|
||||||
{
|
{
|
||||||
@ -437,6 +438,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
parse_error("Bad expression in parenthesis");
|
parse_error("Bad expression in parenthesis");
|
||||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||||
parse_error("Missing closing parenthesis");
|
parse_error("Missing closing parenthesis");
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == DROP_TOKEN)
|
else if (scantoken == DROP_TOKEN)
|
||||||
{
|
{
|
||||||
@ -482,18 +484,19 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
scan_rewind(tokenstr);
|
scan_rewind(tokenstr);
|
||||||
if (type & (VAR_TYPE | PTR_TYPE))
|
if (type & WORD_TYPE)
|
||||||
{
|
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
if (deref)
|
else if (type & BYTE_TYPE)
|
||||||
deref--;
|
parse_error("Using BYTE value as a pointer");
|
||||||
}
|
else
|
||||||
|
deref++;
|
||||||
}
|
}
|
||||||
valseq = gen_icall(valseq);
|
valseq = gen_icall(valseq);
|
||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth += cfnvals - 1;
|
*stackdepth += cfnvals - 1;
|
||||||
cfnparms = 0; cfnvals = 1;
|
cfnparms = 0; cfnvals = 1;
|
||||||
type &= ~(FUNC_TYPE | VAR_TYPE);
|
type &= PTR_TYPE;
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == OPEN_BRACKET_TOKEN)
|
else if (scantoken == OPEN_BRACKET_TOKEN)
|
||||||
{
|
{
|
||||||
@ -506,24 +509,26 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
* Function address dereference
|
* Function address dereference
|
||||||
*/
|
*/
|
||||||
cfnparms = 0; cfnvals = 1;
|
cfnparms = 0; cfnvals = 1;
|
||||||
type = BPTR_TYPE;
|
|
||||||
}
|
}
|
||||||
while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN)
|
while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN)
|
||||||
{
|
{
|
||||||
valseq = gen_idxw(valseq);
|
valseq = gen_idxw(valseq);
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq); // Multi-dimenstion arrays are array pointers to arrays
|
||||||
}
|
}
|
||||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||||
parse_error("Missing closing bracket");
|
parse_error("Missing closing bracket");
|
||||||
if (type & (WPTR_TYPE | WORD_TYPE))
|
if (type & WORD_TYPE)
|
||||||
{
|
{
|
||||||
valseq = gen_idxw(valseq);
|
valseq = gen_idxw(valseq);
|
||||||
type = (type & PTR_TYPE) | WORD_TYPE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
valseq = gen_idxb(valseq);
|
valseq = gen_idxb(valseq);
|
||||||
type = (type & PTR_TYPE) | BYTE_TYPE;
|
if (!(type & BYTE_TYPE))
|
||||||
|
{
|
||||||
|
type = (type & PTR_TYPE) | BYTE_TYPE;
|
||||||
|
deref++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (scantoken == PTRB_TOKEN || scantoken == PTRW_TOKEN)
|
else if (scantoken == PTRB_TOKEN || scantoken == PTRW_TOKEN)
|
||||||
@ -542,16 +547,19 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth += cfnvals - 1;
|
*stackdepth += cfnvals - 1;
|
||||||
cfnparms = 0; cfnvals = 1;
|
cfnparms = 0; cfnvals = 1;
|
||||||
type &= ~FUNC_TYPE;
|
|
||||||
}
|
}
|
||||||
else if (type & (VAR_TYPE | PTR_TYPE))
|
else if (type & WORD_TYPE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Pointer dereference
|
* Pointer dereference
|
||||||
*/
|
*/
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
}
|
}
|
||||||
type = (scantoken == PTRB_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
|
else if (type & BYTE_TYPE)
|
||||||
|
parse_error("Using BYTE value as a pointer");
|
||||||
|
else
|
||||||
|
deref++;
|
||||||
|
type = (type & PTR_TYPE) | (scantoken == PTRB_TOKEN) ? BYTE_TYPE : WORD_TYPE; // Type override
|
||||||
if (!parse_const(&const_offset))
|
if (!parse_const(&const_offset))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -579,11 +587,10 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
* Function address dereference
|
* Function address dereference
|
||||||
*/
|
*/
|
||||||
cfnparms = 0; cfnvals = 1;
|
cfnparms = 0; cfnvals = 1;
|
||||||
type = 0;
|
|
||||||
}
|
}
|
||||||
type = (type & (VAR_TYPE | CONST_TYPE))
|
else if (!(type & VAR_TYPE))
|
||||||
? ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE)
|
deref++;
|
||||||
: ((scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE);
|
type = (type & PTR_TYPE) | ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE); // Type override
|
||||||
if (!parse_const(&const_offset))
|
if (!parse_const(&const_offset))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -603,12 +610,20 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Probably parsing RVALUE as LVALUE
|
||||||
|
*/
|
||||||
|
if (deref < 0)
|
||||||
|
{
|
||||||
|
release_seq(valseq);
|
||||||
|
release_seq(uopseq);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Resolve outstanding dereference pointer loads
|
* Resolve outstanding dereference pointer loads
|
||||||
*/
|
*/
|
||||||
while (deref > rvalue)
|
while (deref > rvalue)
|
||||||
{
|
{
|
||||||
deref--;
|
|
||||||
if (type & FUNC_TYPE)
|
if (type & FUNC_TYPE)
|
||||||
{
|
{
|
||||||
if (cfnparms)
|
if (cfnparms)
|
||||||
@ -619,8 +634,11 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
cfnparms = 0; cfnvals = 1;
|
cfnparms = 0; cfnvals = 1;
|
||||||
type &= ~FUNC_TYPE;
|
type &= ~FUNC_TYPE;
|
||||||
}
|
}
|
||||||
else if (type & VAR_TYPE)
|
else //if (type & VAR_TYPE)
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
|
//else
|
||||||
|
// {fprintf(stderr,"deref=%d",deref);parse_error("What are we dereferencing #1?");}
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
if (deref)
|
if (deref)
|
||||||
{
|
{
|
||||||
@ -638,6 +656,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
valseq = gen_lb(valseq);
|
valseq = gen_lb(valseq);
|
||||||
else if (type & (WORD_TYPE | WPTR_TYPE))
|
else if (type & (WORD_TYPE | WPTR_TYPE))
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
|
else
|
||||||
|
parse_error("What are we dereferencing?");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Output pre-operations
|
* Output pre-operations
|
||||||
@ -657,6 +677,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
release_seq(valseq);
|
release_seq(valseq);
|
||||||
return (NULL); // Function or const cannot be LVALUE, must be RVALUE
|
return (NULL); // Function or const cannot be LVALUE, must be RVALUE
|
||||||
}
|
}
|
||||||
|
if (stackdepth)
|
||||||
|
*stackdepth--;
|
||||||
}
|
}
|
||||||
return (cat_seq(codeseq, valseq));
|
return (cat_seq(codeseq, valseq));
|
||||||
}
|
}
|
||||||
@ -1039,10 +1061,13 @@ int parse_stmnt(void)
|
|||||||
{
|
{
|
||||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
emit_const(0);
|
emit_const(0);
|
||||||
else if (cfnvals > 1)
|
else
|
||||||
{
|
{
|
||||||
parse_warn("Expression value overflow");
|
if (cfnvals > 1)
|
||||||
while (cfnvals-- > 1) seq = gen_drop(seq);
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
emit_seq(seq);
|
emit_seq(seq);
|
||||||
}
|
}
|
||||||
emit_ret();
|
emit_ret();
|
||||||
@ -1141,13 +1166,18 @@ int parse_var(int type, long basesize)
|
|||||||
else
|
else
|
||||||
parse_error("Bad variable initializer");
|
parse_error("Bad variable initializer");
|
||||||
}
|
}
|
||||||
else if (idlen)
|
else
|
||||||
id_add(idstr, idlen, type, size);
|
{
|
||||||
|
if (idlen)
|
||||||
|
id_add(idstr, idlen, type, size);
|
||||||
|
else
|
||||||
|
emit_data(0, 0, 0, size);
|
||||||
|
}
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
int parse_struc(void)
|
int parse_struc(void)
|
||||||
{
|
{
|
||||||
long size;
|
long basesize, size;
|
||||||
int type, constsize, offset = 0;
|
int type, constsize, offset = 0;
|
||||||
char *idstr, strucid[80];
|
char *idstr, strucid[80];
|
||||||
int idlen = 0, struclen = 0;
|
int idlen = 0, struclen = 0;
|
||||||
@ -1163,18 +1193,19 @@ int parse_struc(void)
|
|||||||
{
|
{
|
||||||
if (scantoken == EOL_TOKEN)
|
if (scantoken == EOL_TOKEN)
|
||||||
continue;
|
continue;
|
||||||
size = 1;
|
basesize = 1;
|
||||||
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
|
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
|
||||||
if (scan() == OPEN_BRACKET_TOKEN)
|
if (scan() == OPEN_BRACKET_TOKEN)
|
||||||
{
|
{
|
||||||
size = 0;
|
basesize = 0;
|
||||||
parse_constexpr(&size, &constsize);
|
parse_constexpr(&basesize, &constsize);
|
||||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||||
parse_error("Missing closing bracket");
|
parse_error("Missing closing bracket");
|
||||||
scan();
|
scan();
|
||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
size = 1;
|
||||||
idlen = 0;
|
idlen = 0;
|
||||||
if (scantoken == ID_TOKEN)
|
if (scantoken == ID_TOKEN)
|
||||||
{
|
{
|
||||||
@ -1189,6 +1220,7 @@ int parse_struc(void)
|
|||||||
scan();
|
scan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size *= basesize;
|
||||||
if (type & WORD_TYPE)
|
if (type & WORD_TYPE)
|
||||||
size *= 2;
|
size *= 2;
|
||||||
if (idlen)
|
if (idlen)
|
||||||
|
@ -228,8 +228,8 @@ def parse_list#2
|
|||||||
return listseq, listdepth
|
return listseq, listdepth
|
||||||
end
|
end
|
||||||
def parse_value(codeseq, rvalue)#2
|
def parse_value(codeseq, rvalue)#2
|
||||||
byte cfnparms, cfnvals, stackdepth, deref, operation
|
byte cfnparms, cfnvals, stackdepth, operation
|
||||||
word type, optos, idptr, value, const_offset
|
word deref, type, optos, idptr, value, const_offset
|
||||||
word uopseq, valseq, idxseq
|
word uopseq, valseq, idxseq
|
||||||
|
|
||||||
deref = rvalue
|
deref = rvalue
|
||||||
@ -256,12 +256,10 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
if not rvalue; exit_err(ERR_INVAL|ERR_SYNTAX); fin
|
if not rvalue; exit_err(ERR_INVAL|ERR_SYNTAX); fin
|
||||||
break
|
break
|
||||||
is BPTR_TKN
|
is BPTR_TKN
|
||||||
deref++
|
|
||||||
type = type | BPTR_TYPE
|
|
||||||
break
|
|
||||||
is WPTR_TKN
|
is WPTR_TKN
|
||||||
|
if type & BPTR_TYPE; exit_err(ERR_INVAL|ERR_SYNTAX); fin
|
||||||
|
type = token == BPTR_TKN ?? BPTR_TYPE :: WPTR_TYPE
|
||||||
deref++
|
deref++
|
||||||
type = type | WPTR_TYPE
|
|
||||||
break
|
break
|
||||||
is AT_TKN
|
is AT_TKN
|
||||||
if not deref; exit_err(ERR_INVAL|ERR_SYNTAX); fin
|
if not deref; exit_err(ERR_INVAL|ERR_SYNTAX); fin
|
||||||
@ -278,24 +276,25 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
is ID_TKN
|
is ID_TKN
|
||||||
idptr = lookup_id(tknptr, tknlen)
|
idptr = lookup_id(tknptr, tknlen)
|
||||||
if not idptr; return codeseq, 0; fin
|
if not idptr; return codeseq, 0; fin
|
||||||
if not idptr=>idtype; return codeseq, 0; fin
|
if not idptr=>idtype; return codeseq, 0; fin // DEBUG
|
||||||
type = type | idptr=>idtype
|
type = type | idptr=>idtype
|
||||||
value = idptr=>idval
|
value = idptr=>idval
|
||||||
if type & CONST_TYPE
|
if type & CONST_TYPE
|
||||||
valseq = gen_const(NULL, value)
|
valseq = gen_const(NULL, value)
|
||||||
|
deref--
|
||||||
else
|
else
|
||||||
valseq = type & LOCAL_TYPE ?? gen_oplcl(NULL, LADDR_CODE, value) :: gen_opglbl(NULL, GADDR_CODE, value, 0)
|
valseq = type & LOCAL_TYPE ?? gen_oplcl(NULL, LADDR_CODE, value) :: gen_opglbl(NULL, GADDR_CODE, value, 0)
|
||||||
fin
|
if type & FUNC_TYPE
|
||||||
if type & FUNC_TYPE
|
cfnparms = idptr->funcparms
|
||||||
cfnparms = idptr->funcparms
|
cfnvals = idptr->funcvals
|
||||||
cfnvals = idptr->funcvals
|
fin
|
||||||
fin
|
fin
|
||||||
break
|
break
|
||||||
is INT_TKN
|
is INT_TKN
|
||||||
is CHR_TKN
|
is CHR_TKN
|
||||||
value = constval
|
value = constval
|
||||||
type = type | CONST_TYPE
|
|
||||||
valseq = gen_const(NULL, value)
|
valseq = gen_const(NULL, value)
|
||||||
|
deref--
|
||||||
break
|
break
|
||||||
is STR_TKN
|
is STR_TKN
|
||||||
codeseq = gen_str(codeseq, constval)
|
codeseq = gen_str(codeseq, constval)
|
||||||
@ -305,6 +304,7 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
is OPEN_PAREN_TKN
|
is OPEN_PAREN_TKN
|
||||||
valseq, stackdepth = parse_expr(NULL)
|
valseq, stackdepth = parse_expr(NULL)
|
||||||
if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
|
if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
|
||||||
|
deref--
|
||||||
break
|
break
|
||||||
is DROP_TKN
|
is DROP_TKN
|
||||||
if rvalue; exit_err(ERR_INVAL|ERR_STATE); fin
|
if rvalue; exit_err(ERR_INVAL|ERR_STATE); fin
|
||||||
@ -313,9 +313,9 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
return codeseq, 0 // Special case return
|
return codeseq, 0 // Special case return
|
||||||
is LAMBDA_TKN
|
is LAMBDA_TKN
|
||||||
if not rvalue; return codeseq, 0; fin // Lambdas can't be LVALUES
|
if not rvalue; return codeseq, 0; fin // Lambdas can't be LVALUES
|
||||||
type = type | CONST_TYPE
|
|
||||||
value = parse_lambda
|
value = parse_lambda
|
||||||
valseq = gen_opglbl(NULL, GADDR_CODE, value, 0)
|
valseq = gen_opglbl(NULL, GADDR_CODE, value, 0)
|
||||||
|
deref--
|
||||||
break
|
break
|
||||||
otherwise
|
otherwise
|
||||||
if uopseq; release_seq(uopseq); fin
|
if uopseq; release_seq(uopseq); fin
|
||||||
@ -344,39 +344,44 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
else
|
else
|
||||||
rewind(tknptr)
|
rewind(tknptr)
|
||||||
fin
|
fin
|
||||||
if type & (VAR_TYPE | PTR_TYPE)
|
if type & WORD_TYPE
|
||||||
valseq = gen_op(valseq, LW_CODE)
|
valseq = gen_op(valseq, LW_CODE)
|
||||||
if deref; deref--; fin
|
elsif type & BYTE_TYPE
|
||||||
|
exit_err(ERR_INVAL|ERR_CODE)
|
||||||
|
else
|
||||||
|
deref++
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
valseq = gen_op(valseq, ICAL_CODE)
|
valseq = gen_op(valseq, ICAL_CODE)
|
||||||
stackdepth = stackdepth + cfnvals - 1
|
stackdepth = stackdepth + cfnvals - 1
|
||||||
cfnparms = 0
|
cfnparms = 0
|
||||||
cfnvals = 1
|
cfnvals = 1
|
||||||
type = type & ~(FUNC_TYPE | VAR_TYPE)
|
type = type & PTR_TYPE
|
||||||
|
deref--
|
||||||
break
|
break
|
||||||
is OPEN_BRACKET_TKN
|
is OPEN_BRACKET_TKN
|
||||||
//
|
//
|
||||||
// Array of arrays
|
// Array of arrays
|
||||||
//
|
//
|
||||||
if type & FUNC_TYPE // Function address dereference
|
if type & FUNC_TYPE // Function address dereference
|
||||||
cfnparms = 0
|
cfnparms = 0
|
||||||
cfnvals = 1
|
cfnvals = 1
|
||||||
type = BPTR_TYPE
|
|
||||||
fin
|
fin
|
||||||
repeat
|
repeat
|
||||||
valseq, drop = parse_expr(valseq)
|
valseq, drop = parse_expr(valseq)
|
||||||
if token <> COMMA_TKN; break; fin
|
if token <> COMMA_TKN; break; fin
|
||||||
valseq = gen_op(valseq, INDEXW_CODE)
|
valseq = gen_op(valseq, INDEXW_CODE)
|
||||||
valseq = gen_op(valseq, LW_CODE)
|
valseq = gen_op(valseq, LW_CODE) // Multi-dimenstion arrays are array pointers to arrays
|
||||||
until FALSE
|
until FALSE
|
||||||
if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
|
if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
|
||||||
if type & (WPTR_TYPE | WORD_TYPE)
|
if type & WORD_TYPE
|
||||||
valseq = gen_op(valseq, INDEXW_CODE)
|
valseq = gen_op(valseq, INDEXW_CODE)
|
||||||
type = (type & PTR_TYPE) | WORD_TYPE
|
|
||||||
else
|
else
|
||||||
valseq = gen_op(valseq, INDEXB_CODE)
|
valseq = gen_op(valseq, INDEXB_CODE)
|
||||||
type = (type & PTR_TYPE) | BYTE_TYPE
|
if not (type & BYTE_TYPE)
|
||||||
|
type = (type & PTR_TYPE) | BYTE_TYPE
|
||||||
|
deref++
|
||||||
|
fin
|
||||||
fin
|
fin
|
||||||
break
|
break
|
||||||
is PTRB_TKN
|
is PTRB_TKN
|
||||||
@ -390,11 +395,14 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
stackdepth = stackdepth + cfnvals - 1
|
stackdepth = stackdepth + cfnvals - 1
|
||||||
cfnparms = 0
|
cfnparms = 0
|
||||||
cfnvals = 1
|
cfnvals = 1
|
||||||
type = type & ~FUNC_TYPE
|
elsif type & WORD_TYPE
|
||||||
elsif type & (VAR_TYPE | PTR_TYPE)
|
|
||||||
valseq = gen_op(valseq, LW_CODE) // Pointer dereference
|
valseq = gen_op(valseq, LW_CODE) // Pointer dereference
|
||||||
|
elsif type & BYTE_TYPE
|
||||||
|
exit_err(ERR_INVAL|ERR_CODE)
|
||||||
|
else
|
||||||
|
deref++
|
||||||
fin
|
fin
|
||||||
type = token == PTRB_TKN ?? BPTR_TYPE :: WPTR_TYPE
|
type = (type & PTR_TYPE) | token == PTRB_TKN ?? BYTE_TYPE :: WORD_TYPE
|
||||||
if not parse_const(@const_offset)
|
if not parse_const(@const_offset)
|
||||||
rewind(tknptr) // Setting type override for following operations
|
rewind(tknptr) // Setting type override for following operations
|
||||||
elsif const_offset <> 0
|
elsif const_offset <> 0
|
||||||
@ -410,13 +418,10 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
if type & FUNC_TYPE // Function address dereference
|
if type & FUNC_TYPE // Function address dereference
|
||||||
cfnparms = 0
|
cfnparms = 0
|
||||||
cfnvals = 1
|
cfnvals = 1
|
||||||
type = VAR_TYPE
|
elsif not (type & VAR_TYPE)
|
||||||
fin
|
deref++
|
||||||
if type & (VAR_TYPE | CONST_TYPE)
|
|
||||||
type = token == DOT_TKN ?? BYTE_TYPE :: WORD_TYPE
|
|
||||||
else
|
|
||||||
type = token == DOT_TKN ?? BPTR_TYPE :: WPTR_TYPE
|
|
||||||
fin
|
fin
|
||||||
|
type = (type & VAR_TYPE) | (token == DOT_TKN ?? BYTE_TYPE :: WORD_TYPE)
|
||||||
if not parse_const(@const_offset)
|
if not parse_const(@const_offset)
|
||||||
rewind(tknptr) // Setting type override for following operations
|
rewind(tknptr) // Setting type override for following operations
|
||||||
elsif const_offset <> 0
|
elsif const_offset <> 0
|
||||||
@ -429,10 +434,17 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
wend
|
wend
|
||||||
until not operation
|
until not operation
|
||||||
//
|
//
|
||||||
|
//Probably parsing RVALUE as LVALUE
|
||||||
|
//
|
||||||
|
if deref < 0
|
||||||
|
release_seq(valseq)
|
||||||
|
release_seq(uopseq)
|
||||||
|
return codeseq, 0
|
||||||
|
fin
|
||||||
|
//
|
||||||
// Resolve outstanding dereference pointer loads
|
// Resolve outstanding dereference pointer loads
|
||||||
//
|
//
|
||||||
while deref > rvalue
|
while deref > rvalue
|
||||||
deref--
|
|
||||||
if type & FUNC_TYPE
|
if type & FUNC_TYPE
|
||||||
if cfnparms; exit_err(ERR_MISS|ERR_ID); fin
|
if cfnparms; exit_err(ERR_MISS|ERR_ID); fin
|
||||||
valseq = gen_op(valseq, ICAL_CODE)
|
valseq = gen_op(valseq, ICAL_CODE)
|
||||||
@ -440,9 +452,10 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
cfnparms = 0
|
cfnparms = 0
|
||||||
cfnvals = 1
|
cfnvals = 1
|
||||||
type = type & ~FUNC_TYPE;
|
type = type & ~FUNC_TYPE;
|
||||||
elsif type & VAR_TYPE
|
else
|
||||||
valseq = gen_op(valseq, LW_CODE)
|
valseq = gen_op(valseq, LW_CODE)
|
||||||
fin
|
fin
|
||||||
|
deref--
|
||||||
loop
|
loop
|
||||||
if deref
|
if deref
|
||||||
if type & FUNC_TYPE
|
if type & FUNC_TYPE
|
||||||
@ -454,6 +467,8 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
valseq = gen_op(valseq, LB_CODE)
|
valseq = gen_op(valseq, LB_CODE)
|
||||||
elsif type & (WORD_TYPE | WPTR_TYPE)
|
elsif type & (WORD_TYPE | WPTR_TYPE)
|
||||||
valseq = gen_op(valseq, LW_CODE)
|
valseq = gen_op(valseq, LW_CODE)
|
||||||
|
else
|
||||||
|
exit_err(ERR_INVAL|ERR_CODE)
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
//
|
//
|
||||||
@ -464,15 +479,15 @@ def parse_value(codeseq, rvalue)#2
|
|||||||
// Wrap up LVALUE store
|
// Wrap up LVALUE store
|
||||||
//
|
//
|
||||||
if not rvalue
|
if not rvalue
|
||||||
stackdepth--
|
|
||||||
if type & (BYTE_TYPE | BPTR_TYPE)
|
if type & (BYTE_TYPE | BPTR_TYPE)
|
||||||
valseq = gen_op(valseq, SB_CODE)
|
valseq = gen_op(valseq, SB_CODE)
|
||||||
elsif type & (WORD_TYPE | WPTR_TYPE)
|
elsif type & (WORD_TYPE | WPTR_TYPE)
|
||||||
valseq = gen_op(valseq, SW_CODE)
|
valseq = gen_op(valseq, SW_CODE)
|
||||||
else
|
else
|
||||||
release_seq(valseq)
|
release_seq(valseq)
|
||||||
return NULL, 0 // Function or const cannot be LVALUE, must be RVALUE
|
return codeseq, 0 // Function or const cannot be LVALUE, must be RVALUE
|
||||||
fin
|
fin
|
||||||
|
stackdepth--
|
||||||
fin
|
fin
|
||||||
return cat_seq(codeseq, valseq), stackdepth
|
return cat_seq(codeseq, valseq), stackdepth
|
||||||
end
|
end
|
||||||
@ -836,9 +851,11 @@ def parse_stmnt
|
|||||||
seq, cfnvals = parse_expr(NULL)
|
seq, cfnvals = parse_expr(NULL)
|
||||||
if not seq
|
if not seq
|
||||||
emit_const(0)
|
emit_const(0)
|
||||||
elsif cfnvals > 1
|
else
|
||||||
exit_err(ERR_OVER|ERR_CLOSE|ERR_STATE)
|
if cfnvals > 1
|
||||||
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
|
exit_err(ERR_OVER|ERR_CLOSE|ERR_STATE)
|
||||||
|
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
|
||||||
|
fin
|
||||||
emit_seq(seq)
|
emit_seq(seq)
|
||||||
fin
|
fin
|
||||||
emit_code(RET_CODE)
|
emit_code(RET_CODE)
|
||||||
@ -917,18 +934,22 @@ def parse_var(type, basesize)#0
|
|||||||
arraysize = arraysize + emit_data(type, consttype, constval, constsize)
|
arraysize = arraysize + emit_data(type, consttype, constval, constsize)
|
||||||
loop
|
loop
|
||||||
size_iddata(PTR_TYPE, size, arraysize)
|
size_iddata(PTR_TYPE, size, arraysize)
|
||||||
elsif idlen
|
else
|
||||||
if infunc
|
if idlen
|
||||||
new_idlocal(idptr, idlen, type, size)
|
if infunc
|
||||||
else
|
new_idlocal(idptr, idlen, type, size)
|
||||||
new_iddata(idptr, idlen, type, size)
|
else
|
||||||
|
new_iddata(idptr, idlen, type, size)
|
||||||
|
fin
|
||||||
|
elsif not (type & (EXTERN_TYPE|LOCAL_TYPE))
|
||||||
|
emit_fill(size)
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
end
|
end
|
||||||
def parse_struc#0
|
def parse_struc#0
|
||||||
byte strucid[16]
|
byte strucid[16]
|
||||||
byte idlen, struclen, constsize, consttype
|
byte idlen, struclen, constsize, consttype
|
||||||
word type, size, offset, idstr
|
word type, basesize, size, offset, idstr
|
||||||
|
|
||||||
struclen = 0
|
struclen = 0
|
||||||
if scan == ID_TKN
|
if scan == ID_TKN
|
||||||
@ -944,15 +965,16 @@ def parse_struc#0
|
|||||||
offset = 0
|
offset = 0
|
||||||
while nextln == BYTE_TKN or token == WORD_TKN or token == EOL_TKN
|
while nextln == BYTE_TKN or token == WORD_TKN or token == EOL_TKN
|
||||||
if token <> EOL_TKN
|
if token <> EOL_TKN
|
||||||
size = 1
|
basesize = 1
|
||||||
type = token == BYTE_TKN ?? BYTE_TYPE :: WORD_TYPE
|
type = token == BYTE_TKN ?? BYTE_TYPE :: WORD_TYPE
|
||||||
if scan == OPEN_BRACKET_TKN
|
if scan == OPEN_BRACKET_TKN
|
||||||
size, constsize, consttype = parse_constexpr
|
basesize, constsize, consttype = parse_constexpr
|
||||||
if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
|
if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
|
||||||
scan
|
scan
|
||||||
fin
|
fin
|
||||||
repeat
|
repeat
|
||||||
idlen = 0;
|
size = 1
|
||||||
|
idlen = 0
|
||||||
if token == ID_TKN
|
if token == ID_TKN
|
||||||
idstr = tknptr
|
idstr = tknptr
|
||||||
idlen = tknlen
|
idlen = tknlen
|
||||||
@ -962,6 +984,7 @@ def parse_struc#0
|
|||||||
scan
|
scan
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
|
size = size * basesize
|
||||||
if type & WORD_TYPE
|
if type & WORD_TYPE
|
||||||
size = size * 2
|
size = size * 2
|
||||||
fin
|
fin
|
||||||
|
@ -152,6 +152,7 @@ byte = "AND", LOGIC_AND_TKN
|
|||||||
byte = "NOT", LOGIC_NOT_TKN
|
byte = "NOT", LOGIC_NOT_TKN
|
||||||
byte = "RES", BYTE_TKN
|
byte = "RES", BYTE_TKN
|
||||||
byte = "VAR", WORD_TKN
|
byte = "VAR", WORD_TKN
|
||||||
|
byte = "RES", BYTE_TKN
|
||||||
byte = "WORD", WORD_TKN
|
byte = "WORD", WORD_TKN
|
||||||
byte = "CHAR", BYTE_TKN
|
byte = "CHAR", BYTE_TKN
|
||||||
byte = "BYTE", BYTE_TKN
|
byte = "BYTE", BYTE_TKN
|
||||||
@ -281,21 +282,21 @@ word srcline // Saved source line number
|
|||||||
//
|
//
|
||||||
// Scanner variables
|
// Scanner variables
|
||||||
//
|
//
|
||||||
const inbuff = $0200
|
word instr
|
||||||
const instr = $01FF
|
word inbuff
|
||||||
word scanptr = inbuff
|
word scanptr
|
||||||
byte token = EOL_TKN
|
byte token = EOL_TKN
|
||||||
byte scanchr, tknlen
|
byte scanchr, tknlen
|
||||||
word tknptr, parserrln
|
word tknptr, parserrln
|
||||||
word constval
|
word constval
|
||||||
word lineno
|
word lineno
|
||||||
//
|
//
|
||||||
// Parser variables
|
// Parser variables
|
||||||
//
|
//
|
||||||
const LVALUE = 0
|
const LVALUE = 0
|
||||||
const RVALUE = 1
|
const RVALUE = 1
|
||||||
const LAMBDANUM = 16
|
const LAMBDANUM = 16
|
||||||
byte[80] strconst
|
word strconstbuff
|
||||||
word strconstptr
|
word strconstptr
|
||||||
byte infunc, inlambda
|
byte infunc, inlambda
|
||||||
byte stack_loop
|
byte stack_loop
|
||||||
@ -348,14 +349,6 @@ def puth(hex)#0
|
|||||||
putc('$')
|
putc('$')
|
||||||
call($F941, hex >> 8, hex, 0, 0)
|
call($F941, hex >> 8, hex, 0, 0)
|
||||||
end
|
end
|
||||||
def strcpy(dst, src)
|
|
||||||
if ^src
|
|
||||||
memcpy(dst, src, ^src + 1)
|
|
||||||
else
|
|
||||||
^dst = 0
|
|
||||||
fin
|
|
||||||
return ^dst
|
|
||||||
end
|
|
||||||
def nametostr(namestr, len, strptr)#0
|
def nametostr(namestr, len, strptr)#0
|
||||||
^strptr = len
|
^strptr = len
|
||||||
memcpy(strptr + 1, namestr, len)
|
memcpy(strptr + 1, namestr, len)
|
||||||
@ -394,7 +387,7 @@ def exit_err(err)#0
|
|||||||
if err & ERR_SYNTAX; puts("syntax"); fin
|
if err & ERR_SYNTAX; puts("syntax"); fin
|
||||||
putcurln
|
putcurln
|
||||||
fileio:close(0) // Close all open files
|
fileio:close(0) // Close all open files
|
||||||
longjmp(exit, TRUE)
|
throw(exit, TRUE)
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Warning
|
// Warning
|
||||||
@ -415,16 +408,17 @@ include "toolsrc/parse.pla"
|
|||||||
//
|
//
|
||||||
// Look at command line arguments and compile module
|
// Look at command line arguments and compile module
|
||||||
//
|
//
|
||||||
|
puts("PLASMA Compiler, Version 1.0\n")
|
||||||
arg = argNext(argFirst)
|
arg = argNext(argFirst)
|
||||||
if ^arg and ^(arg + 1) == '-'
|
if ^arg and ^(arg + 1) == '-'
|
||||||
opt = arg + 2
|
opt = arg + 2
|
||||||
while TRUE
|
while TRUE
|
||||||
if toupper(^opt) == 'O'
|
if toupper(^opt) == 'O'
|
||||||
//
|
//
|
||||||
// Load optimizer module here
|
// Load optimizer module here
|
||||||
//
|
//
|
||||||
if MACHID & $30 == $30
|
if MACHID & $30 == $30
|
||||||
if modexec("CODEOPT") >= 0
|
if cmdsys:modexec("CODEOPT") >= 0
|
||||||
outflags = outflags | OPTIMIZE
|
outflags = outflags | OPTIMIZE
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
@ -448,10 +442,10 @@ if ^arg and ^(arg + 1) == '-'
|
|||||||
loop
|
loop
|
||||||
arg = argNext(arg)
|
arg = argNext(arg)
|
||||||
fin
|
fin
|
||||||
if arg
|
if ^arg
|
||||||
strcpy(@srcfile, arg)
|
strcpy(@srcfile, arg)
|
||||||
arg = argNext(arg)
|
arg = argNext(arg)
|
||||||
if arg and ^arg
|
if ^arg
|
||||||
strcpy(@relfile, arg)
|
strcpy(@relfile, arg)
|
||||||
else
|
else
|
||||||
strcpy(@relfile, @srcfile)
|
strcpy(@relfile, @srcfile)
|
||||||
@ -474,12 +468,15 @@ if srcfile and relfile
|
|||||||
srcref = fileio:open(@srcfile)
|
srcref = fileio:open(@srcfile)
|
||||||
if srcref
|
if srcref
|
||||||
fileio:newline(srcref, $7F, $0D)
|
fileio:newline(srcref, $7F, $0D)
|
||||||
refnum = srcref
|
refnum = srcref
|
||||||
parsefile = @srcfile
|
parsefile = @srcfile
|
||||||
*instr = 0
|
strconstbuff = heapalloc(80)
|
||||||
scanptr = inbuff
|
instr = cmdsys:cmdline
|
||||||
exit = heapalloc(t_longjmp)
|
inbuff = instr + 1
|
||||||
if not setjmp(exit)
|
scanptr = inbuff
|
||||||
|
*instr = NULL
|
||||||
|
exit = heapalloc(t_except)
|
||||||
|
if not except(exit)
|
||||||
//
|
//
|
||||||
// Parse source code module
|
// Parse source code module
|
||||||
//
|
//
|
||||||
|
@ -34,12 +34,12 @@ predef syscall(cmd,null)#1, call(addr,areg,xreg,yreg,status)#1
|
|||||||
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
||||||
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
|
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
|
||||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
||||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, divmod(a,b)#2
|
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2
|
||||||
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
||||||
//
|
//
|
||||||
// System variables.
|
// System variables.
|
||||||
//
|
//
|
||||||
word version = $0099 // 00.99
|
word version = $0100 // 01.00
|
||||||
word systemflags = 0
|
word systemflags = 0
|
||||||
word heap
|
word heap
|
||||||
word symtbl, lastsym
|
word symtbl, lastsym
|
||||||
@ -68,6 +68,7 @@ word cmdptr = @hexchar // make it point to a zero
|
|||||||
//
|
//
|
||||||
byte syslibstr[] = "CMDSYS"
|
byte syslibstr[] = "CMDSYS"
|
||||||
byte machidstr[] = "MACHID"
|
byte machidstr[] = "MACHID"
|
||||||
|
byte syspathstr[] = "SYSPATH"
|
||||||
byte putcstr[] = "PUTC"
|
byte putcstr[] = "PUTC"
|
||||||
byte putlnstr[] = "PUTLN"
|
byte putlnstr[] = "PUTLN"
|
||||||
byte putsstr[] = "PUTS"
|
byte putsstr[] = "PUTS"
|
||||||
@ -88,12 +89,12 @@ byte uisgtstr[] = "ISUGT"
|
|||||||
byte uisgestr[] = "ISUGE"
|
byte uisgestr[] = "ISUGE"
|
||||||
byte uisltstr[] = "ISULT"
|
byte uisltstr[] = "ISULT"
|
||||||
byte uislestr[] = "ISULE"
|
byte uislestr[] = "ISULE"
|
||||||
|
byte sextstr[] = "SEXT"
|
||||||
byte divmodstr[] = "DIVMOD"
|
byte divmodstr[] = "DIVMOD"
|
||||||
byte loadstr[] = "MODLOAD"
|
|
||||||
byte execstr[] = "MODEXEC"
|
|
||||||
byte modadrstr[] = "MODADDR"
|
|
||||||
byte argstr[] = "ARGS"
|
byte argstr[] = "ARGS"
|
||||||
word exports[] = @sysstr, @syscall
|
byte syspath[] = "" // Set to NULL
|
||||||
|
word exports[] = @syslibstr, @version
|
||||||
|
word = @sysstr, @syscall
|
||||||
word = @callstr, @call
|
word = @callstr, @call
|
||||||
word = @putcstr, @cout
|
word = @putcstr, @cout
|
||||||
word = @putlnstr, @crout
|
word = @putlnstr, @crout
|
||||||
@ -113,11 +114,10 @@ word = @uisgtstr, @uword_isgt
|
|||||||
word = @uisgestr, @uword_isge
|
word = @uisgestr, @uword_isge
|
||||||
word = @uisltstr, @uword_islt
|
word = @uisltstr, @uword_islt
|
||||||
word = @uislestr, @uword_isle
|
word = @uislestr, @uword_isle
|
||||||
|
word = @sextstr, @sext
|
||||||
word = @divmodstr, @divmod
|
word = @divmodstr, @divmod
|
||||||
word = @loadstr, @loadmod
|
|
||||||
word = @execstr, @execmod
|
|
||||||
word = @modadrstr, @lookupstrmod
|
|
||||||
word = @machidstr, @machid
|
word = @machidstr, @machid
|
||||||
|
word = @syspathstr,@syspath
|
||||||
word = @argstr, @cmdptr
|
word = @argstr, @cmdptr
|
||||||
word = 0
|
word = 0
|
||||||
word syslibsym = @exports
|
word syslibsym = @exports
|
||||||
@ -375,6 +375,14 @@ _divmod DEX
|
|||||||
STA ESTKH,X
|
STA ESTKH,X
|
||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
|
asm sext(a)#1
|
||||||
|
LDY #$00
|
||||||
|
LDA ESTKL,X
|
||||||
|
BPL +
|
||||||
|
DEY
|
||||||
|
+ STY ESTKH,X
|
||||||
|
RTS
|
||||||
|
end
|
||||||
//
|
//
|
||||||
// Addresses of internal routines.
|
// Addresses of internal routines.
|
||||||
//
|
//
|
||||||
@ -485,38 +493,6 @@ end
|
|||||||
// pre-pended with a '#' to differentiate them
|
// pre-pended with a '#' to differentiate them
|
||||||
// from normal symbols.
|
// from normal symbols.
|
||||||
//
|
//
|
||||||
//def modtosym(mod, dci)
|
|
||||||
// byte len, c
|
|
||||||
// (dci).0 = '#'|$80
|
|
||||||
// len = 0
|
|
||||||
// repeat
|
|
||||||
// c = (mod).[len]
|
|
||||||
// len = len + 1
|
|
||||||
// (dci).[len] = c
|
|
||||||
// until !(c & $80)
|
|
||||||
// return dci
|
|
||||||
//end
|
|
||||||
asm modtosym(mod, dci)#1
|
|
||||||
LDA ESTKL+1,X
|
|
||||||
STA SRCL
|
|
||||||
LDA ESTKH+1,X
|
|
||||||
STA SRCH
|
|
||||||
LDA ESTKL,X
|
|
||||||
STA ESTKL+1,X
|
|
||||||
STA DSTL
|
|
||||||
LDA ESTKH,X
|
|
||||||
STA ESTKH+1,X
|
|
||||||
STA DSTH
|
|
||||||
INX
|
|
||||||
LDY #$00
|
|
||||||
LDA #'#'+$80
|
|
||||||
- STA (DST),Y
|
|
||||||
ASL
|
|
||||||
LDA (SRC),Y
|
|
||||||
INY
|
|
||||||
BCS -
|
|
||||||
RTS
|
|
||||||
end
|
|
||||||
//
|
//
|
||||||
// Lookup routines.
|
// Lookup routines.
|
||||||
//
|
//
|
||||||
@ -622,47 +598,53 @@ def rdstr(prompt)#1
|
|||||||
cout(prompt)
|
cout(prompt)
|
||||||
repeat
|
repeat
|
||||||
ch = cin
|
ch = cin
|
||||||
when ch
|
when ch
|
||||||
is $15 // right arrow
|
is $15 // right arrow
|
||||||
if inbuff.0 < maxlen
|
if ^inbuff < maxlen //inbuff.0 < maxlen
|
||||||
inbuff.0 = inbuff.0 + 1
|
inbuff.0 = inbuff.0 + 1
|
||||||
ch = inbuff[inbuff.0]
|
ch = inbuff[inbuff.0]
|
||||||
cout(ch)
|
cout(ch)
|
||||||
fin
|
fin
|
||||||
is $08 // left arrow
|
break
|
||||||
if inbuff.0
|
is $08 // left arrow
|
||||||
cout('\\')
|
if inbuff.0
|
||||||
cout(inbuff[inbuff.0])
|
cout('\\')
|
||||||
inbuff.0 = inbuff.0 - 1
|
cout(inbuff[inbuff.0])
|
||||||
fin
|
inbuff.0 = inbuff.0 - 1
|
||||||
is $04 // ctrl-d
|
fin
|
||||||
if inbuff.0
|
break
|
||||||
cout('#')
|
is $04 // ctrl-d
|
||||||
cout(inbuff[inbuff.0])
|
if inbuff.0
|
||||||
memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0)
|
cout('#')
|
||||||
maxlen = maxlen - 1
|
cout(inbuff[inbuff.0])
|
||||||
inbuff.0 = inbuff.0 - 1
|
memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0)
|
||||||
fin
|
maxlen = maxlen - 1
|
||||||
is $0C // ctrl-l
|
inbuff.0 = inbuff.0 - 1
|
||||||
crout
|
fin
|
||||||
prstr(inbuff)
|
break
|
||||||
is $0D // return
|
is $0C // ctrl-l
|
||||||
is $18 // ctrl-x
|
crout
|
||||||
crout
|
prstr(inbuff)
|
||||||
inbuff.0 = 0
|
break
|
||||||
is $9B // escape
|
is $0D // return
|
||||||
inbuff.0 = 0
|
is $18 // ctrl-x
|
||||||
ch = $0D
|
crout
|
||||||
otherwise
|
inbuff.0 = 0
|
||||||
if ch >= ' '
|
break
|
||||||
cout(ch)
|
is $9B // escape
|
||||||
inbuff.0 = inbuff.0 + 1
|
inbuff.0 = 0
|
||||||
inbuff[inbuff.0] = ch
|
ch = $0D
|
||||||
if inbuff.0 > maxlen
|
break
|
||||||
maxlen = inbuff.0
|
otherwise
|
||||||
fin
|
if ch >= ' '
|
||||||
fin
|
cout(ch)
|
||||||
wend
|
inbuff.0 = inbuff.0 + 1
|
||||||
|
inbuff[inbuff.0] = ch
|
||||||
|
if inbuff.0 > maxlen
|
||||||
|
maxlen = inbuff.0
|
||||||
|
fin
|
||||||
|
fin
|
||||||
|
wend
|
||||||
until ch == $0D or inbuff.0 == $7F
|
until ch == $0D or inbuff.0 == $7F
|
||||||
cout($0D)
|
cout($0D)
|
||||||
return inbuff
|
return inbuff
|
||||||
@ -751,19 +733,6 @@ end
|
|||||||
//
|
//
|
||||||
// Module routines.
|
// Module routines.
|
||||||
//
|
//
|
||||||
def lookupmod(mod)#1
|
|
||||||
byte dci[17]
|
|
||||||
return lookuptbl(modtosym(mod, @dci), symtbl)
|
|
||||||
end
|
|
||||||
def lookupstrmod(str)#1
|
|
||||||
byte mod[17]
|
|
||||||
stodci(str, @mod)
|
|
||||||
return lookupmod(@mod)
|
|
||||||
end
|
|
||||||
def addmod(mod, addr)#0
|
|
||||||
byte dci[17]
|
|
||||||
addsym(modtosym(mod, @dci), addr)
|
|
||||||
end
|
|
||||||
def lookupextern(esd, index)#1
|
def lookupextern(esd, index)#1
|
||||||
word sym, addr
|
word sym, addr
|
||||||
byte str[16]
|
byte str[16]
|
||||||
@ -837,7 +806,7 @@ def loadmod(mod)#1
|
|||||||
// Load module dependencies.
|
// Load module dependencies.
|
||||||
//
|
//
|
||||||
while ^moddep
|
while ^moddep
|
||||||
if !lookupmod(moddep)
|
if !lookuptbl(moddep, symtbl)
|
||||||
if loadmod(moddep) < 0
|
if loadmod(moddep) < 0
|
||||||
return -perr
|
return -perr
|
||||||
fin
|
fin
|
||||||
@ -867,7 +836,7 @@ def loadmod(mod)#1
|
|||||||
//
|
//
|
||||||
// Add module to symbol table.
|
// Add module to symbol table.
|
||||||
//
|
//
|
||||||
addmod(mod, modaddr)
|
addsym(mod, modaddr)
|
||||||
//
|
//
|
||||||
// Apply all fixups and symbol import/export.
|
// Apply all fixups and symbol import/export.
|
||||||
//
|
//
|
||||||
@ -1032,13 +1001,15 @@ end
|
|||||||
//
|
//
|
||||||
heap = *freemem
|
heap = *freemem
|
||||||
//
|
//
|
||||||
|
// Print PLASMA version
|
||||||
|
//
|
||||||
|
prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout
|
||||||
|
//
|
||||||
// Init symbol table.
|
// Init symbol table.
|
||||||
//
|
//
|
||||||
symtbl = allocheap($200)
|
symtbl = allocheap($200)
|
||||||
lastsym = symtbl
|
lastsym = symtbl
|
||||||
^lastsym = 0
|
^lastsym = 0
|
||||||
stodci(@syslibstr, heap)
|
|
||||||
addmod(heap, @version)
|
|
||||||
while *syslibsym
|
while *syslibsym
|
||||||
stodci(syslibsym=>0, heap)
|
stodci(syslibsym=>0, heap)
|
||||||
addsym(heap, syslibsym=>2)
|
addsym(heap, syslibsym=>2)
|
||||||
@ -1058,11 +1029,6 @@ perr = 0
|
|||||||
// Print some startup info.
|
// Print some startup info.
|
||||||
//
|
//
|
||||||
if not ^cmdptr
|
if not ^cmdptr
|
||||||
prstr(@verstr)
|
|
||||||
prbyte(version.1)
|
|
||||||
cout('.')
|
|
||||||
prbyte(version.0)
|
|
||||||
crout
|
|
||||||
prstr(@freestr)
|
prstr(@freestr)
|
||||||
prword(availheap)
|
prword(availheap)
|
||||||
crout
|
crout
|
||||||
|
@ -25,31 +25,35 @@ const modinitkeep = $4000
|
|||||||
// Pedefined functions.
|
// Pedefined functions.
|
||||||
//
|
//
|
||||||
predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
|
predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
|
||||||
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
predef crout()#0, cout(c)#0, prstr(s)#0, prbyte(b)#0, prword(w)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
||||||
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1
|
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1
|
||||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1
|
||||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, divmod(a,b)#2
|
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2
|
||||||
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
predef execmod(modfile)#1
|
||||||
//
|
//
|
||||||
// System variable.
|
// Exported CMDSYS table
|
||||||
//
|
//
|
||||||
word version = $0099 // 00.99
|
word version = $0100 // 01.00
|
||||||
word systemflags = 0
|
word syspath
|
||||||
word heap
|
word = getlnbuf
|
||||||
word xheap = $0800
|
word = @execmod
|
||||||
word lastsym = symtbl
|
word = getlnbuf
|
||||||
byte perr
|
//
|
||||||
byte cmdln = "" // Overlay exported strings table
|
// Working input buffer overlayed with strings table
|
||||||
|
//
|
||||||
|
byte cmdln = ""
|
||||||
//
|
//
|
||||||
// Standard Library exported functions.
|
// Standard Library exported functions.
|
||||||
//
|
//
|
||||||
byte syslibstr = "CMDSYS"
|
byte sysmodstr = "CMDSYS"
|
||||||
byte machidstr = "MACHID"
|
byte machidstr = "MACHID"
|
||||||
byte sysstr = "SYSCALL"
|
byte sysstr = "SYSCALL"
|
||||||
byte callstr = "CALL"
|
byte callstr = "CALL"
|
||||||
byte putcstr = "PUTC"
|
byte putcstr = "PUTC"
|
||||||
byte putlnstr = "PUTLN"
|
byte putlnstr = "PUTLN"
|
||||||
byte putsstr = "PUTS"
|
byte putsstr = "PUTS"
|
||||||
|
byte putbstr = "PUTB"
|
||||||
|
byte putwstr = "PUTH"
|
||||||
byte putistr = "PUTI"
|
byte putistr = "PUTI"
|
||||||
byte getcstr = "GETC"
|
byte getcstr = "GETC"
|
||||||
byte getsstr = "GETS"
|
byte getsstr = "GETS"
|
||||||
@ -59,24 +63,27 @@ byte hpalignstr = "HEAPALLOCALIGN"
|
|||||||
byte hpallocstr = "HEAPALLOC"
|
byte hpallocstr = "HEAPALLOC"
|
||||||
byte hprelstr = "HEAPRELEASE"
|
byte hprelstr = "HEAPRELEASE"
|
||||||
byte hpavlstr = "HEAPAVAIL"
|
byte hpavlstr = "HEAPAVAIL"
|
||||||
byte memsetstr = "MEMSET"
|
word memsetstr = "MEMSET"
|
||||||
byte memcpystr = "MEMCPY"
|
byte memcpystr = "MEMCPY"
|
||||||
byte uisgtstr = "ISUGT"
|
byte uisgtstr = "ISUGT"
|
||||||
byte uisgestr = "ISUGE"
|
byte uisgestr = "ISUGE"
|
||||||
byte uisltstr = "ISULT"
|
byte uisltstr = "ISULT"
|
||||||
byte uislestr = "ISULE"
|
byte uislestr = "ISULE"
|
||||||
|
byte sysmods[] // overlay with exported strings
|
||||||
|
byte strcpystr = "STRCPY"
|
||||||
|
byte strcatstr = "STRCAT"
|
||||||
|
byte sextstr = "SEXT"
|
||||||
byte divmodstr = "DIVMOD"
|
byte divmodstr = "DIVMOD"
|
||||||
byte loadstr = "MODLOAD"
|
|
||||||
byte execstr = "MODEXEC"
|
|
||||||
byte modadrstr = "MODADDR"
|
|
||||||
byte argstr = "ARGS"
|
|
||||||
byte autorun = "AUTORUN"
|
byte autorun = "AUTORUN"
|
||||||
byte prefix[] // overlay with exported symbols table
|
byte prefix[] // overlay with exported symbols table
|
||||||
word exports = @sysstr, @syscall
|
word exports = @sysmodstr, @version
|
||||||
|
word = @sysstr, @syscall
|
||||||
word = @callstr, @call
|
word = @callstr, @call
|
||||||
word = @putcstr, @cout
|
word = @putcstr, @cout
|
||||||
word = @putlnstr, @crout
|
word = @putlnstr, @crout
|
||||||
word = @putsstr, @prstr
|
word = @putsstr, @prstr
|
||||||
|
word = @putbstr, @prbyte
|
||||||
|
word = @putwstr, @prword
|
||||||
word = @putistr, @print
|
word = @putistr, @print
|
||||||
word = @getcstr, @cin
|
word = @getcstr, @cin
|
||||||
word = @getsstr, @rdstr
|
word = @getsstr, @rdstr
|
||||||
@ -92,26 +99,32 @@ word = @uisgtstr, @uword_isgt
|
|||||||
word = @uisgestr, @uword_isge
|
word = @uisgestr, @uword_isge
|
||||||
word = @uisltstr, @uword_islt
|
word = @uisltstr, @uword_islt
|
||||||
word = @uislestr, @uword_isle
|
word = @uislestr, @uword_isle
|
||||||
|
word = @strcpystr, @strcpy
|
||||||
|
word = @strcatstr, @strcat
|
||||||
|
word = @sextstr, @sext
|
||||||
word = @divmodstr, @divmod
|
word = @divmodstr, @divmod
|
||||||
word = @loadstr, @loadmod
|
|
||||||
word = @execstr, @execmod
|
|
||||||
word = @modadrstr, @lookupstrmod
|
|
||||||
word = @machidstr, MACHID
|
word = @machidstr, MACHID
|
||||||
word = @argstr, @cmdln
|
|
||||||
word = 0
|
word = 0
|
||||||
word syslibsym = @exports
|
word sysmodsym = @exports
|
||||||
|
//
|
||||||
|
// System variable.
|
||||||
|
//
|
||||||
|
word systemflags = 0
|
||||||
|
byte perr
|
||||||
|
word heap
|
||||||
|
word xheap = $0800
|
||||||
|
word lastsym = symtbl
|
||||||
//
|
//
|
||||||
// Utility functions
|
// Utility functions
|
||||||
//
|
//
|
||||||
//asm equates included from cmdstub.s
|
//asm equates included from cmdstub.s
|
||||||
//
|
//
|
||||||
asm saveX#0
|
asm saveX#0
|
||||||
STX XREG
|
STX XREG+1
|
||||||
RTS
|
RTS
|
||||||
XREG !BYTE 0
|
|
||||||
end
|
end
|
||||||
asm restoreX#0
|
asm restoreX#0
|
||||||
LDX XREG
|
XREG LDX #$00
|
||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
// CALL PRODOS
|
// CALL PRODOS
|
||||||
@ -344,10 +357,8 @@ asm memxcpy(dst,src,size)#0
|
|||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
asm crout()#0
|
asm crout()#0
|
||||||
DEX
|
LDA #$8D
|
||||||
LDA #$0D
|
BNE ++
|
||||||
BNE +
|
|
||||||
; FALL THROUGH TO COUT
|
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// CHAR OUT
|
// CHAR OUT
|
||||||
@ -359,10 +370,10 @@ asm cout(c)#0
|
|||||||
BMI +
|
BMI +
|
||||||
JSR TOUPR
|
JSR TOUPR
|
||||||
+ ORA #$80
|
+ ORA #$80
|
||||||
BIT ROMEN
|
INX
|
||||||
|
++ BIT ROMEN
|
||||||
JSR $FDED
|
JSR $FDED
|
||||||
BIT LCRDEN+LCBNK2
|
BIT LCRDEN+LCBNK2
|
||||||
INX
|
|
||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
@ -408,11 +419,20 @@ asm prstr(s)#0
|
|||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
|
// PRINT WORD
|
||||||
|
//
|
||||||
|
asm prword(w)#0
|
||||||
|
LDA ESTKH,X
|
||||||
|
JSR +
|
||||||
|
DEX
|
||||||
|
; FALL THROUGH TO PRBYTE
|
||||||
|
end
|
||||||
|
//
|
||||||
// PRINT BYTE
|
// PRINT BYTE
|
||||||
//
|
//
|
||||||
asm prbyte(b)#0
|
asm prbyte(b)#0
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
STX ESP
|
+ STX ESP
|
||||||
BIT ROMEN
|
BIT ROMEN
|
||||||
JSR $FDDA
|
JSR $FDDA
|
||||||
LDX ESP
|
LDX ESP
|
||||||
@ -421,22 +441,6 @@ asm prbyte(b)#0
|
|||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// PRINT WORD
|
|
||||||
//
|
|
||||||
asm prword(w)#0
|
|
||||||
STX ESP
|
|
||||||
TXA
|
|
||||||
TAY
|
|
||||||
LDA ESTKH,Y
|
|
||||||
LDX ESTKL,Y
|
|
||||||
BIT ROMEN
|
|
||||||
JSR $F941
|
|
||||||
LDX ESP
|
|
||||||
BIT LCRDEN+LCBNK2
|
|
||||||
INX
|
|
||||||
RTS
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// READ STRING
|
// READ STRING
|
||||||
// STR = RDSTR(PROMPTCHAR)
|
// STR = RDSTR(PROMPTCHAR)
|
||||||
//
|
//
|
||||||
@ -534,6 +538,14 @@ _divmod DEX
|
|||||||
STA ESTKH,X
|
STA ESTKH,X
|
||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
|
asm sext(a)#1
|
||||||
|
LDY #$00
|
||||||
|
LDA ESTKL,X
|
||||||
|
BPL +
|
||||||
|
DEY
|
||||||
|
+ STY ESTKH,X
|
||||||
|
RTS
|
||||||
|
end
|
||||||
//
|
//
|
||||||
// Utility routines.
|
// Utility routines.
|
||||||
//
|
//
|
||||||
@ -631,43 +643,6 @@ TOUPR AND #$7F
|
|||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Module symbols are entered into the symbol table
|
|
||||||
// pre-pended with a '#' to differentiate them
|
|
||||||
// from normal symbols.
|
|
||||||
//
|
|
||||||
//def modtosym(mod, dci)
|
|
||||||
// byte len, c
|
|
||||||
// (dci).0 = '#'|$80
|
|
||||||
// len = 0
|
|
||||||
// repeat
|
|
||||||
// c = (mod).[len]
|
|
||||||
// len = len + 1
|
|
||||||
// (dci).[len] = c
|
|
||||||
// until !(c & $80)
|
|
||||||
// return dci
|
|
||||||
//end
|
|
||||||
asm modtosym(mod,dci)#1
|
|
||||||
LDA ESTKL+1,X
|
|
||||||
STA SRCL
|
|
||||||
LDA ESTKH+1,X
|
|
||||||
STA SRCH
|
|
||||||
LDA ESTKL,X
|
|
||||||
STA ESTKL+1,X
|
|
||||||
STA DSTL
|
|
||||||
LDA ESTKH,X
|
|
||||||
STA ESTKH+1,X
|
|
||||||
STA DSTH
|
|
||||||
INX
|
|
||||||
LDY #$00
|
|
||||||
LDA #'#'+$80
|
|
||||||
- STA (DST),Y
|
|
||||||
ASL
|
|
||||||
LDA (SRC),Y
|
|
||||||
INY
|
|
||||||
BCS -
|
|
||||||
RTS
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Lookup routines.
|
// Lookup routines.
|
||||||
//
|
//
|
||||||
//def lookuptbl(dci, tbl)
|
//def lookuptbl(dci, tbl)
|
||||||
@ -757,12 +732,12 @@ def setpfx(path)#1
|
|||||||
perr = syscall($C6, @params)
|
perr = syscall($C6, @params)
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
def open(path, buff)#1
|
def open(path)#1
|
||||||
byte params[6]
|
byte params[6]
|
||||||
|
|
||||||
params.0 = 3
|
params.0 = 3
|
||||||
params:1 = path
|
params:1 = path
|
||||||
params:3 = buff
|
params:3 = iobuffer
|
||||||
params.5 = 0
|
params.5 = 0
|
||||||
perr = syscall($C8, @params)
|
perr = syscall($C8, @params)
|
||||||
return params.5
|
return params.5
|
||||||
@ -873,30 +848,30 @@ end
|
|||||||
def addsym(sym, addr)#0
|
def addsym(sym, addr)#0
|
||||||
while ^sym & $80
|
while ^sym & $80
|
||||||
^lastsym = ^sym
|
^lastsym = ^sym
|
||||||
lastsym = lastsym + 1
|
lastsym++
|
||||||
sym = sym + 1
|
sym++
|
||||||
loop
|
loop
|
||||||
lastsym->0 = ^sym
|
lastsym->0 = ^sym
|
||||||
lastsym=>1 = addr
|
lastsym=>1 = addr
|
||||||
lastsym = lastsym + 3
|
lastsym = lastsym + 3
|
||||||
^lastsym = 0
|
^lastsym = 0
|
||||||
|
end
|
||||||
|
//
|
||||||
|
// String routines.
|
||||||
|
//
|
||||||
|
def strcpy(dst, src)#1
|
||||||
|
memcpy(dst+1, src+1, ^src)
|
||||||
|
^dst = ^src
|
||||||
|
return dst
|
||||||
|
end
|
||||||
|
def strcat(dst, src)#1
|
||||||
|
memcpy(dst + ^dst + 1, src + 1, ^src)
|
||||||
|
^dst = ^dst + ^src
|
||||||
|
return dst
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Module routines.
|
// Module routines.
|
||||||
//
|
//
|
||||||
def lookupmod(mod)#1
|
|
||||||
byte dci[17]
|
|
||||||
return lookuptbl(modtosym(mod, @dci), symtbl)
|
|
||||||
end
|
|
||||||
def lookupstrmod(str)#1
|
|
||||||
byte mod[17]
|
|
||||||
stodci(str, @mod)
|
|
||||||
return lookupmod(@mod)
|
|
||||||
end
|
|
||||||
def addmod(mod, addr)#0
|
|
||||||
byte dci[17]
|
|
||||||
addsym(modtosym(mod, @dci), addr)
|
|
||||||
end
|
|
||||||
def lookupextern(esd, index)#1
|
def lookupextern(esd, index)#1
|
||||||
word sym, addr
|
word sym, addr
|
||||||
byte str[16]
|
byte str[16]
|
||||||
@ -939,18 +914,24 @@ def lookupdef(addr, deftbl)#1
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
def loadmod(mod)#1
|
def loadmod(mod)#1
|
||||||
word refnum, rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup
|
word rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup
|
||||||
word addr, defaddr, modaddr, modfix, modofst, modend
|
word addr, defaddr, modaddr, modfix, modofst, modend
|
||||||
word deftbl, deflast
|
word deftbl, deflast
|
||||||
word moddep, rld, esd, sym
|
word moddep, rld, esd, sym
|
||||||
byte defbank, str[16], filename[64]
|
byte refnum, defbank, str[16], filename[64]
|
||||||
byte header[128]
|
byte header[128]
|
||||||
//
|
//
|
||||||
// Read the RELocatable module header (first 128 bytes)
|
// Read the RELocatable module header (first 128 bytes)
|
||||||
//
|
//
|
||||||
dcitos(mod, @filename)
|
dcitos(mod, @filename)
|
||||||
refnum = open(@filename, iobuffer)
|
refnum = open(@filename)
|
||||||
if refnum > 0
|
if !refnum
|
||||||
|
//
|
||||||
|
// Try system path
|
||||||
|
//
|
||||||
|
refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
|
||||||
|
fin
|
||||||
|
if refnum
|
||||||
rdlen = read(refnum, @header, 128)
|
rdlen = read(refnum, @header, 128)
|
||||||
modsize = header:0
|
modsize = header:0
|
||||||
moddep = @header.1
|
moddep = @header.1
|
||||||
@ -969,7 +950,7 @@ def loadmod(mod)#1
|
|||||||
// Load module dependencies.
|
// Load module dependencies.
|
||||||
//
|
//
|
||||||
while ^moddep
|
while ^moddep
|
||||||
if !lookupmod(moddep)
|
if !lookuptbl(moddep, symtbl)//lookupmod(moddep)
|
||||||
close(refnum)
|
close(refnum)
|
||||||
refnum = 0
|
refnum = 0
|
||||||
if loadmod(moddep) < 0
|
if loadmod(moddep) < 0
|
||||||
@ -988,7 +969,7 @@ def loadmod(mod)#1
|
|||||||
//
|
//
|
||||||
// Reset read pointer.
|
// Reset read pointer.
|
||||||
//
|
//
|
||||||
refnum = open(@filename, iobuffer)
|
refnum = open(@filename)
|
||||||
rdlen = read(refnum, @header, 128)
|
rdlen = read(refnum, @header, 128)
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
@ -1013,7 +994,7 @@ def loadmod(mod)#1
|
|||||||
//
|
//
|
||||||
// Add module to symbol table.
|
// Add module to symbol table.
|
||||||
//
|
//
|
||||||
addmod(mod, modaddr)
|
addsym(mod, modaddr)//addmod(mod, modaddr)
|
||||||
//
|
//
|
||||||
// Apply all fixups and symbol import/export.
|
// Apply all fixups and symbol import/export.
|
||||||
//
|
//
|
||||||
@ -1181,7 +1162,7 @@ def catalog(optpath)#1
|
|||||||
prstr(@path)
|
prstr(@path)
|
||||||
crout()
|
crout()
|
||||||
fin
|
fin
|
||||||
refnum = open(@path, iobuffer)
|
refnum = open(@path)
|
||||||
if perr
|
if perr
|
||||||
return perr
|
return perr
|
||||||
fin
|
fin
|
||||||
@ -1249,7 +1230,7 @@ def striptrail(strptr)#1
|
|||||||
for i = 1 to ^strptr
|
for i = 1 to ^strptr
|
||||||
if ^(strptr + i) <= ' '
|
if ^(strptr + i) <= ' '
|
||||||
^strptr = i - 1
|
^strptr = i - 1
|
||||||
return strptr
|
break
|
||||||
fin
|
fin
|
||||||
next
|
next
|
||||||
return strptr
|
return strptr
|
||||||
@ -1287,7 +1268,7 @@ def execsys(sysfile)#0
|
|||||||
if ^sysfile
|
if ^sysfile
|
||||||
memcpy($280, sysfile, ^sysfile + 1)
|
memcpy($280, sysfile, ^sysfile + 1)
|
||||||
striptrail(sysfile)
|
striptrail(sysfile)
|
||||||
refnum = open(sysfile, iobuffer)
|
refnum = open(sysfile)
|
||||||
if refnum
|
if refnum
|
||||||
len = read(refnum, databuff, $FFFF)
|
len = read(refnum, databuff, $FFFF)
|
||||||
resetmemfiles()
|
resetmemfiles()
|
||||||
@ -1330,34 +1311,34 @@ end
|
|||||||
//
|
//
|
||||||
heap = *freemem
|
heap = *freemem
|
||||||
//
|
//
|
||||||
|
// Print PLASMA version
|
||||||
|
//
|
||||||
|
prstr("PLASMA Pre "); prbyte(version.1); cout('.'); prbyte(version.0); crout
|
||||||
|
//
|
||||||
// Init symbol table.
|
// Init symbol table.
|
||||||
//
|
//
|
||||||
stodci(@syslibstr, heap)
|
while *sysmodsym
|
||||||
addmod(heap, @version)
|
stodci(sysmodsym=>0, heap)
|
||||||
while *syslibsym
|
addsym(heap, sysmodsym=>2)
|
||||||
stodci(syslibsym=>0, heap)
|
sysmodsym = sysmodsym + 4
|
||||||
addsym(heap, syslibsym=>2)
|
|
||||||
syslibsym = syslibsym + 4
|
|
||||||
loop
|
loop
|
||||||
//
|
//
|
||||||
|
// Set system path
|
||||||
|
//
|
||||||
|
strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
|
||||||
|
syspath = @sysmods // Update external interface table
|
||||||
|
//
|
||||||
// Try to load autorun.
|
// Try to load autorun.
|
||||||
//
|
//
|
||||||
autorun = open(@autorun, iobuffer)
|
autorun = open(@autorun)
|
||||||
if autorun > 0
|
if autorun > 0
|
||||||
cmdln = read(autorun, @syslibstr, 128)
|
cmdln = read(autorun, @sysmodstr, 128)
|
||||||
close(autorun)
|
close(autorun)
|
||||||
else
|
else
|
||||||
//
|
//
|
||||||
// Print some startup info.
|
// Print some startup info.
|
||||||
//
|
//
|
||||||
prstr("PLASMA ")
|
prstr("MEM FREE:$"); prword(availheap); crout
|
||||||
prbyte(version.1)
|
|
||||||
cout('.')
|
|
||||||
prbyte(version.0)
|
|
||||||
crout
|
|
||||||
prstr("MEM FREE:$")
|
|
||||||
prword(availheap)
|
|
||||||
crout
|
|
||||||
fin
|
fin
|
||||||
perr = 0
|
perr = 0
|
||||||
while 1
|
while 1
|
||||||
@ -1372,6 +1353,14 @@ while 1
|
|||||||
is 'P'
|
is 'P'
|
||||||
setpfx(@cmdln)
|
setpfx(@cmdln)
|
||||||
break
|
break
|
||||||
|
is '/'
|
||||||
|
repeat
|
||||||
|
prefix--
|
||||||
|
until prefix[prefix] == '/'
|
||||||
|
if prefix > 1
|
||||||
|
setpfx(@prefix)
|
||||||
|
fin
|
||||||
|
break
|
||||||
is 'V'
|
is 'V'
|
||||||
volumes()
|
volumes()
|
||||||
break
|
break
|
||||||
@ -1400,6 +1389,6 @@ while 1
|
|||||||
crout()
|
crout()
|
||||||
fin
|
fin
|
||||||
prstr(getpfx(@prefix))
|
prstr(getpfx(@prefix))
|
||||||
memcpy(@cmdln, rdstr($BA), 128)
|
strcpy(@cmdln, rdstr($BA))
|
||||||
loop
|
loop
|
||||||
done
|
done
|
||||||
|
129
src/vmsrc/plvm.c
129
src/vmsrc/plvm.c
@ -40,17 +40,47 @@ word *esp = eval_stack + EVAL_STACKSZ;
|
|||||||
|
|
||||||
#define SYMTBLSZ 1024
|
#define SYMTBLSZ 1024
|
||||||
#define SYMSZ 16
|
#define SYMSZ 16
|
||||||
#define MODTBLSZ 128
|
|
||||||
#define MODSZ 16
|
|
||||||
#define MODLSTSZ 32
|
|
||||||
byte symtbl[SYMTBLSZ];
|
byte symtbl[SYMTBLSZ];
|
||||||
byte *lastsym = symtbl;
|
byte *lastsym = symtbl;
|
||||||
byte modtbl[MODTBLSZ];
|
|
||||||
byte *lastmod = modtbl;
|
|
||||||
/*
|
/*
|
||||||
* Predef.
|
* Predef.
|
||||||
*/
|
*/
|
||||||
void interp(code *ip);
|
void interp(code *ip);
|
||||||
|
/*
|
||||||
|
* CMDSYS exports
|
||||||
|
*/
|
||||||
|
char *syslib_exp[] = {
|
||||||
|
"CMDSYS",
|
||||||
|
"MACHID",
|
||||||
|
"PUTC",
|
||||||
|
"PUTLN",
|
||||||
|
"PUTS",
|
||||||
|
"PUTI",
|
||||||
|
"GETC",
|
||||||
|
"GETS",
|
||||||
|
"PUTB",
|
||||||
|
"PUTH",
|
||||||
|
"TOUPPER",
|
||||||
|
"CALL",
|
||||||
|
"SYSCALL",
|
||||||
|
"HEAPMARK",
|
||||||
|
"HEAPALLOCALLIGN",
|
||||||
|
"HEAPALLOC",
|
||||||
|
"HEAPRELEASE",
|
||||||
|
"HEAPAVAIL",
|
||||||
|
"MEMSET",
|
||||||
|
"MEMCPY",
|
||||||
|
"STRCPY",
|
||||||
|
"STRCAT",
|
||||||
|
"SEXT",
|
||||||
|
"DIVMOD",
|
||||||
|
"ISUGT",
|
||||||
|
"ISUGE",
|
||||||
|
"ISULT",
|
||||||
|
"ISULE",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility routines.
|
* Utility routines.
|
||||||
*
|
*
|
||||||
@ -181,19 +211,6 @@ uword add_sym(byte *sym, int addr)
|
|||||||
/*
|
/*
|
||||||
* Module routines.
|
* Module routines.
|
||||||
*/
|
*/
|
||||||
void dump_mod(void)
|
|
||||||
{
|
|
||||||
printf("\nSystem Module Table:\n");
|
|
||||||
dump_tbl(modtbl);
|
|
||||||
}
|
|
||||||
uword lookup_mod(byte *mod)
|
|
||||||
{
|
|
||||||
return lookup_tbl(mod, modtbl);
|
|
||||||
}
|
|
||||||
uword add_mod(byte *mod, int addr)
|
|
||||||
{
|
|
||||||
return add_tbl(mod, addr, &lastmod);
|
|
||||||
}
|
|
||||||
uword defcall_add(int bank, int addr)
|
uword defcall_add(int bank, int addr)
|
||||||
{
|
{
|
||||||
mem_data[lastdef] = bank ? 2 : 1;
|
mem_data[lastdef] = bank ? 2 : 1;
|
||||||
@ -204,7 +221,7 @@ uword defcall_add(int bank, int addr)
|
|||||||
uword def_lookup(byte *cdd, int defaddr)
|
uword def_lookup(byte *cdd, int defaddr)
|
||||||
{
|
{
|
||||||
int i, calldef = 0;
|
int i, calldef = 0;
|
||||||
for (i = 0; cdd[i * 4] == 0x02; i++)
|
for (i = 0; cdd[i * 4] == 0x00; i++)
|
||||||
{
|
{
|
||||||
if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr)
|
if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr)
|
||||||
{
|
{
|
||||||
@ -263,7 +280,7 @@ int load_mod(byte *mod)
|
|||||||
*/
|
*/
|
||||||
while (*moddep)
|
while (*moddep)
|
||||||
{
|
{
|
||||||
if (lookup_mod(moddep) == 0)
|
if (lookup_sym(moddep) == 0)
|
||||||
{
|
{
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
@ -324,7 +341,7 @@ int load_mod(byte *mod)
|
|||||||
/*
|
/*
|
||||||
* Add module to symbol table.
|
* Add module to symbol table.
|
||||||
*/
|
*/
|
||||||
add_mod(mod, modaddr);
|
add_sym(mod, modaddr);
|
||||||
/*
|
/*
|
||||||
* Print out the Re-Location Dictionary.
|
* Print out the Re-Location Dictionary.
|
||||||
*/
|
*/
|
||||||
@ -337,6 +354,7 @@ int load_mod(byte *mod)
|
|||||||
if (show_state) printf("\tDEF CODE");
|
if (show_state) printf("\tDEF CODE");
|
||||||
addr = rld[1] | (rld[2] << 8);
|
addr = rld[1] | (rld[2] << 8);
|
||||||
addr += modfix - MOD_ADDR;
|
addr += modfix - MOD_ADDR;
|
||||||
|
rld[0] = 0; // Set call code to 0
|
||||||
rld[1] = addr;
|
rld[1] = addr;
|
||||||
rld[2] = addr >> 8;
|
rld[2] = addr >> 8;
|
||||||
end = rld - mem_data + 4;
|
end = rld - mem_data + 4;
|
||||||
@ -440,25 +458,29 @@ void call(uword pc)
|
|||||||
char c, sz[64];
|
char c, sz[64];
|
||||||
|
|
||||||
if (show_state)
|
if (show_state)
|
||||||
printf("\nCall code:$%02X\n", mem_data[pc]);
|
printf("\nCall: %s\n", mem_data[pc] ? syslib_exp[mem_data[pc] - 1] : "BYTECODE");
|
||||||
switch (mem_data[pc++])
|
switch (mem_data[pc++])
|
||||||
{
|
{
|
||||||
case 0: // NULL call
|
case 0: // BYTECODE in mem_data
|
||||||
printf("NULL call code\n");
|
|
||||||
break;
|
|
||||||
case 1: // BYTECODE in mem_code
|
|
||||||
//interp(mem_code + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
|
||||||
break;
|
|
||||||
case 2: // BYTECODE in mem_data
|
|
||||||
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
||||||
break;
|
break;
|
||||||
|
case 1: // CMDSYS call
|
||||||
|
printf("CMD call code!\n");
|
||||||
|
break;
|
||||||
|
case 2: // MACHID
|
||||||
|
printf("MACHID call code!\n");
|
||||||
|
break;
|
||||||
case 3: // LIBRARY STDLIB::PUTC
|
case 3: // LIBRARY STDLIB::PUTC
|
||||||
c = POP;
|
c = POP;
|
||||||
if (c == 0x0D)
|
if (c == 0x0D)
|
||||||
c = '\n';
|
c = '\n';
|
||||||
putchar(c);
|
putchar(c);
|
||||||
break;
|
break;
|
||||||
case 4: // LIBRARY STDLIB::PUTS
|
case 4: // LIBRARY STDLIB::PUTNL
|
||||||
|
putchar('\n');
|
||||||
|
fflush(stdout);
|
||||||
|
break;
|
||||||
|
case 5: // LIBRARY STDLIB::PUTS
|
||||||
s = POP;
|
s = POP;
|
||||||
i = mem_data[s++];
|
i = mem_data[s++];
|
||||||
while (i--)
|
while (i--)
|
||||||
@ -469,19 +491,14 @@ void call(uword pc)
|
|||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // LIBRARY STDLIB::PUTSZ
|
case 6: // LIBRARY STDLIB::PUTI
|
||||||
s = POP;
|
i = POP;
|
||||||
while ((c = mem_data[s++]))
|
printf("%d", i);
|
||||||
{
|
|
||||||
if (c == 0x0D)
|
|
||||||
c = '\n';
|
|
||||||
putchar(c);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 6: // LIBRARY STDLIB::GETC
|
case 7: // LIBRARY STDLIB::GETC
|
||||||
PUSH(getchar());
|
PUSH(getchar());
|
||||||
break;
|
break;
|
||||||
case 7: // LIBRARY STDLIB::GETS
|
case 8: // LIBRARY STDLIB::GETS
|
||||||
gets(sz);
|
gets(sz);
|
||||||
for (i = 0; sz[i]; i++)
|
for (i = 0; sz[i]; i++)
|
||||||
mem_data[0x200 + i] = sz[i];
|
mem_data[0x200 + i] = sz[i];
|
||||||
@ -489,19 +506,8 @@ void call(uword pc)
|
|||||||
mem_data[0x1FF] = i;
|
mem_data[0x1FF] = i;
|
||||||
PUSH(i);
|
PUSH(i);
|
||||||
break;
|
break;
|
||||||
case 8: // LIBRARY STDLIB::PUTNL
|
|
||||||
putchar('\n');
|
|
||||||
fflush(stdout);
|
|
||||||
break;
|
|
||||||
case 9: // LIBRARY STDLIB::MACHID
|
|
||||||
PUSH(0x0000);
|
|
||||||
break;
|
|
||||||
case 10: // LIBRARY STDLIB::PUTI
|
|
||||||
i = POP;
|
|
||||||
printf("%d", i);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
printf("\nBad call code:$%02X\n", mem_data[pc - 1]);
|
printf("\nUnimplemented call code:$%02X\n", mem_data[pc - 1]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -875,18 +881,6 @@ void interp(code *ip)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *syslib_exp[] = {
|
|
||||||
"PUTC",
|
|
||||||
"PUTS",
|
|
||||||
"PUTSZ",
|
|
||||||
"GETC",
|
|
||||||
"GETS",
|
|
||||||
"PUTLN",
|
|
||||||
"MACHID",
|
|
||||||
"PUTI",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
byte dci[32];
|
byte dci[32];
|
||||||
@ -904,17 +898,16 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Add default library.
|
* Add default library.
|
||||||
*/
|
*/
|
||||||
stodci("CMDSYS", dci);
|
|
||||||
add_mod(dci, 0xFFFF);
|
|
||||||
for (i = 0; syslib_exp[i]; i++)
|
for (i = 0; syslib_exp[i]; i++)
|
||||||
{
|
{
|
||||||
mem_data[i] = i + 3;
|
mem_data[i] = i;
|
||||||
stodci(syslib_exp[i], dci);
|
stodci(syslib_exp[i], dci);
|
||||||
add_sym(dci, i);
|
add_sym(dci, i+1);
|
||||||
}
|
}
|
||||||
if (argc)
|
if (argc)
|
||||||
{
|
{
|
||||||
stodci(*argv, dci);
|
stodci(*argv, dci);
|
||||||
|
if (show_state) dump_sym();
|
||||||
load_mod(dci);
|
load_mod(dci);
|
||||||
if (show_state) dump_sym();
|
if (show_state) dump_sym();
|
||||||
argc--;
|
argc--;
|
||||||
|
@ -863,15 +863,15 @@ BRGT INX
|
|||||||
CMP ESTKL,X
|
CMP ESTKL,X
|
||||||
LDA ESTKH-1,X
|
LDA ESTKH-1,X
|
||||||
SBC ESTKH,X
|
SBC ESTKH,X
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
BRLT INX
|
BRLT INX
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
CMP ESTKL-1,X
|
CMP ESTKL-1,X
|
||||||
LDA ESTKH,X
|
LDA ESTKH,X
|
||||||
SBC ESTKH-1,X
|
SBC ESTKH-1,X
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
IBRNCH LDA IPL
|
IBRNCH LDA IPL
|
||||||
CLC
|
CLC
|
||||||
ADC ESTKL,X
|
ADC ESTKL,X
|
||||||
|
@ -281,8 +281,8 @@ BYE LDY DEFCMD
|
|||||||
STA STRBUF,Y
|
STA STRBUF,Y
|
||||||
DEY
|
DEY
|
||||||
BPL -
|
BPL -
|
||||||
INY ; CLEAR CMDLINE BUFF
|
; INY ; CLEAR CMDLINE BUFF
|
||||||
STY $01FF
|
; STY $01FF
|
||||||
CMDENTRY = *
|
CMDENTRY = *
|
||||||
;
|
;
|
||||||
; DEACTIVATE 80 COL CARDS
|
; DEACTIVATE 80 COL CARDS
|
||||||
@ -338,8 +338,9 @@ CMDENTRY = *
|
|||||||
;
|
;
|
||||||
; INIT VM ENVIRONMENT STACK POINTERS
|
; INIT VM ENVIRONMENT STACK POINTERS
|
||||||
;
|
;
|
||||||
; LDA #$00 ; INIT FRAME POINTER
|
; LDA #$00
|
||||||
STA PPL
|
STA $01FF ; CLEAR CMDLINE BUFF
|
||||||
|
STA PPL ; INIT FRAME POINTER
|
||||||
STA IFPL
|
STA IFPL
|
||||||
LDA #$BF
|
LDA #$BF
|
||||||
STA PPH
|
STA PPH
|
||||||
@ -347,6 +348,13 @@ CMDENTRY = *
|
|||||||
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
|
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
|
||||||
TXS
|
TXS
|
||||||
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
|
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
|
||||||
|
;
|
||||||
|
; CHANGE CMD STRING TO SYSPATH STRING
|
||||||
|
;
|
||||||
|
LDA STRBUF
|
||||||
|
SEC
|
||||||
|
SBC #$03
|
||||||
|
STA STRBUF
|
||||||
JMP $2000 ; JUMP TO LOADED SYSTEM COMMAND
|
JMP $2000 ; JUMP TO LOADED SYSTEM COMMAND
|
||||||
;
|
;
|
||||||
; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT
|
; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT
|
||||||
@ -1367,15 +1375,15 @@ BRGT INX
|
|||||||
CMP ESTKL,X
|
CMP ESTKL,X
|
||||||
LDA ESTKH-1,X
|
LDA ESTKH-1,X
|
||||||
SBC ESTKH,X
|
SBC ESTKH,X
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
BRLT INX
|
BRLT INX
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
CMP ESTKL-1,X
|
CMP ESTKL-1,X
|
||||||
LDA ESTKH,X
|
LDA ESTKH,X
|
||||||
SBC ESTKH-1,X
|
SBC ESTKH-1,X
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
IBRNCH LDA IPL
|
IBRNCH LDA IPL
|
||||||
CLC
|
CLC
|
||||||
ADC ESTKL,X
|
ADC ESTKL,X
|
||||||
|
@ -1020,15 +1020,15 @@ BRGT INX
|
|||||||
CMP ESTKL,X
|
CMP ESTKL,X
|
||||||
LDA ESTKH-1,X
|
LDA ESTKH-1,X
|
||||||
SBC ESTKH,X
|
SBC ESTKH,X
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
BRLT INX
|
BRLT INX
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
CMP ESTKL-1,X
|
CMP ESTKL-1,X
|
||||||
LDA ESTKH,X
|
LDA ESTKH,X
|
||||||
SBC ESTKH-1,X
|
SBC ESTKH-1,X
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
IBRNCH LDA IPL
|
IBRNCH LDA IPL
|
||||||
CLC
|
CLC
|
||||||
ADC ESTKL,X
|
ADC ESTKL,X
|
||||||
|
@ -130,10 +130,10 @@ BADCPU !TEXT "65C802/65C816 CPU REQUIRED.", 13
|
|||||||
;*
|
;*
|
||||||
;* INITIALIZE STACK
|
;* INITIALIZE STACK
|
||||||
;*
|
;*
|
||||||
INITSP LDX #$FE
|
;INITSP LDX #$FE
|
||||||
TXS
|
; TXS
|
||||||
LDX #$00
|
; LDX #$00
|
||||||
STX $01FF
|
; STX $01FF
|
||||||
;*
|
;*
|
||||||
;* DISCONNECT /RAM
|
;* DISCONNECT /RAM
|
||||||
;*
|
;*
|
||||||
@ -361,8 +361,8 @@ BYE LDY DEFCMD
|
|||||||
STA STRBUF,Y
|
STA STRBUF,Y
|
||||||
DEY
|
DEY
|
||||||
BPL -
|
BPL -
|
||||||
INY ; CLEAR CMDLINE BUFF
|
; INY ; CLEAR CMDLINE BUFF
|
||||||
STY $01FF
|
; STY $01FF
|
||||||
CMDENTRY = *
|
CMDENTRY = *
|
||||||
;
|
;
|
||||||
; DEACTIVATE 80 COL CARDS
|
; DEACTIVATE 80 COL CARDS
|
||||||
@ -425,8 +425,9 @@ CMDENTRY = *
|
|||||||
;
|
;
|
||||||
; INIT VM ENVIRONMENT STACK POINTERS
|
; INIT VM ENVIRONMENT STACK POINTERS
|
||||||
;
|
;
|
||||||
; LDA #$00 ; INIT FRAME POINTER
|
; LDA #$00
|
||||||
STA PPL
|
STA $01FF ; CLEAR CMDLINE BUFF
|
||||||
|
STA PPL ; INIT FRAME POINTER
|
||||||
STA IFPL
|
STA IFPL
|
||||||
LDA #$BF
|
LDA #$BF
|
||||||
STA PPH
|
STA PPH
|
||||||
@ -434,6 +435,13 @@ CMDENTRY = *
|
|||||||
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
|
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
|
||||||
TXS
|
TXS
|
||||||
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
|
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
|
||||||
|
;
|
||||||
|
; CHANGE CMD STRING TO SYSPATH STRING
|
||||||
|
;
|
||||||
|
LDA STRBUF
|
||||||
|
SEC
|
||||||
|
SBC #$03
|
||||||
|
STA STRBUF
|
||||||
JMP $2000 ; JUMP TO LOADED SYSTEM COMMAND
|
JMP $2000 ; JUMP TO LOADED SYSTEM COMMAND
|
||||||
;
|
;
|
||||||
; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT
|
; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT
|
||||||
@ -1238,8 +1246,8 @@ BRGT PLA
|
|||||||
SEC
|
SEC
|
||||||
SBC TOS,S
|
SBC TOS,S
|
||||||
BVS +
|
BVS +
|
||||||
BMI BRNCH
|
|
||||||
BPL NOBRNCH
|
BPL NOBRNCH
|
||||||
|
BMI BRNCH
|
||||||
+ BMI NOBRNCH
|
+ BMI NOBRNCH
|
||||||
BPL BRNCH
|
BPL BRNCH
|
||||||
BRLT PLA
|
BRLT PLA
|
||||||
@ -1567,7 +1575,7 @@ LEAVE +ACCMEM8 ; 8 BIT A/M
|
|||||||
INX
|
INX
|
||||||
+ CPX ESP
|
+ CPX ESP
|
||||||
BNE -
|
BNE -
|
||||||
!IF DEBUG {
|
!IF DEBUG {
|
||||||
STX TMPL
|
STX TMPL
|
||||||
TSX
|
TSX
|
||||||
CPX HWSP
|
CPX HWSP
|
||||||
|
@ -29,20 +29,17 @@ predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
|
|||||||
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
|
||||||
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
|
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1
|
||||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
||||||
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, divmod(a,b)#2
|
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2
|
||||||
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
|
predef execmod(modfile)#1
|
||||||
//
|
//
|
||||||
// System variables.
|
// System variables.
|
||||||
//
|
//
|
||||||
word version = $0099 // 00.99
|
word version = $0100 // 01.00
|
||||||
word systemflags = 0
|
word syspath
|
||||||
|
word cmdptr
|
||||||
|
word = @execmod
|
||||||
byte refcons = 0
|
byte refcons = 0
|
||||||
byte devcons = 0
|
byte devcons = 0
|
||||||
word heap = $2000
|
|
||||||
byte modid = 0
|
|
||||||
byte modseg[15]
|
|
||||||
word symtbl, lastsym
|
|
||||||
byte perr, terr, lerr
|
|
||||||
//
|
//
|
||||||
// String pool.
|
// String pool.
|
||||||
//
|
//
|
||||||
@ -55,13 +52,9 @@ byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E',
|
|||||||
//
|
//
|
||||||
byte machid = $F2 // Apple ///, 80 columns
|
byte machid = $F2 // Apple ///, 80 columns
|
||||||
//
|
//
|
||||||
// Command line pointer
|
|
||||||
//
|
|
||||||
word cmdptr
|
|
||||||
//
|
|
||||||
// Standard Library exported functions.
|
// Standard Library exported functions.
|
||||||
//
|
//
|
||||||
byte syslibstr[] = "CMDSYS"
|
byte sysmodstr[] = "CMDSYS"
|
||||||
byte machidstr[] = "MACHID"
|
byte machidstr[] = "MACHID"
|
||||||
byte sysstr[] = "SYSCALL"
|
byte sysstr[] = "SYSCALL"
|
||||||
byte callstr[] = "CALL"
|
byte callstr[] = "CALL"
|
||||||
@ -83,13 +76,15 @@ byte uisgtstr[] = "ISUGT"
|
|||||||
byte uisgestr[] = "ISUGE"
|
byte uisgestr[] = "ISUGE"
|
||||||
byte uisltstr[] = "ISULT"
|
byte uisltstr[] = "ISULT"
|
||||||
byte uislestr[] = "ISULE"
|
byte uislestr[] = "ISULE"
|
||||||
|
byte sysmods[] // overlay with exported strings
|
||||||
|
byte sextstr[] = "SEXT"
|
||||||
byte divmodstr[] = "DIVMOD"
|
byte divmodstr[] = "DIVMOD"
|
||||||
byte loadstr[] = "MODLOAD"
|
byte loadstr[] = "MODLOAD"
|
||||||
byte execstr[] = "MODEXEC"
|
byte execstr[] = "MODEXEC"
|
||||||
byte modadrstr[] = "MODADDR"
|
byte modadrstr[] = "MODADDR"
|
||||||
byte argstr[] = "ARGS"
|
|
||||||
byte prefix[] // Overlay with exported symbols table
|
byte prefix[] // Overlay with exported symbols table
|
||||||
word exports[] = @sysstr, @syscall
|
word exports[] = @sysmodstr, @version
|
||||||
|
word = @sysstr, @syscall
|
||||||
word = @callstr, @call
|
word = @callstr, @call
|
||||||
word = @putcstr, @cout
|
word = @putcstr, @cout
|
||||||
word = @putlnstr, @crout
|
word = @putlnstr, @crout
|
||||||
@ -109,14 +104,20 @@ word = @uisgtstr, @uword_isgt
|
|||||||
word = @uisgestr, @uword_isge
|
word = @uisgestr, @uword_isge
|
||||||
word = @uisltstr, @uword_islt
|
word = @uisltstr, @uword_islt
|
||||||
word = @uislestr, @uword_isle
|
word = @uislestr, @uword_isle
|
||||||
|
word = @sextstr, @sext
|
||||||
word = @divmodstr, @divmod
|
word = @divmodstr, @divmod
|
||||||
word = @loadstr, @loadmod
|
|
||||||
word = @execstr, @execmod
|
|
||||||
word = @modadrstr, @lookupstrmod
|
|
||||||
word = @machidstr, @machid
|
word = @machidstr, @machid
|
||||||
word = @argstr, @cmdptr
|
|
||||||
word = 0
|
word = 0
|
||||||
word syslibsym = @exports
|
word sysmodsym = @exports
|
||||||
|
//
|
||||||
|
// System variables.
|
||||||
|
//
|
||||||
|
word systemflags = 0
|
||||||
|
word heap = $2000
|
||||||
|
byte modid = 0
|
||||||
|
byte modseg[15]
|
||||||
|
word symtbl, lastsym
|
||||||
|
byte perr, terr, lerr
|
||||||
//
|
//
|
||||||
// CALL SOS
|
// CALL SOS
|
||||||
// SYSCALL(CMD, PARAMS)
|
// SYSCALL(CMD, PARAMS)
|
||||||
@ -436,6 +437,14 @@ _divmod DEX
|
|||||||
STA ESTKH,X
|
STA ESTKH,X
|
||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
|
asm sext(a)#1
|
||||||
|
LDY #$00
|
||||||
|
LDA ESTKL,X
|
||||||
|
BPL +
|
||||||
|
DEY
|
||||||
|
+ STY ESTKH,X
|
||||||
|
RTS
|
||||||
|
end
|
||||||
//
|
//
|
||||||
// Addresses of internal routines.
|
// Addresses of internal routines.
|
||||||
//
|
//
|
||||||
@ -557,27 +566,27 @@ end
|
|||||||
// until !(c & $80)
|
// until !(c & $80)
|
||||||
// return dci
|
// return dci
|
||||||
//end
|
//end
|
||||||
asm modtosym(mod, dci)#1
|
//asm modtosym(mod, dci)#1
|
||||||
LDA ESTKL+1,X
|
// LDA ESTKL+1,X
|
||||||
STA SRCL
|
// STA SRCL
|
||||||
LDA ESTKH+1,X
|
// LDA ESTKH+1,X
|
||||||
STA SRCH
|
// STA SRCH
|
||||||
LDA ESTKL,X
|
// LDA ESTKL,X
|
||||||
STA ESTKL+1,X
|
// STA ESTKL+1,X
|
||||||
STA DSTL
|
// STA DSTL
|
||||||
LDA ESTKH,X
|
// LDA ESTKH,X
|
||||||
STA ESTKH+1,X
|
// STA ESTKH+1,X
|
||||||
STA DSTH
|
// STA DSTH
|
||||||
INX
|
// INX
|
||||||
LDY #$00
|
// LDY #$00
|
||||||
LDA #'#'+$80
|
// LDA #'#'+$80
|
||||||
- STA (DST),Y
|
//- STA (DST),Y
|
||||||
ASL
|
// ASL
|
||||||
LDA (SRC),Y
|
// LDA (SRC),Y
|
||||||
INY
|
// INY
|
||||||
BCS -
|
// BCS -
|
||||||
RTS
|
// RTS
|
||||||
end
|
//end
|
||||||
//
|
//
|
||||||
// Lookup routines.
|
// Lookup routines.
|
||||||
//
|
//
|
||||||
@ -913,21 +922,29 @@ def addsym(sym, addr)#0
|
|||||||
lastsym = lastsym + 3
|
lastsym = lastsym + 3
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
|
// String routines.
|
||||||
|
//
|
||||||
|
def strcpy(dst, src)#1
|
||||||
|
memcpy(dst+1, src+1, ^src)
|
||||||
|
^dst = ^src
|
||||||
|
return dst
|
||||||
|
end
|
||||||
|
def strcat(dst, src)#1
|
||||||
|
memcpy(dst + ^dst + 1, src + 1, ^src)
|
||||||
|
^dst = ^dst + ^src
|
||||||
|
return dst
|
||||||
|
end
|
||||||
|
//
|
||||||
// Module routines.
|
// Module routines.
|
||||||
//
|
//
|
||||||
def lookupmod(mod)#1
|
//def lookupmod(mod)#1
|
||||||
byte dci[17]
|
// byte dci[17]
|
||||||
return lookuptbl(modtosym(mod, @dci), symtbl)
|
// return lookuptbl(modtosym(mod, @dci), symtbl)
|
||||||
end
|
//end
|
||||||
def lookupstrmod(str)#1
|
//def addmod(mod, addr)#0
|
||||||
byte mod[17]
|
// byte dci[17]
|
||||||
stodci(str, @mod)
|
// addsym(modtosym(mod, @dci), addr)
|
||||||
return lookupmod(@mod)
|
//end
|
||||||
end
|
|
||||||
def addmod(mod, addr)#0
|
|
||||||
byte dci[17]
|
|
||||||
addsym(modtosym(mod, @dci), addr)
|
|
||||||
end
|
|
||||||
def lookupextern(esd, index)#1
|
def lookupextern(esd, index)#1
|
||||||
word sym, addr
|
word sym, addr
|
||||||
byte str[16]
|
byte str[16]
|
||||||
@ -980,7 +997,13 @@ def loadmod(mod)#1
|
|||||||
//
|
//
|
||||||
dcitos(mod, @filename)
|
dcitos(mod, @filename)
|
||||||
refnum = open(@filename)
|
refnum = open(@filename)
|
||||||
if refnum > 0
|
if !refnum
|
||||||
|
//
|
||||||
|
// Try system path
|
||||||
|
//
|
||||||
|
refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
|
||||||
|
fin
|
||||||
|
if refnum
|
||||||
rdlen = read(refnum, @header, 128)
|
rdlen = read(refnum, @header, 128)
|
||||||
modsize = header:0
|
modsize = header:0
|
||||||
moddep = @header.1
|
moddep = @header.1
|
||||||
@ -999,7 +1022,7 @@ def loadmod(mod)#1
|
|||||||
// Load module dependencies.
|
// Load module dependencies.
|
||||||
//
|
//
|
||||||
while ^moddep
|
while ^moddep
|
||||||
if !lookupmod(moddep)
|
if !lookuptbl(moddep, symtbl)
|
||||||
if refnum
|
if refnum
|
||||||
close(refnum)
|
close(refnum)
|
||||||
refnum = 0
|
refnum = 0
|
||||||
@ -1045,7 +1068,7 @@ def loadmod(mod)#1
|
|||||||
//
|
//
|
||||||
// Add module to symbol table.
|
// Add module to symbol table.
|
||||||
//
|
//
|
||||||
addmod(mod, modaddr)
|
addsym(mod, modaddr)
|
||||||
//
|
//
|
||||||
// Apply all fixups and symbol import/export.
|
// Apply all fixups and symbol import/export.
|
||||||
//
|
//
|
||||||
@ -1260,15 +1283,16 @@ def stripspaces(strptr)#0
|
|||||||
^strptr = ^strptr - 1
|
^strptr = ^strptr - 1
|
||||||
loop
|
loop
|
||||||
end
|
end
|
||||||
def striptrail(strptr)#0
|
def striptrail(strptr)#1
|
||||||
byte i
|
byte i
|
||||||
|
|
||||||
for i = 1 to ^strptr
|
for i = 1 to ^strptr
|
||||||
if (strptr)[i] <= ' '
|
if (strptr)[i] <= ' '
|
||||||
^strptr = i - 1
|
^strptr = i - 1
|
||||||
return
|
break
|
||||||
fin
|
fin
|
||||||
next
|
next
|
||||||
|
return strptr
|
||||||
end
|
end
|
||||||
def parsecmd(strptr)#1
|
def parsecmd(strptr)#1
|
||||||
byte cmd
|
byte cmd
|
||||||
@ -1312,19 +1336,26 @@ end
|
|||||||
//
|
//
|
||||||
init_cons
|
init_cons
|
||||||
//
|
//
|
||||||
|
// Print PLASMA version
|
||||||
|
//
|
||||||
|
prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
|
||||||
|
//
|
||||||
// Init 2K symbol table.
|
// Init 2K symbol table.
|
||||||
//
|
//
|
||||||
seg_find($00, @symtbl, @lastsym, $08, $11)
|
seg_find($00, @symtbl, @lastsym, $08, $11)
|
||||||
lastsym = symtbl & $FF00
|
lastsym = symtbl & $FF00
|
||||||
xpokeb(symtbl.0, lastsym, 0)
|
xpokeb(symtbl.0, lastsym, 0)
|
||||||
stodci(@syslibstr, heap)
|
while *sysmodsym
|
||||||
addmod(heap, @version)
|
stodci(sysmodsym=>0, heap)
|
||||||
while *syslibsym
|
addsym(heap, sysmodsym=>2)
|
||||||
stodci(syslibsym=>0, heap)
|
sysmodsym = sysmodsym + 4
|
||||||
addsym(heap, syslibsym=>2)
|
|
||||||
syslibsym = syslibsym + 4
|
|
||||||
loop
|
loop
|
||||||
//
|
//
|
||||||
|
// Clear system path
|
||||||
|
//
|
||||||
|
sysmods = 0
|
||||||
|
syspath = @sysmods
|
||||||
|
//
|
||||||
// Try to load autorun.
|
// Try to load autorun.
|
||||||
//
|
//
|
||||||
cmdptr = heap
|
cmdptr = heap
|
||||||
@ -1337,11 +1368,6 @@ else
|
|||||||
//
|
//
|
||||||
// Print some startup info.
|
// Print some startup info.
|
||||||
//
|
//
|
||||||
prstr("PLASMA ")
|
|
||||||
prbyte(version.1)
|
|
||||||
cout('.')
|
|
||||||
prbyte(version.0)
|
|
||||||
crout
|
|
||||||
prstr("MEM:$")
|
prstr("MEM:$")
|
||||||
prword(availheap)
|
prword(availheap)
|
||||||
crout
|
crout
|
||||||
@ -1361,11 +1387,15 @@ while 1
|
|||||||
is 'P'
|
is 'P'
|
||||||
setpfx(cmdptr)
|
setpfx(cmdptr)
|
||||||
break
|
break
|
||||||
|
is 'S'
|
||||||
|
setpfx(cmdptr)
|
||||||
|
strcat(getpfx(@sysmods), "SYS/"))
|
||||||
|
break
|
||||||
is 'V'
|
is 'V'
|
||||||
volumes
|
volumes
|
||||||
break
|
break
|
||||||
is '+'
|
is '+'
|
||||||
execmod(cmdptr)
|
execmod(striptrail(cmdptr))
|
||||||
write(refcons, @textmode, 3)
|
write(refcons, @textmode, 3)
|
||||||
break
|
break
|
||||||
otherwise
|
otherwise
|
||||||
|
@ -38,7 +38,7 @@ pod=comment_doc
|
|||||||
|
|
||||||
[keywords]
|
[keywords]
|
||||||
# all items must be in one line
|
# all items must be in one line
|
||||||
primary=done include import export struc const word byte var char and predef asm def end not or repeat until continue break for to downto next step when wend is otherwise if else elsif fin while loop return
|
primary=done include import export struc const word byte var char res and predef asm def end not or repeat until continue break for to downto next step when wend is otherwise if else elsif fin while loop return
|
||||||
|
|
||||||
[settings]
|
[settings]
|
||||||
# default extension used when saving files
|
# default extension used when saving files
|
||||||
|
Loading…
x
Reference in New Issue
Block a user