1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2026-03-12 01:41:40 +00:00

362 Commits
v1.1a ... DP2

Author SHA1 Message Date
David Schmenk
3bb038b1d5 Update README.md 2019-12-29 06:39:33 -08:00
David Schmenk
74f00b9764 Direct link to change list for DP2 2019-12-29 06:39:17 -08:00
David Schmenk
3caa4b909c More DP2 change description 2019-12-29 06:37:54 -08:00
David Schmenk
80a6b2d4b7 Developer Preview 2 Release 2019-12-28 20:39:43 -08:00
David Schmenk
262a799a9d Update SOS images 2019-12-28 18:52:58 -08:00
Dave Schmenk
eb076459e9 Fix all remaining NOJIT issues (defentry size discrepancy) 2019-12-28 18:48:15 -08:00
David Schmenk
f5b0fb86b4 Not loading NOJIT interpreter correctly 2019-12-28 17:36:34 -08:00
David Schmenk
64f4f56379 Add Apple /// non-jit default to free up a little memory and update images to DP2 2019-12-28 16:18:51 -08:00
Dave Schmenk
8c885a6b8b Remove old pixmap data 2019-12-28 13:40:04 -08:00
David Schmenk
c09b15f377 A little re-org and assembly-izing 2019-12-28 12:03:59 -08:00
David Schmenk
4a4468cc22 Fix divmod7 for negative numbers 2019-12-28 09:47:24 -08:00
David Schmenk
322546a0b1 Add sprite center 2019-12-28 08:19:31 -08:00
David Schmenk
b5f832b0b2 Fix simple line plot routine 2019-12-27 19:01:01 -08:00
David Schmenk
c7c69fe0d5 Update line spacing 2019-12-27 18:37:21 -08:00
David Schmenk
8a960f018b Fix lines in all directions 2019-12-27 17:51:31 -08:00
David Schmenk
a056e00e93 Clean up some build problems 2019-12-27 15:17:53 -08:00
David Schmenk
efead509ad Assembly-ize many things and clip sprites 2019-12-27 14:46:10 -08:00
Dave Schmenk
bc532f4458 Load/Save sprites to a file 2019-12-26 22:37:07 -08:00
David Schmenk
cec1252ff6 Copy sprite library over TFTP 2019-12-26 21:17:57 -08:00
David Schmenk
4186c5170d Break out sprite library 2019-12-26 21:13:46 -08:00
David Schmenk
f829682876 Assembly-ize mahorline 2019-12-26 19:21:04 -08:00
David Schmenk
755c4b424a Assembly-ize some rotuines 2019-12-26 16:01:38 -08:00
David Schmenk
e258131e71 Assemly-ize some routines 2019-12-26 11:46:11 -08:00
David Schmenk
8aae1077ee Sprite list test 2019-12-25 12:25:28 -08:00
David Schmenk
dd721f5a75 HGR sprite library WIP 2019-12-25 10:23:50 -08:00
Dave Schmenk
1f94b7331a export divmod7 2019-12-24 16:00:49 -08:00
Dave Schmenk
7ba288d2d6 HGR lib WIP 2019-12-24 15:58:19 -08:00
David Schmenk
a77c50c90a Add 32 bit integer librbary just to print out file sizes in CAT 2019-12-24 12:02:56 -08:00
David Schmenk
5f8f6f0a97 int32 WIP 2019-12-23 17:16:03 -08:00
David Schmenk
2197286604 int32 WIP 2019-12-22 21:41:53 -08:00
Dave Schmenk
5ca96095cf New 32 bit integer library 2019-12-22 18:44:58 -08:00
David Schmenk
4aa8c8da1f Add utils source and reorg 2019-12-21 08:30:04 -08:00
Dave Schmenk
48a33a4432 Break out the utils 2019-12-20 17:52:03 -08:00
David Schmenk
91a1b16807 show & change af files type and aux 2019-12-20 17:50:10 -08:00
Dave Schmenk
ea6656d05b Basic file managing utilites 2019-12-20 16:26:10 -08:00
David Schmenk
3161692d4a Fix line edit changed flag 2019-12-20 10:20:09 -08:00
David Schmenk
3d91e4175b editine c;eanip. still loses ctrl-d once in awhile 2019-12-20 03:36:03 -08:00
David Schmenk
15b4551b2a Editor write file change to identify very rare write corruption 2019-12-20 00:49:12 -08:00
David Schmenk
8df7cea4a0 Add optional goto line number to command line load filename 2019-12-19 20:42:37 -08:00
David Schmenk
af90f40f32 in-line simple line routine 2019-12-19 19:38:26 -08:00
David Schmenk
44c8bf9a13 Premature GRLIB checking 2019-12-19 18:48:14 -08:00
David Schmenk
ae5e5b4237 GRLIB WIP 2019-12-19 18:30:22 -08:00
Dave Schmenk
1cd9156d8d First lores graphics library add 2019-12-19 18:13:59 -08:00
Dave Schmenk
0f1a15fb4a SOS.INTERP launcher fix and graphics libs WIP 2019-12-19 18:11:59 -08:00
Dave Schmenk
b9c5a8cb23 More WIP for the graphics libraries 2019-12-19 14:27:08 -08:00
David Schmenk
72f7dea67f Clean up DGRlib 2019-12-19 10:22:26 -08:00
Dave Schmenk
04139858fc WIP for graphics libraries 2019-12-18 21:48:52 -08:00
Dave Schmenk
0b750d46c5 Back to fun HGR stuff 2019-12-18 18:59:24 -08:00
David Schmenk
7a9123b261 Fixes and optimizations for the value of zero, my hero. 2019-12-17 21:43:05 -08:00
Dave Schmenk
10a98d5392 Seriously broken dividing zero by anything 2019-12-17 21:20:09 -08:00
Dave Schmenk
ff3d3c0b87 Simple 65C02 opts I didn't do before. 2019-12-17 16:51:33 -08:00
Dave Schmenk
60e556cc63 more low hanging opts (and fix previous cross compiler opt) 2019-12-17 14:52:35 -08:00
Dave Schmenk
b81e911857 Snag a few more easy optimizations 2019-12-17 13:30:09 -08:00
Dave Schmenk
ae5ea36e87 Remove #$%&! TAB characters 2019-12-17 11:01:05 -08:00
Dave Schmenk
1afb559849 Remove extraneous OK printouts 2019-12-17 10:59:06 -08:00
David Schmenk
3ce76f7308 simplify indent/undent code 2019-12-17 08:11:07 -08:00
David Schmenk
f937e8265e Update images with edit tab/detab fixes 2019-12-16 10:09:56 -08:00
Dave Schmenk
e1e16ef36d Better blank line detab 2019-12-16 10:05:07 -08:00
Dave Schmenk
6cabe160c4 Fix empty line TABbing 2019-12-16 09:03:34 -08:00
David Schmenk
454ecb29a8 Improve indent/undent and toggle gutter view. Additional compiler stats 2019-12-16 08:25:58 -08:00
Dave Schmenk
9011b1cc64 Add more compiler stats 2019-12-15 16:33:09 -08:00
David Schmenk
bc45a9263c Fix some editor redraw issues 2019-12-15 13:24:26 -08:00
David Schmenk
72ddf025e3 Update editor docs 2019-12-14 19:25:01 -08:00
David Schmenk
a902bc4c97 DP 1ED (editor!) release 2019-12-14 18:42:56 -08:00
Dave Schmenk
c7f48765b2 Return to editor when toggling lower-case chip support 2019-12-14 17:58:35 -08:00
Dave Schmenk
d3c1b8881a Merge branch 'master' of https://github.com/dschmenk/PLASMA 2019-12-14 17:43:29 -08:00
Dave Schmenk
27129fe152 Upgrade editor to programmers editor 2019-12-14 17:42:39 -08:00
David Schmenk
203b88a979 Edit with auto-indent 2019-12-13 19:48:11 -08:00
Dave Schmenk
f67e58011a Auto-indent for editor 2019-12-13 13:30:54 -08:00
Dave Schmenk
18102a319a Botched filename 2019-12-12 11:24:00 -08:00
Dave Schmenk
bbf0a0f666 Make image names a little more sensical 2019-12-12 11:22:46 -08:00
David Schmenk
8e124ca05b Update docs for DP 1a 2019-12-12 09:59:41 -08:00
David Schmenk
f90e339b01 Update Apple /// JIT and images to DP 1a 2019-12-12 09:56:05 -08:00
Dave Schmenk
8364f5c631 Fix premature restore of jitcodeptr in modexec 2019-12-12 01:13:05 -08:00
Dave Schmenk
f5236f2a1d More profiling? 2019-12-08 17:13:43 -08:00
Dave Schmenk
d91ca59b52 Additional jit16 tuning 2019-12-08 17:06:20 -08:00
Dave Schmenk
0981cae313 Merge branch 'master' of https://github.com/dschmenk/PLASMA 2019-12-08 16:51:01 -08:00
Dave Schmenk
fb989e22e4 profile jit16 default values 2019-12-08 16:48:23 -08:00
David Schmenk
1a230ab165 typo 2019-12-08 14:23:12 -08:00
David Schmenk
987a546bf6 Add SANE floating point file copy directions 2019-12-08 13:37:47 -08:00
Dave Schmenk
5088e67de5 Update image name for 800K full install 2019-12-08 12:33:52 -08:00
David Schmenk
6305c74b65 Update issues 2019-12-07 19:59:55 -08:00
David Schmenk
df77781c17 Automatic configuration 2019-12-07 19:56:14 -08:00
David Schmenk
9fc8ee56a7 Update documentation 2019-12-07 19:49:03 -08:00
David Schmenk
30cdd22211 Update images 2019-12-07 19:34:12 -08:00
David Schmenk
dfbc296311 Make mkrel and tftprel consistent 2019-12-07 18:00:12 -08:00
Dave Schmenk
0df8f864e7 Add autorun TFTPD floppy image 2019-12-07 17:06:54 -08:00
Dave Schmenk
517b60d86f TFTP full release to physical Apple II 2019-12-07 17:03:31 -08:00
Dave Schmenk
e2d1fb3ba4 Add online volume call and more tftp scripts 2019-12-07 13:42:03 -08:00
Dave Schmenk
1dc0d252f8 Fix is_hw test for 16 bit JIT 2019-12-06 18:14:08 -08:00
Dave Schmenk
7f6f9e7bbd Fix directory creation ops 2019-12-06 10:23:38 -08:00
Dave Schmenk
1a9ab9629b Copy FP modules 2019-12-01 15:48:41 -08:00
David Schmenk
db6bc55df3 Back out DINTRP opt as ENTER needs Y to bee zero 2019-12-01 15:39:21 -08:00
David Schmenk
8f85445700 Back out DINTRP opt as ENTER requires Y being zero 2019-12-01 15:36:48 -08:00
Dave Schmenk
1242b53824 Back out some of the DINTRP optimizations. Dependecy on Y being szero in ENTER 2019-12-01 15:24:18 -08:00
David Schmenk
2fe4b9ed52 Simpler DINTERP entry 2019-11-28 13:28:04 -08:00
David Schmenk
50f2ac669c Simpler DINTERP entry 2019-11-28 13:27:11 -08:00
David Schmenk
acf2aaacfe Simpler INTERP entry 2019-11-28 13:23:53 -08:00
David Schmenk
27eca20a04 Simpler DINTERP entry 2019-11-28 13:22:06 -08:00
David Schmenk
02b3b88862 Simpler INTERP entry 2019-11-28 13:21:23 -08:00
David Schmenk
cfe2fc4a98 Simpler INTERP entry 2019-11-28 13:20:43 -08:00
David Schmenk
49188358af Replace gets() with fgets() 2018-12-17 13:24:15 -08:00
David Schmenk
abb89438ef Merge pull request #52 from iflan/lex-cleanup
Remove duplicate 'res' token declarations
2018-11-25 11:13:05 -08:00
Ian Flanigan
9a5bf76b71 Remove duplicate token declaration from plasm.pla
Before this change, there were two declarations for the 'res' token.
Now there is only one.
2018-11-25 17:46:26 +01:00
Ian Flanigan
a8629a4f9a Remove duplicate token declaration from lex.c
Before this change, there were two declarations for the 'res' token.
Now there is only one.
2018-11-25 17:04:21 +01:00
David Schmenk
522703b278 Merge pull request #51 from iflan/addressing
Prefer pointer types in prefix operator parsing
2018-11-18 07:53:08 -08:00
Ian Flanigan
ce0b92bf8c Prefer pointer types in prefix operator parsing
This fixes issue #49 in the simplest way. Before, if the
dereferenced variable was a byte type, the result of the word
pointer dereference operator, `*`, would be a byte type. This
caused `*@a` to return a byte if `a` was a byte type. Now the
pointer type is used instead, causing `*@a` to return a word.

Prefix operator parsing allows some nonsensical constructions,
like `@*x`, but these were already possible before.

Before the output from:
```
include "inc/cmdsys.plh"

byte a
byte b
word x

a = 5
b = 6
x = $55FF
puti(*@a) // 5
putln()
puti(*(@a)) // 1541
putln()
puti(@*a) // 5
putln()
puti(^@x) // 255
putln()
puti(^(@x)) // 255
putln()
puti(@^x) // 255
putln()
done
```
was:
```
5
1541
5
255
255
255
```
now it is:
```
1541
1541
1541
255
255
255
```
2018-11-18 12:15:14 +00:00
David Schmenk
4b03b371b6 Merge pull request #50 from iflan/master
Implement puth in plvm
2018-11-16 16:49:37 -08:00
Ian Flanigan
76d010392a Implement puth in plvm
This change adds a simple implementation of puth() that is just
printf("%04X", i). This corresponds with the native implementations
for both Apple and C64.
2018-11-14 20:25:12 +00:00
David Schmenk
7a5578277f Fix over optimization of immediate opcodes 2018-10-01 16:24:01 -07:00
David Schmenk
3f23acf49c Clean up when/is evaluation 2018-09-26 15:51:35 -07:00
David Schmenk
2d8f2b9b22 Fix JIT16 SEC bug 2018-07-26 16:21:49 -07:00
David Schmenk
34c8a2efa3 Fix Uthernet2 MAC address (doesn't like non-zero MSB) 2018-07-26 11:53:38 -07:00
David Schmenk
fe6742d33e Set retry count back to 4 with longer delay - add debug print to uthernet2 2018-07-22 19:25:28 -07:00
David Schmenk
c789c3249e cleanup formatting 2018-07-21 18:55:25 -07:00
David Schmenk
b5098afbce Merge branch 'master' of https://github.com/dschmenk/PLASMA 2018-07-21 15:57:49 -07:00
David Schmenk
1527eaac24 increse DHCP timeout and add consts for 16 bit JIT ZP values 2018-07-21 15:56:49 -07:00
David Schmenk
0b2caa6931 Clean up directory structure 2018-07-14 08:57:00 -07:00
David Schmenk
5ca23ee898 Add 800K disk image of PLASMA install 2018-07-13 09:49:22 -07:00
David Schmenk
0185e4e5f5 Add new benchmark 2018-07-03 12:03:22 -07:00
David Schmenk
4039c6a3ad Set theme jekyll-theme-hacker 2018-05-28 11:44:18 -07:00
David Schmenk
72533c9ad9 Refix ProDOS clock input buffer 2018-05-27 20:12:26 -07:00
David Schmenk
22f22a382b Fix comments for FETCHOP 2018-05-27 08:13:26 -07:00
David Schmenk
6f8d5810d5 Forgot to bring in fix for ProDOS clock from 1.x 2018-05-26 17:42:06 -07:00
David Schmenk
67829d96cd Make sure prefix is set for AUTORUN 2018-05-26 08:31:05 -07:00
David Schmenk
6320ff0d65 Merge pull request #47 from ZornsLemma/jit-zp-constants-2
Use constants for zero page addresses in JIT
2018-05-16 20:48:09 -07:00
Steven Flintham
872d3d40f9 Use constants for zero page addresses in JIT 2018-05-16 21:31:37 +01:00
Steven Flintham
f59401f767 Use constants for zero page addresses in JIT 2018-05-16 21:28:36 +01:00
David Schmenk
7b2d5df99d Let fileio get JITted again 2018-05-13 06:18:06 -07:00
David Schmenk
52baa5c016 Update README.md 2018-05-08 07:10:13 -07:00
David Schmenk
e6c81e8c8d Fix unhandled IRQ on IIGS 2018-05-07 10:22:28 -07:00
ZornsLemma
660334fd84 Merge pull request #13 from dschmenk/master
Merge latest upstream changes
2018-05-04 23:02:30 +01:00
David Schmenk
92300ab18a update images 2018-05-02 18:31:48 -07:00
David Schmenk
4628eacb78 Update test to use VLB INT 2018-05-02 18:28:39 -07:00
David Schmenk
b34eed7de0 Stop continuous events when mouse button pressed 2018-05-02 13:27:08 -07:00
David Schmenk
fcfb971df3 Generate mouse event when button status changes 2018-05-02 13:13:58 -07:00
David Schmenk
09246e0e40 Update images 2018-05-01 07:36:11 -07:00
David Schmenk
ac021d2120 Merge branch 'master' of https://github.com/dschmenk/PLASMA 2018-05-01 07:33:55 -07:00
David Schmenk
cdc51a5ba8 Rework disk images 2018-05-01 07:33:33 -07:00
David Schmenk
c04c57487e Update Version 1.2.md 2018-04-29 19:24:01 -07:00
David Schmenk
a3223e8eac Merge branch 'master' of https://github.com/dschmenk/PLASMA 2018-04-29 19:21:31 -07:00
David Schmenk
bd3d3dbb6f Update version 2018-04-29 19:21:08 -07:00
David Schmenk
7d076e809f Update README.md 2018-04-29 19:20:13 -07:00
David Schmenk
20756214e2 Update portable VM to current VM ops 2018-04-29 16:52:05 -07:00
David Schmenk
d7e0873c10 Change text file EOL strategy 2018-04-29 14:47:44 -07:00
David Schmenk
1ced9b1a1a fix paths and execute bits for batchfiles 2018-04-29 08:07:35 -07:00
David Schmenk
b1143a2b7e Fix writing xlated data to disk 2018-04-29 07:19:48 -07:00
David Schmenk
2f5bb106bd Break out TFTP copies 2018-04-29 07:15:56 -07:00
David Schmenk
d539ff5b49 Add more files to tftp release batch file 2018-04-28 19:44:43 -07:00
David Schmenk
3d44c8533b Functional mouse API 2018-04-28 18:43:57 -07:00
David Schmenk
78a068e6d2 fix addres of int counters 2018-04-28 17:11:12 -07:00
David Schmenk
3db676c5dd Mouse API test 2018-04-28 13:34:05 -07:00
David Schmenk
67d0762272 Prepare for event manager 2018-04-28 08:00:10 -07:00
David Schmenk
d5f812d878 check for mouse/VBL events 2018-04-28 07:15:56 -07:00
David Schmenk
0f2a76dd55 Fix infunc for asm defs 2018-04-27 19:47:23 -07:00
David Schmenk
d52bf07344 Clen mouse init up 2018-04-27 19:36:01 -07:00
David Schmenk
3eb62ead0d Clean mouse init up 2018-04-27 19:35:26 -07:00
Dave Schmenk
1783aaef7a Fix resetmemfiles, use heap for catalog/volumes, and free CMD init code 2018-04-27 13:06:49 -07:00
David Schmenk
5ab6d915b3 track down mouse int corrption 2018-04-26 20:00:15 -07:00
David Schmenk
d0d328227a Mouse updates 2018-04-25 21:28:05 -07:00
David Schmenk
6ec3ce3b91 Import VM02 mouse driver 2018-04-25 11:25:41 -07:00
Dave Schmenk
b576ea8b85 update images 2018-04-24 20:42:07 -07:00
David Schmenk
1299cbc48b Fix UTHERNET autodetect and code cleanup 2018-04-24 18:56:35 -07:00
David Schmenk
d3a19cccbf Remove xheap from 64K cmdsys. Rework init message 2018-04-24 10:26:48 -07:00
David Schmenk
e6fc45a798 Network error messages and code cleanp 2018-04-23 13:29:54 -07:00
David Schmenk
ea542905b7 Better Uthernet card detection 2018-04-23 12:02:58 -07:00
David Schmenk
fb1f08bcc9 Fix UDP header len for UTHERNET 2018-04-22 14:26:12 -07:00
David Schmenk
8c0e66daf8 Update image 2018-04-21 22:31:59 -07:00
David Schmenk
be9465cd02 Try different fixes 2018-04-21 19:05:37 -07:00
David Schmenk
881c017ac7 update images 2018-04-21 17:54:29 -07:00
David Schmenk
a9607e7476 update images 2018-04-21 17:37:27 -07:00
David Schmenk
4db8271a25 TFTP server and fix FOR/NEXT in module init bug 2018-04-21 16:35:31 -07:00
Dave Schmenk
0a1f497d6c Smaller startup message 2018-04-20 10:05:53 -07:00
Dave Schmenk
ddd5e28fd4 Update startup message 2018-04-20 09:42:01 -07:00
David Schmenk
8d7ed176c5 update images 2018-04-19 16:35:32 -07:00
David Schmenk
912a4526fe LZ4 unpack library and sample lz4cat 2018-04-19 13:41:14 -07:00
David Schmenk
6cf47da936 LZ4 decompressor 2018-04-19 06:59:39 -07:00
David Schmenk
430b70f931 Update memmgr library 2018-04-17 16:15:50 -07:00
David Schmenk
d0eb8a5897 update images with FOR/NEXT changes 2018-04-17 11:11:11 -07:00
David Schmenk
c1d849946f BIG change so FOR/NEXT exits with proper terminal value in variable 2018-04-17 10:39:05 -07:00
David Schmenk
1c63d4832e Update C64 VM 2018-04-16 11:10:51 -07:00
David Schmenk
bef66ae6c0 Fix buggered 65802 JIT optimization 2018-04-15 15:28:20 -07:00
David Schmenk
f32349b849 Buggered that optimization up 2018-04-15 15:25:00 -07:00
David Schmenk
8d119d3d8c Check for H/W/ access on BYTE loads 2018-04-15 14:47:14 -07:00
David Schmenk
bbac311c4f John Brooks Optiizations 2018-04-15 14:34:45 -07:00
David Schmenk
174ff0b7a2 update image` 2018-04-14 13:32:38 -07:00
David Schmenk
45b3560040 Fix compiler allocations for 64K machine 2018-04-14 12:48:12 -07:00
David Schmenk
ed280b3584 Update README.md 2018-04-13 21:47:12 -07:00
David Schmenk
c88d5cabcb update images 2018-04-13 16:14:40 -07:00
David Schmenk
97e2c48098 Fix 64K VM 2018-04-13 16:13:12 -07:00
David Schmenk
0925945d2e Fix VM filename in VMLOAD 2018-04-13 13:34:10 -07:00
David Schmenk
b5c30d524e update images 2018-04-13 12:21:04 -07:00
David Schmenk
3a6c77a4eb Simplify VM configurations and auto-load alternative VMs 2018-04-13 12:09:14 -07:00
David Schmenk
795d56c2a7 Fix SEL JIT16 compiler 2018-04-12 17:15:16 -07:00
David Schmenk
2bb9f73448 Fix INCBRLE and JIT cleanup 2018-04-12 14:20:02 -07:00
David Schmenk
23aaef442d Cleanup 2018-04-11 22:16:30 -07:00
David Schmenk
7f46144911 Working 65802 JIT compiler 2018-04-11 14:48:21 -07:00
David Schmenk
3e4d0bcedf Build jit16 for real 2018-04-11 10:06:57 -07:00
Dave Schmenk
177c951a2d Update images 2018-04-11 07:49:19 -07:00
David Schmenk
11ee2feed5 JIT16 WIP 2018-04-10 21:02:48 -07:00
David Schmenk
07733cc5a6 JIT 65802 WIP 2018-04-10 18:11:35 -07:00
David Schmenk
ce27807cd9 update image 2018-04-09 10:17:29 -07:00
David Schmenk
7fae43e216 Update image 2018-04-09 09:16:02 -07:00
David Schmenk
758f6eb499 Merge branch 'master' of https://github.com/dschmenk/PLASMA 2018-04-09 09:14:05 -07:00
David Schmenk
daf25e990a Running out of disk image space 2018-04-09 09:13:17 -07:00
David Schmenk
f884034786 Update image with SOS.DRIVERS for Mame Apple /// 2018-04-09 08:51:00 -07:00
David Schmenk
8ee09363f0 New Acronym 2018-04-09 08:15:15 -07:00
David Schmenk
f097361b83 Update Version 1.1.md 2018-04-09 07:16:07 -07:00
David Schmenk
b33856ee28 Get 65802 to sort-of run JIT 2018-04-08 14:59:45 -07:00
ZornsLemma
87d43d74ce Merge pull request #12 from dschmenk/master
Merge latest upstream
2018-04-08 15:18:23 +01:00
David Schmenk
61eaeef9c1 Disable JITC on certain modules. 2018-04-07 10:48:11 -07:00
David Schmenk
2241c0c65f Somehow this got lost in the merge 2018-04-07 09:33:22 -07:00
David Schmenk
bc7e38ee17 Merge branch 'devel' 2018-04-07 09:27:21 -07:00
David Schmenk
dad0f4b4d5 Add NO-JITC flag to module SYSFLAGS 2018-04-06 17:53:51 -07:00
David Schmenk
fd641bef8f JIT specific module loading 2018-04-06 14:22:39 -07:00
David Schmenk
11dc4abcda 65802 JITC placeholders 2018-04-06 12:45:34 -07:00
David Schmenk
82a4b57c43 65802 requires 128K and JITC 2018-04-06 12:42:48 -07:00
David Schmenk
2a015d98cf Update images 2018-04-06 09:13:55 -07:00
David Schmenk
625ce2704e Sync cleanjit with jitcore 2018-04-06 08:25:42 -07:00
David Schmenk
f35f0b3bba Fix OBO in branch calc loop and free up bytes to re-enable LLA opt 2018-04-06 08:05:23 -07:00
David Schmenk
e3606f3f64 Fix byte variable used in negative FOR/NEXT 2018-04-05 11:51:53 -07:00
David Schmenk
558290100c Clear MSB for DLB/DAB 2018-04-05 11:20:43 -07:00
David Schmenk
5285f99a03 Merge branch 'devel' of https://github.com/dschmenk/PLASMA into devel 2018-04-04 20:20:16 -07:00
David Schmenk
6c6dca3348 re-arrange a few things 2018-04-04 20:19:35 -07:00
David Schmenk
87a0b24d7a image update 2018-04-04 17:44:52 -07:00
David Schmenk
8b649b0d48 fix opcode skip for CS in branch detection 2018-04-04 13:25:13 -07:00
David Schmenk
9a82e3b5fb Looking for one more JITC bug 2018-04-03 13:56:55 -07:00
David Schmenk
3e0d81d09d Put buffer at beginning of SBANK 2018-04-03 10:10:41 -07:00
Dave Schmenk
763cbd6986 Full 4K JIT codebuffer 2018-04-02 21:46:53 -07:00
David Schmenk
347aa5329d Leave buffer for maxcode and assembly defcpy 2018-04-02 15:41:41 -07:00
David Schmenk
9e4f9936af Cleanup 2018-04-02 13:51:04 -07:00
David Schmenk
d0215eb7e1 Allocate proper size for defentries 2018-04-02 12:36:44 -07:00
David Schmenk
58eb615176 Remove JITC puts from JIT module 2018-04-02 10:17:33 -07:00
David Schmenk
e5e43f58b7 Save/Restore JIT code ptr 2018-04-02 10:02:17 -07:00
David Schmenk
77ca9b2813 Re-org some JIT <-> CMDSYS <-> VM connections 2018-04-02 09:17:18 -07:00
David Schmenk
d4f15e3a90 Apple /// JITC 2018-04-02 08:47:16 -07:00
David Schmenk
574911e389 Apple /// JIT WIP 2018-04-01 18:53:56 -07:00
David Schmenk
46b24b077a Break out cor JIT for all platforms 2018-04-01 15:29:57 -07:00
David Schmenk
46b9f073d5 New JIT defaults 2018-03-31 17:15:18 -07:00
David Schmenk
630ccd88fa Improve LLA opts a little 2018-03-31 15:13:13 -07:00
David Schmenk
53a992debb Update images 2018-03-30 13:23:52 -07:00
David Schmenk
51ba2df618 Move JIT compiler to top of AUX memory 2018-03-30 13:12:39 -07:00
David Schmenk
cccfdbb9a7 Combine similar opcodes to shring module size to ~8K (keep clean version) 2018-03-30 09:52:35 -07:00
David Schmenk
f11a1470f0 Allocate seq buffer on heap and keep ints disabled durin aux memory move 2018-03-29 21:44:40 -07:00
David Schmenk
43a03d2882 Make sure all buffers on heap are allocated 2018-03-29 21:07:08 -07:00
David Schmenk
3fe85c5835 Make sure to always allocate data on heap - it can get overwritten by JIT 2018-03-29 20:00:06 -07:00
David Schmenk
f7b1d6c3fb Tracking Y register WIP 2018-03-29 17:14:27 -07:00
David Schmenk
b5885dfe8f Better tracking of Y register WIP 2018-03-29 12:19:49 -07:00
David Schmenk
148031d192 Make SIEVE JITable 2018-03-29 07:58:31 -07:00
David Schmenk
3968f82625 Lose the JIT warmup count 2018-03-28 17:02:26 -07:00
David Schmenk
208be4da1f Update images 2018-03-28 16:30:18 -07:00
David Schmenk
b72e592c9a Fix SEL tests 2018-03-28 11:51:04 -07:00
Dave Schmenk
5e049ebe8e Fix CS destination jump 2018-03-27 22:13:58 -07:00
David Schmenk
7cd9c00706 Fix SELect default branch 2018-03-27 20:00:49 -07:00
David Schmenk
369e9731f4 Source cleanup 2018-03-27 19:21:27 -07:00
David Schmenk
1e05ab789e Finished updating ops $B0-$BE 2018-03-27 14:02:09 -07:00
David Schmenk
169d347754 Make sure A_IS_TOSL is cleared at opt fence 2018-03-27 10:12:13 -07:00
David Schmenk
818a2b14ea Update ops $A0-$AE 2018-03-26 16:51:09 -07:00
David Schmenk
15c779d63b Update ops $90-$9E 2018-03-26 11:04:45 -07:00
David Schmenk
4717e01862 Fix SUB typo 2018-03-26 06:58:44 -07:00
David Schmenk
9922127a41 Updates ops $80-$8E 2018-03-25 23:03:29 -07:00
David Schmenk
26a03d8e0b Update ops $70-$7E 2018-03-25 20:20:19 -07:00
David Schmenk
8f5d4647bf Update ops $60-$6E 2018-03-25 17:31:07 -07:00
David Schmenk
08e41bf472 Update ops $50-$5E 2018-03-25 13:53:53 -07:00
David Schmenk
23779176d2 Update ops $40-$4E 2018-03-24 21:37:52 -07:00
David Schmenk
2c9373c962 WIP opcodes $40-$4E 2018-03-24 17:17:06 -07:00
David Schmenk
6cfb957df4 Rework ops $30-$3E 2018-03-24 17:04:21 -07:00
David Schmenk
1bf3c7043f Fix LLA 2018-03-24 16:37:47 -07:00
David Schmenk
8adc03d640 Rework ops $20-$2E 2018-03-24 15:47:05 -07:00
David Schmenk
27a2d8d0b7 Start more efficient coding for writing native code to buffer 2018-03-24 10:02:14 -07:00
David Schmenk
efd1ff58e3 Fix ISLE 2018-03-23 17:13:42 -07:00
David Schmenk
8b1ca4bf1e Fix DLW TOSL_DIRTY 2018-03-23 16:05:39 -07:00
David Schmenk
3c72bb9df3 Better TOSL cache checks 2018-03-23 12:31:17 -07:00
David Schmenk
36c2506a24 Move max code buffer down a smidge 2018-03-23 11:33:01 -07:00
David Schmenk
72a7996871 Fix optimization fences and BROR/BRAND/DUP/DLW 2018-03-23 11:26:25 -07:00
Dave Schmenk
56f6d783e2 JIT optimizations fixes 2018-03-22 21:53:49 -07:00
David Schmenk
9be1bd5eb8 Change sense of test to take advantage of Y=0 2018-03-22 16:50:18 -07:00
David Schmenk
a7ecdc7edc Save a few bytes so we can test JIT 2018-03-22 16:38:05 -07:00
David Schmenk
7b201b4392 Optimizing JIT WIP 2018-03-22 16:11:06 -07:00
David Schmenk
cdb0dac92f Fix SEL and SUBI 2018-03-22 12:23:25 -07:00
Dave Schmenk
81574a8a62 JIT tuning parameters 2018-03-21 22:31:06 -07:00
David Schmenk
8c18a28e49 JIT WIP 2018-03-21 20:54:16 -07:00
David Schmenk
71d17a99e4 Fix immediate value loads 2018-03-21 18:24:15 -07:00
David Schmenk
cb7f86a911 Order DFD by address 2018-03-21 16:23:32 -07:00
David Schmenk
fa71ec3948 Fix ENTER/LEAVE 2018-03-21 14:01:17 -07:00
David Schmenk
e16f45f59b First pass at JIT 2018-03-21 13:00:23 -07:00
David Schmenk
3afd11fd03 New code translations 2018-03-20 21:01:59 -07:00
David Schmenk
3fc34fe028 Parsing bytecode to compile 2018-03-20 16:54:44 -07:00
David Schmenk
9701c00d1e Merge branch 'devel' of https://github.com/dschmenk/PLASMA into devel 2018-03-20 14:19:42 -07:00
David Schmenk
4dcc033ed0 Invokable JIT compiler version 2018-03-20 14:19:17 -07:00
David Schmenk
d392cbca9c Slight improvement to return address calc for ICAL/CALL 2018-03-19 15:21:15 -07:00
David Schmenk
4577983799 Update images 2018-03-18 16:26:09 -07:00
David Schmenk
b3c05c9797 Case-ify more of the editor if/ifelse/else 2018-03-18 15:49:55 -07:00
David Schmenk
571e8d8eb0 All out speed CFFB 2018-03-18 14:31:36 -07:00
David Schmenk
1a8f3048b5 Verify REL module tyoe before loading 2018-03-18 13:47:14 -07:00
David Schmenk
5a0d9e5751 VerifyREL module filetype before trying to load 2018-03-18 13:38:13 -07:00
David Schmenk
309f5d45b0 Shuffle routines around based on available INTERP mem 2018-03-18 13:23:39 -07:00
David Schmenk
6d2336a343 Update image 2018-03-17 19:14:42 -07:00
David Schmenk
caebedc1e5 Working Apple 3 again 2018-03-17 19:07:36 -07:00
David Schmenk
773e0d0af0 update images 2018-03-17 17:14:21 -07:00
David Schmenk
f7cf0be03e more cmdsys rearrangement 2018-03-17 16:51:00 -07:00
David Schmenk
0d1b2d5db9 Update images 2018-03-17 15:58:41 -07:00
David Schmenk
a9237f58cc Sync cmd exported sysroutines 2018-03-17 15:52:15 -07:00
David Schmenk
3356cdd036 Break out cmd into module 2018-03-17 15:06:31 -07:00
David Schmenk
95e15e4b86 Better CASE END 2018-03-17 09:46:13 -07:00
David Schmenk
3975e54c29 Update image 2018-03-17 08:48:51 -07:00
David Schmenk
d379cefe2a 6502 caseblock early exit test 2018-03-17 08:44:02 -07:00
Dave Schmenk
c02bcd413d BYTE size variables 2018-03-16 22:42:57 -07:00
David Schmenk
463db3c170 Fix 65802 caseblock early exit 2018-03-16 20:44:09 -07:00
David Schmenk
68479c1606 Fix Y adjust on cse early exit 2018-03-16 19:08:13 -07:00
David Schmenk
5c9bc34844 Fix check for duplicate CASE and updates images 2018-03-16 16:57:42 -07:00
David Schmenk
423ca66fc0 No need for SANDBOX anymore. Tests for codeblock on 65802 2018-03-16 16:36:39 -07:00
David Schmenk
010750efed Early exit caseblock if value less than ordered list 2018-03-16 15:14:58 -07:00
David Schmenk
ec0fdde747 Order caseblock values in ascending order 2018-03-16 14:52:27 -07:00
ZornsLemma
55711af895 Merge pull request #11 from dschmenk/master
Merge latest upstream changes
2018-03-16 21:36:05 +00:00
David Schmenk
bbbe2d0d38 opcode statistics 2018-03-16 09:57:01 -07:00
David Schmenk
4af5c37dea Update images 2018-03-16 07:41:17 -07:00
David Schmenk
d165509293 Allow CONST/PREDEF before IMPORT 2018-03-16 07:39:42 -07:00
David Schmenk
d485654d0e Update images 2018-03-16 07:06:17 -07:00
David Schmenk
f9a007398f CASE checking and limit to 64 cases on self-hosted compiler 2018-03-16 07:00:22 -07:00
Dave Schmenk
b987b927d3 Merge branch 'devel' of https://github.com/dschmenk/PLASMA into devel 2018-03-15 21:54:32 -07:00
Dave Schmenk
5fc2807ace BREQ/BRNE optimizations 2018-03-15 21:54:11 -07:00
David Schmenk
7ffe5a6767 Update images 2018-03-15 11:24:35 -07:00
David Schmenk
b8714745dd Add BRGT/BRLT FOR/NEXT optimization 2018-03-15 11:16:58 -07:00
David Schmenk
c07bc8172c Shrink a few bytes to fit 2018-03-15 07:59:16 -07:00
David Schmenk
3d84a2192c BREQ and BRNE ops 2018-03-14 21:34:55 -07:00
David Schmenk
934b04ae56 Update images 2018-03-14 19:19:01 -07:00
David Schmenk
53c832da58 Fix ADDx ops 2018-03-14 18:43:21 -07:00
David Schmenk
b145f82a9d Faster ADDx ops 2018-03-14 17:22:12 -07:00
David Schmenk
852b5b7268 Update images 2018-03-14 12:30:51 -07:00
David Schmenk
0045d0eabb Remove debug prints 2018-03-14 11:59:39 -07:00
David Schmenk
518b4e2680 local and absolute address ADDs 2018-03-14 11:56:16 -07:00
David Schmenk
c3f9ee0911 Save a few more bytes in the VM 2018-03-13 16:02:08 -07:00
Dave Schmenk
d515ab5969 Update images 2018-03-13 10:28:04 -07:00
Dave Schmenk
2da878889b Reduce makefile noise for OSX too 2018-03-13 10:23:01 -07:00
Dave Schmenk
19bacbc7ea Reduce noise doesn't work on OSX 2018-03-13 09:39:46 -07:00
Dave Schmenk
6f75211e7e Reduce makefile noise 2018-03-13 09:29:51 -07:00
Dave Schmenk
5d531f53b1 Fix sign of mod and divmod 2018-03-13 09:19:18 -07:00
David Schmenk
35539e8f6e Update test case, portable VM WIP 2018-03-13 08:16:01 -07:00
David Schmenk
f5a94313f2 Add assembly helper for lexical scanner ID/Keyword match 2018-03-12 15:13:35 -07:00
David Schmenk
214f9c163d Update images 2018-03-10 18:55:24 -08:00
David Schmenk
4f11cad955 Update XBYTE in SELect 2018-03-10 15:45:01 -08:00
David Schmenk
20790d2dbb Make sure sequnce opcode is invalidated for gen_ctag 2018-03-10 15:38:57 -08:00
David Schmenk
023030831c Sync all VMs and update images 2018-03-10 08:30:39 -08:00
Dave Schmenk
9dbb1671a4 Update images 2018-03-09 20:40:50 -08:00
David Schmenk
ce29a7c361 65802 bug fixes 2018-03-09 19:50:31 -08:00
David Schmenk
b0a9cb3e0e Update images 2018-03-07 20:05:17 -08:00
Dave Schmenk
3d9c54adbf 65802 VM updates 2018-03-06 22:24:42 -08:00
David Schmenk
25599c00c8 Apple 3 VM updates 2018-03-06 19:20:59 -08:00
Dave Schmenk
2e952bfde3 New FOR/NEXT changes for terminal variable value 2018-03-05 22:14:49 -08:00
David Schmenk
a8553cfdb7 re-arrange some ops 2018-03-05 15:40:43 -08:00
David Schmenk
f3ef1b4820 Enable 65C02 ConstantNybble 2018-03-05 12:19:47 -08:00
David Schmenk
334bf1ec4d Nybble constants encoded in opcode 2018-03-05 11:38:16 -08:00
David Schmenk
eff01c5f12 Short circuit AND/OR 2018-03-05 10:55:19 -08:00
David Schmenk
6de120ec89 New WHEN/IS for hosted compiler 2018-03-05 08:58:21 -08:00
David Schmenk
3ee19e86f6 SWITCH/CASE table optimization 2018-03-04 21:36:23 -08:00
David Schmenk
e1090c012c Better WHILE/LOOP 2018-03-04 15:00:40 -08:00
David Schmenk
18301b6ce9 Adjust to new for/next 2018-03-04 14:21:40 -08:00
David Schmenk
5b41fd07c4 More work on for/next 2018-03-04 13:15:02 -08:00
Dave Schmenk
2b2e464c9b More immidiate ops, add/sub next branches 2018-03-04 10:18:31 -08:00
Dave Schmenk
793b1760a0 Constant op codes 2018-03-03 18:55:39 -08:00
Dave Schmenk
40c3dcd197 Better FOR/NEXT ops 2018-03-02 21:43:09 -08:00
112 changed files with 24936 additions and 5886 deletions

Binary file not shown.

Binary file not shown.

113
README.md
View File

@@ -1,12 +1,17 @@
# 3/13/2018 PLASMA 1.1 Available!
[Download and read the Release Notes](https://github.com/dschmenk/PLASMA/blob/master/doc/Version%201.1.md)
# 12/28/2019 PLASMA 2.0 Developer Preview 2 Available!
[Download and read the Release Notes](https://github.com/dschmenk/PLASMA/blob/master/doc/Version%202.0.md)
[Change List](https://github.com/dschmenk/PLASMA/blob/master/doc/Version%202.0.md#changes-in-plasma-for-20-dp-2)
# 4/29/2018 PLASMA 1.2 Available!
[Download and read the Release Notes](https://github.com/dschmenk/PLASMA/blob/master/doc/Version%201.2.md)
# The PLASMA Programming Language
![Luc Viatour](https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Plasma-lamp_2.jpg/1200px-Plasma-lamp_2.jpg)
image credit: Luc Viatour / www.Lucnix.be
PLASMA: **P**roto **L**anguage **A**s**S**e**M**bler for **A**pple
PLASMA: **P**roto **L**anguage **A**s**S**e**M**bler for **A**ll
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.
@@ -94,7 +99,7 @@ Different projects have led to the architecture of PLASMA, most notably Apple Pa
- [Call Stack](#call-stack)
- [Local Frame Stack](#local-frame-stack)
- [Local String Pool](#local-string-pool)
- [The Bytecodes](#the-bytecodes)
- [The Bytecodes](https://github.com/dschmenk/PLASMA/wiki/PLASMA-Byte-Codes)
- [Apple 1 PLASMA](#apple-1-plasma)
- [Apple II PLASMA](#apple-ii-plasma)
- [Apple /// PLASMA](#apple--plasma)
@@ -106,7 +111,7 @@ Different projects have led to the architecture of PLASMA, most notably Apple Pa
## 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 [Linux Subsystem for Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) or 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. Linux users should make sure the development packages are installed.
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:
@@ -518,7 +523,7 @@ else
fin
```
The `when`/`is`/`otherwise`/`wend` statement is similar to the `if`/`elsif`/`else`/`fin` construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. Only the `when` value is compared against a list of expressions. The expressions do not need to be constants, they can be any valid expression. The list of expressions is evaluated in order, so for efficiency sake, place the most common cases earlier in the list. Just as in C programs, a `break` statement is required to keep one clause from falling through to the next. Falling through from one clause to the next can have its uses, so this behavior has been added to PLASMA.
The `when`/`is`/`otherwise`/`wend` statement is similar to the `if`/`elsif`/`else`/`fin` construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. Only the `when` value is compared against a list of constant. Just as in C programs, a `break` statement is required to keep one clause from falling through to the next. Falling through from one clause to the next can have its uses, so this behavior has been added to PLASMA.
```
when keypressed
@@ -1139,7 +1144,7 @@ The common `if` test can have optional `elsif` and/or `else` clauses. Any expres
#### WHEN/IS/[OTHERWISE]/WEND
The complex test case is handled with `when`. Basically an `if`, `elsif`, `else` list of comparisons, it is generally more efficient. The `is` value can be any expression. It is evaluated and tested for equality to the `when` value.
The complex test case is handled with `when`. Basically an `if`, `elsif`, `else` list of comparisons, it is generally more efficient. The `is` value must be a constant.
```
when key
@@ -1162,26 +1167,6 @@ when key
wend
```
With a little "Yoda-Speak", some fairly complex test can be made:
```
const FALSE = 0
const TRUE = NOT FALSE
byte a
when TRUE
is (a <= 10)
// 10 or less
break
is (a > 10) AND (a < 20)
// between 10 and 20
break
is (a >= 20)
// 20 or greater
wend
```
A `when` clause can fall-through to the following clause, just like C `switch` statements by leaving out the `break`.
#### FOR \<TO,DOWNTO\> [STEP]/NEXT
@@ -1313,80 +1298,6 @@ One of the biggest problems to overcome with the 6502 is its very small hardware
Any function that uses in-line strings may have those strings copied to the local string pool for usage. This allows string literals to exist in the same memory as the bytecode and only copied to main memory when used. The string pool is deallocated along with the local frame stack when the function exits.
### The Opcodes
The compact code representation comes through the use of opcodes closely matched to the PLASMA compiler. They are:
| OPCODE | Name | Description
|:------:|:------:|-----------------------------------
| $00 | ZERO | push zero on the stack
| $02 | ADD | add top two values, leave result on top
| $04 | SUB | subtract next from top from top, leave result on top
| $06 | MUL | multiply two topmost stack values, leave result on top
| $08 | DIV | divide next from top by top, leave result on top
| $0A | MOD | divide next from top by top, leave remainder on top
| $0C | INCR | increment top of stack
| $0E | DECR | decrement top of stack
| $10 | NEG | negate top of stack
| $12 | COMP | compliment top of stack
| $14 | AND | bit wise AND top two values, leave result on top
| $16 | IOR | bit wise inclusive OR top two values, leave result on top
| $18 | XOR | bit wise exclusive OR top two values, leave result on top
| $1A | SHL | shift left next from top by top, leave result on top
| $1C | SHR | shift right next from top by top, leave result on top
| $02 | IDXB | add top of stack to next from top, leave result on top (ADD)
| $1E | IDXW | add 2X top of stack to next from top, leave result on top
| $20 | NOT | logical NOT of top of stack
| $22 | LOR | logical OR top two values, leave result on top
| $24 | LAND | logical AND top two values, leave result on top
| $26 | LA | load address
| $28 | LLA | load local address from frame offset
| $2A | CB | constant byte
| $2C | CW | constant word
| $2E | CS | constant string
| $30 | DROP | drop top stack value
| $32 | DUP | duplicate top stack value
| $34 | NOP |
| $36 | DIVMOD | divide next from to by top, leave result and remainder on stack
| $38 | BRGT | branch next from top greater than top
| $3A | BRLT | branch next from top less than top
| $3C | BREQ | branch next from top equal to top
| $3E | BRNE | branch next from top not equal to top
| $40 | ISEQ | if next from top is equal to top, set top true
| $42 | ISNE | if next from top is not equal to top, set top true
| $44 | ISGT | if next from top is greater than top, set top true
| $46 | ISLT | if next from top is less than top, set top true
| $48 | ISGE | if next from top is greater than or equal to top, set top true
| $4A | ISLE | if next from top is less than or equal to top, set top true
| $4C | BRFLS | branch if top of stack is zero
| $4E | BRTRU | branch if top of stack is non-zero
| $50 | BRNCH | branch to address
| $52 | IBRNCH | branch to address on stack top
| $54 | CALL | sub routine call with stack parameters
| $56 | ICAL | sub routine call to address on stack top with stack parameters
| $58 | ENTER | allocate frame size and copy stack parameters to local frame
| $5A | LEAVE | deallocate frame and return from sub routine call
| $5C | RET | return from sub routine call
| $5E | CFFB | constant with $FF MSB
| $60 | LB | load byte from top of stack address
| $62 | LW | load word from top of stack address
| $64 | LLB | load byte from frame offset
| $66 | LLW | load word from frame offset
| $68 | LAB | load byte from absolute address
| $6A | LAW | load word from absolute address
| $6C | DLB | duplicate top of stack into local byte at frame offset
| $6E | DLW | duplicate top of stack into local word at frame offset
| $70 | SB | store next from top of stack byte into top address
| $72 | SW | store next from top of stack word into top address
| $74 | SLB | store top of stack into local byte at frame offset
| $76 | SLW | store top of stack into local word at frame offset
| $78 | SAB | store top of stack into byte at absolute address
| $7A | SAW | store top of stack into word at absolute address
| $7C | DAB | duplicate top of stack into byte at absolute address
| $7E | DAW | duplicate top of stack into word at absolute address
The opcodes were developed over time by starting with a very basic set of operations and slowly adding opcodes when the PLASMA compiler could improve code density or performance.
## Apple 1 PLASMA
Obviously the Apple 1 is a little more constrained than most machines PLASMA is targeting. But, with the required addition of the CFFA1 (http://dreher.net/?s=projects/CFforApple1&c=projects/CFforApple1/main.php), the Apple 1 gets 32K of RAM and a mass storage device. Enough to run PLASMA and load/execute modules.

Binary file not shown.

View File

@@ -2,8 +2,8 @@ WELCOME TO THE PLASMA EDITOR!
=============================
FIRST THINGS FIRST:
TO NAVIGATE, USE THE ARROW KEYS. ON THE
APPLE ][:
TO NAVIGATE, USE THE ARROW KEYS. ON
THE APPLE ][:
CTRL-K = UP
CTRL-J = DOWN.
@@ -18,22 +18,23 @@ TO JUMP AROUND THE TEXT FILE USE:
CTRL-Q = JUMP BEGINNING
CTRL-E = JUMP END
THE 'ESCAPE' KEY WILL PUT YOU IN COMMAND
MODE. FROM THERE YOU CAN EXIT BY
ENTERING 'Q' AND 'RETURN'. YOU CAN ALSO
RETURN TO THE EDITOR BY JUST PRESSING
'RETURN'.
THE 'ESCAPE' KEY WILL PUT YOU IN
COMMAND MODE. FROM THERE YOU CAN
EXIT BY ENTERING 'Q' AND 'RETURN'.
YOU CAN ALSO RETURN TO THE EDITOR BY
JUST PRESSING 'RETURN'.
-------
THE PLASMA EDITOR IS A SIMPLE TEXT
EDITOR FOR ENTERING AND MANIPULATING
TEXT AND SOURCE CODE FILES. THE EDITOR
ONLY SUPPORTS 40 COLUMN TEXT ALTHOUGH
LINES CAN BE UP TO 79 CHARACTERS LONG.
THE SCREEN WILL SCROLL HORIZONTALLY
AS THE CURSOR MOVES. THERE IS 16K OF
MEMORY FOR THE TEXT BUFFER.
TEXT AND SOURCE CODE FILES. THE
EDITOR ONLY SUPPORTS 40 COLUMN TEXT
ALTHOUGH LINES CAN BE UP TO 79
CHARACTERS LONG. THE SCREEN WILL
SCROLL HORIZONTALLY AS THE CURSOR
MOVES. THERE IS 16K OF MEMORY FOR
THE TEXT BUFFER.
IT HAS TWO MODES, COMMAND AND EDIT.
@@ -52,13 +53,17 @@ EDIT COMMANDS:
CTRL-Q = JUMP BEGIN
CTRL-E = JUMP END
CTRL-D = DELETE CHAR
CTRL-X = DELETE/CUT LINE
CTRL-V = COPY DELETED LINE
CTRL-B = BEGIN SELECTION
CTRL-C = COPY SELECTION INTO CLIPBOARD
CTRL-X = CUT SELECTION INTO CLIPBOARD
CTRL-V = PASTE CLIPBOARD
CTRL-O = OPEN NEW LINE
CTRL-F = OPEN A FOLLOWING NEW LINE
CTRL-T = JOIN LINES
CTRL-B = TOGGLE INSERT/OVERWRITE
CTRL-Y = TOGGLE INSERT/OVERWRITE
TAB/CTRL-I = INSERT SPACES TO NEXT TAB
= INDENT SELECTION IF INSERT MODE
= UNDENT SELECTION IF OVERWITE MODE
ESCAPE = SWITCH TO COMMAND MODE
DELETE = DELETE CHAR LEFT
@@ -78,7 +83,7 @@ EDIT COMMANDS:
APPLE ][, UPPER AND LOWER CASE
ENTRY WORKS AS EXPECTED.
CTRL-C = FORCE LOWER-CASE CHARS
ESC T C = FORCE LOWER-CASE CHARS
If you have a lower-case character
generator installed, you can force
@@ -93,11 +98,12 @@ EDIT COMMANDS:
The 'SOLID-APPLE' key will modify
theese keys:
SA-RETURN = OPEN LINE
SA-RETURN = OPEN FOLLOWING LINE
SA-LEFT ARROW = JUMP LEFT
SA-RIGHT ARROW = JUMP RIGHT
SA-UP ARROR = JUMP UP
SA-DOWN ARROW = JUMP DOWN
SA-TAB = DETAB
Apple /// FEATURES:
-------------------
@@ -106,11 +112,12 @@ EDIT COMMANDS:
these keys:
OA-\ = DELETE CHAR LEFT
OA-RETURN = OPEN LINE
OA-RETURN = OPEN FOLLOWING LINE
OA-LEFT ARROW = JUMP LEFT
OA-RIGHT ARROW = JUMP RIGHT
OA-UP ARROR = JUMP UP
OA-DOWN ARROW = JUMP DOWN
OA-TAB = DETAB
On the keypad, 'OPEN-APPLE' allows
the keys for navigation and misc:
@@ -124,9 +131,9 @@ EDIT COMMANDS:
OA-7 = JUMP BEGIN
OA-1 = JUMP END
OA-5 = DELETE CHAR
OA-- = DELETE/CUT LINE
OA-0 = COPY DELETED LINE
OA-ENTER = OPEN NEW LINE
OA-- = CUT SELECTION INTO CLIPBOARD
OA-0 = PASTE CLIPBOARD
OA-ENTER = OPEN FOLLOWING LINE
OA-. = TOGGLE INSERT/OVERWRITE
COMMAND MODE:
@@ -142,5 +149,9 @@ COMMAND MODE:
P <PREFIX> = SET PREFIX
H [SLOT] = HARDCOPY TO DEVICE IN SLOT (DEFAULT 1)
N = CLEAR TEXT IN MEMORY
T G = TOGGLE GUTTER VIEW
T C = TOGGLE LOWER-CASE SUPPORT (APPLE ][)
G <LINE> = GO TO LINE #
F [STRING] = FIND STRING
E = EDIT MODE
'RETURN' = EDIT MODE

View File

@@ -1,16 +1,16 @@
# PLASMA Version 1.1
# PLASMA Version 1.2
Welcome to PLASMA: the Grand Unifying Platform for the Apple 1, ][, and ///.
Download the four disk images (three if you don't plan to boot an Apple ///):
[PLASMA 1.1 System and ProDOS Boot](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-SYS1.PO?raw=true)
[PLASMA 1.2 System and ProDOS Boot](https://github.com/dschmenk/PLASMA/blob/ver-1/PLASMA-SYS1.PO?raw=true)
[PLASMA 1.1 Build Tools](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-BLD1.PO?raw=true)
[PLASMA 1.2 Build Tools](https://github.com/dschmenk/PLASMA/blob/ver-1/PLASMA-BLD1.PO?raw=true)
[PLASMA 1.1 Demos](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-DEM1.PO?raw=true)
[PLASMA 1.2 Demos](https://github.com/dschmenk/PLASMA/blob/ver-1/PLASMA-DEM1.PO?raw=true)
[PLASMA 1.1 Apple /// SOS Boot ](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-SOS1.PO?raw=true)
[PLASMA 1.2 Apple /// SOS Boot ](https://github.com/dschmenk/PLASMA/blob/ver-1/PLASMA-SOS1.PO?raw=true)
PLASMA can be run from floppies, System in Drive 1, and Build or Demos in Drive 2. Mass storage is the recommended installation that looks like (replacing HARDISK with your volume name of choice):
@@ -98,6 +98,16 @@ There is a [YouTube playlist](https://www.youtube.com/playlist?list=PLlPKgUMQbJ7
- The documentation is sparse and incomplete. Yep, could use your help...
# Changes in PLASMA for 1.2
1. Add TFTPD TFTP server
2. Fix Uthernet 1 driver
3. Add mouse module
4. Fix IRQ issues for interrupt driven mouse driver
# Changes in PLASMA for 1.1
1. All known bugs are fixed

236
doc/Version 2.0.md Normal file
View File

@@ -0,0 +1,236 @@
# PLASMA Version 2.0 Developer Preview 2
Welcome to PLASMA: the Grand Unifying Platform for the Apple 1, ][, and ///.
Download the four disk images (three if you don't plan to boot an Apple ///):
[PLASMA 2.0 DP 800K Full System](https://github.com/dschmenk/PLASMA/blob/master/images/apple/PLASMA2.2mg?raw=true)
[PLASMA 2.0 DP System and ProDOS Boot](https://github.com/dschmenk/PLASMA/blob/master/images/apple/PLASMA2-SYS.PO?raw=true)
[PLASMA 2.0 DP Build Tools](https://github.com/dschmenk/PLASMA/blob/master/images/apple/PLASMA2-BLD.PO?raw=true)
[PLASMA 2.0 DP Demos](https://github.com/dschmenk/PLASMA/blob/master/images/apple/PLASMA2-DEM.PO?raw=true)
[PLASMA 2.0 DP Apple /// SOS Boot and SANE floating point modules](https://github.com/dschmenk/PLASMA/blob/master/images/apple/PLASMA2-FPSOS.PO?raw=true)
PLASMA can be run from floppies, System in Drive 1, and Build or Demos in Drive 2. Mass storage is the recommended installation that looks like (replacing HARDISK with your volume name of choice):
System Files => /HARDISK/PLASMA/
Build Files => /HARDISK/PLASMA/BLD/
Demo Files => /HARDISK/PLASMA/DEMOS/
SANE files => /HARDISK/PLASMA/SYS
Use the System Utilities to copy the floppy images into the above mentioned directories.
## Apple 1
The Apple 1 is a very constrained system compared to the ][ and ///. It is required to have the CFFA1 disk adapter installed to provide file storage and a full 32K od RAM. To get the files onto the CF card required the use of [CiderPress](http://a2ciderpress.com) and they must be placed in one directory. Most PLASMA programs won't work on the Apple 1 due to limited filesystem support, video/graphics capabilities, and lack of audio output. It does, however, make a good place to start when porting PLASMA to a new platform.
## Apple ][
To boot directly into PLASMA, you will need to put the system files in the root prefix of the boot device and make sure PLASMA.SYSTEM is the first SYSTEM file in the directory. Otherwise, start PLASMA.SYSTEM from your program launcher of choice. All Apple ][ models with 64K and two floppy drives are supported up to a maxed out IIGS with accelerator and hard drive.
#### 65802/65816 Support
PLASMA can utilize the 16 bit features of the 65802 and 65816 processors to improve performance of the PLASMA VM operation. This is transparent to the programmer/user and doesn't make any additional memory or capabilities available to PLASMA. PLASMA will automatically run the most optimal VM for your configuration.
## Apple ///
The Apple /// gets the environment it always wanted: The ability to navigate the filesystem with a command line interface. The Apple /// always boots from the floppy drive, even if a hard disk is installed. The PLASMA.SOS floppy should be updated with the SOS.DRIVER configured for your machine. Once booted, type `S /HARDISK/PLASMA` (or your install directory of choice) to change to, and set, the system directory. This can be automated by creating an `AUTORUN` file on the boot floppy with the above command in it.
## PLASMA Command Line Shell
PLASMA incorporates a very basic command line shell to facilitate navigating the filesystem and executing both SYSTEM/SOS programs and PLASMA modules. It has a few built-in commands:
| Command | Operation |
|:----------------------------:|-------------------------|
| C [PREFIX] | Catalog prefix
| P \<PREFIX\> | change to Prefix
| / | change to parent prefix
| V | show online Volumes
| S \<PREFIX\> | set System prefix*
| +SOS \<SOS.INTERP\> [PREFIX] | launch SOS interpreter*
| -\<SYSTEM PROGRAM\> [PARAMS] | launch SYSTEM program**
| +\<PLASMA MODULE\> [PARAMS] | exec PLASMA module
```
[Optional parameters]
<Required parameters>
* Apple /// only
** Apple ][ only
```
The shell is very brief with error messages. It is meant solely as a way to run programs that accept command line parameters and take up as little memory as possible. It does, however, provide a rich runtime for PLASMA modules.
## Included Modules
PLASMA comes with many library modules used by the tools, demos and sample code. The PLASMA system volume must remain in place for the duration of PLASMAs run otherwise it won't be able to find CMD or the system libraries. Probably the most useful included module is the editor. It is used for editing PLASMA source file, assembly source files, or any text file. Execute it with:
```
+ED [TEXT FILE]
```
## Compiler Modules
The build disk includes sample source, include files for the system modules, and the PLASMA compiler+optimizer modules. The compiler is invoked with:
```
+PLASM [-[W][O[2]] <SOURCE FILE> [OUTPUT FILE]
```
Compiler warnings are enabled with `-W`. The optional optimizer is enabled with `-O` and extra optimizations are enabled with `-O2`. The source code for a few sample programs are included. The big one, `RPNCALC.PLA`, is the sample RPN calculator that uses many of PLASMA's advanced features. The self-hosted compiler is the same compiler as the cross-compiler, just transcribed from C to PLASMA (yes, the self-hosted PLASMA compiler is written in PLASMA). It requires patience when compiling: it is a fairly large and extensive program.
## Demos
There are some demo programs included for your perusal. Check out `ROGUE` for some diversion. You can find the documentation here: https://github.com/dschmenk/PLASMA/blob/master/doc/Rogue%20Instructions.md. A music sequencer to play through a MockingBoard if it is detected, or the built-in speaker if not. A minimal Web server if you have an Uthernet2 card (required). Bug reports appreciated.
## Source Code
Most sample source code is included from the project. They build without alteration and should be a good starting point for further explorations. The header files for the included library modules are in the INC directory.
## Video Playlist
There is a [YouTube playlist](https://www.youtube.com/playlist?list=PLlPKgUMQbJ79VJvZRfv1CJQf4SP2Gw3yU) created for learning PLASMA. It is a WIP, with updates every week or so
## Issues
- All the modules and runtime are written mostly in PLASMA; the compiler and editor as well. This means that there may be some startup delay as the PLASMA module loader reads in the module dependencies and performs dynamic linking. But a 1 MHz, 8 bit CPU interpreting bytecodes is never going to match a modern computer. As noted earlier, an accelerator and mass storage are your (and PLASMA's) friend.
- All the project modules are included. They have been lightly tested.
- The Apple /// may not always report errors properly or at all.
- The documentation is sparse and incomplete. Yep, could use your help...
# Changes in PLASMA for 2.0 DP 2
1. Many file manipulaition utilities (COPY, REName, NEWDIRectory, DELete, CATalog, TYPE)
2. New and updated libraries for lo-res. double lo-res and hi-res graphics w/ sprites
3. 32 bit integer library for those times when 16 bits just isn't enough
4. Apple /// improvements to other SOS.INTERP launching with SOS utility
5. Apple /// JIT VM for speed and non JIT version to free up global memory
6. Editor improvements
7. A couple small compiler optimizations
8. Needed to break out TCP/IP modules into seperate floppy image
9. Library changes require full install
# Changes in PLASMA for 2.0 DP 1z
1. Many fixes for the value zero - especially in 65802/65816 divide routine
# Changes in PLASMA for 2.0 DP 1 E+C
1. Greatly improved code editor and additional compiler stats
# Changes in PLASMA for 2.0 DP 1a
1. Fix interaction with JIT compiler and module load/unload
# Changes in PLASMA for 2.0 DP 1
1. Expanded bytecode for more efficient size/performance of programs
2. Just-In-Time Compiler for native code performance (6502 and 65816) for frequently called routines
3. Automatically identify and run most optimal VM for configuration
# Changes in PLASMA for 1.2
1. Add TFTPD TFTP server
2. Fix Uthernet 1 driver
3. Add mouse module
4. Fix IRQ issues for interrupt driven mouse driver
# Changes in PLASMA for 1.1
1. All known bugs are fixed
2. PLASM compiler received a little performance boost with an assembly language helper for ID/keyword lexical scanner
# Changes in PLASMA for 1.0
If you have been programming in PLASMA before, the 1.0 version has some major and minor changes that you should be aware of:
1. Case is no longer significant. Imported symbols were always upper case. Now, all symbols are treated as if they were upper case. You may find that some symbols clash with previously defined symbols of different case. Hey, we didn't need lower case in 1977 and we don't need it now. You kids, get off my lawn!
2. Modules are now first class citizens. Translation: importing a module adds a symbol with the module name. You can simply refer to a module's address with it's name. This is how a module's API table is accessed (instead of adding a variable of the same name in the IMPORT section).
3. Bytecode changes means previously compiled modules will crash. Rebuild.
4. `BYTE` and `WORD` have aliases that may improve readability of the code. `CHAR` (character) and `RES` (reserve) are synonyms for `BYTE`. `VAR` (variable) is a synonym for `WORD`. These aliases add no functionality. They are simply syntactic sugar to add context to the source code, but may cause problems if you've previously used the same names for identifiers.
5. When declaring variables, a base size can come after the type, and an array size can folllow the identifier. For instance:
```
res[10] a, b, c
```
will reserve three variables of 10 bytes each. Additionally:
```
res[10] v[5], w[3]
```
will reserve a total of 80 bytes (10 * 5 + 10 * 3). This would be useful when combined with a structure definition. One could:
```
res[t_record] patients[20]
```
to reserve an array of 20 patient records.
6. Ternary operator. Just like C and descendants, `??` and `::` allow for an if-then-else inside an expression:
```
puts(truth == TRUE ?? "TRUE" :: "FALSE")
```
7. Multiple value assignements. Multiple values can be returned from functions and listed on variable assignments:
```
def func#3 // Return 3 values
return 10, 20, 30
end
a, b, c = 1, 2, 3
c, d, f = func()
x, y = y, x // Swap x and y
```
8. `DROP` allows for explicit dropping of values. In the above `func()` example, if the middle value was the only one desired, the others can be ignored with:
```
drop, h, drop = func()
```
9. The compiler tracks parameter and return counts for functions. If the above `func()` were used without assigning all the return values, they would be dropped:
```
a = func() // Two values silently dropped
```
To generate compiler warning for this issue, and a few others, use the `-W` option when compiling.
10. Lambda (Anonymous) Functions. The ability to code a quick function in-line can be very powerful when used properly. Look here, https://en.wikipedia.org/wiki/Anonymous_function, for more information.
11. SANE (Standard Apple Numerics Environment) Floating Point Library. An extensive library (two, actually) of extended floating point (80 bit IEEE precision) functionality is suported. A wrapper library has been written to greatly simplify the interface to SANE. Look at the `RPNCALC.PLA` source code as an example.
12. Library Documentation. Preliminary documentation is available on the Wiki: https://github.com/dschmenk/PLASMA/wiki
13. Significant effort has gone into VM tuning and speeding up module loading/dynamic linking.
14. The VM zero page usage has changed. If you write assembly language routines, you will need to rebuild.
# Thanks
I wish to thank the people who have contributed the the PLASMA project. They have greatly improved the development of the language and documentation:
- Martin Haye: PLASMA programmer extraordinaire. Mr. Lawless Legends has requested many of the crucial features that set PLASMA apart.
- Steve F (ZornsLemma): Has taken the optimizer to new levels and his work on porting PLASMA to the Beeb are amazing: http://stardot.org.uk/forums/viewtopic.php?f=55&t=12306&sid=5a503c593f0698ebc31e590ac61b09fc
- Peter Ferrie: Assembly optimizer extraordinaire. He has made significant improvements into the code footprint in PLASMA so all the functionality can exist in just a few bytes.
- David Schmidt (DaveX): His help in documentation have made it much more accessible and professional. Of course any errors are all his. Just kidding, they're mine ;-)
- Andy Werner (6502.org): Catching the grammatical errors that I ain't no good at.
- John Brooks: Apple II Guru par excellence. His insights got 10% performance increase out of the VM.
Dave Schmenk
http://schmenk.is-a-geek.com

BIN
images/apple/PLASMA2-BLD.PO Normal file

Binary file not shown.

Binary file not shown.

BIN
images/apple/PLASMA2-SYS.PO Executable file

Binary file not shown.

BIN
images/apple/PLASMA2.2mg Normal file

Binary file not shown.

BIN
images/apple/TFTPD.PO Normal file

Binary file not shown.

View File

@@ -2,7 +2,7 @@ import cmdsys
//
// Useful values for everyone
//
const _SYSVER_ = $0100 // Version built against
const _SYSVER_ = $0200 // Version built against
const FALSE = 0
const TRUE = not FALSE
const NULL = 0
@@ -33,6 +33,7 @@ import cmdsys
const reshgr2 = $0020
const resxhgr1 = $0040
const resxhgr2 = $0080
const nojitc = $0100
//
// Module don't free memory
//
@@ -46,8 +47,15 @@ import cmdsys
word syspath
word cmdline
word modexec
byte refcons
byte devcons
word sysopen
word sysclose
word sysread
word syswrite
byte syserr
byte jitcount
byte jitsize
byte refcons // Apple /// specific
byte devcons // Apple /// specific
end
//
// CMD exported functions

View File

@@ -1,16 +0,0 @@
import dgr
word[] dgrbuff
predef dgrPlot(buff, x, y)#0
predef dgrHLin(buff, x1, x2, y)#0
predef dgrVLin(buff, x, y1, y2)#0
predef dgrBLT(buff, x, y, width, height, src)#0
predef dgrTile(buff, x, y, src)#0
predef dgrTileStr(buff, x, y, tilestr, strlen, tilebuff)#0
predef dgrFill(buff, x, y, tile)#0
predef dgrMode#1
predef txtMode#0
predef dgrShow(page)#1
predef dgrColor(clr)#0
predef dgrLine(buff, x1, y1, x2, y2)#0
predef dgrClear(buff, clr)#0
end

16
src/inc/dgrlib.plh Normal file
View File

@@ -0,0 +1,16 @@
import dgrlib
predef dgrPlot(x, y)#0
predef dgrHLin(x1, x2, y)#0
predef dgrVLin(y1, y2, x)#0
predef dgrBLT(x, y, width, height, src)#0
predef dgrTile(x, y, src)#0
predef dgrTileStr(x, y, tilestr, strlen, tilebuff)#0
predef dgrFill(x, y, tile)#0
predef dgrClear(clr)#0
predef dgrMode#1
predef txtMode#0
predef dgrShow(page)#1
predef dgrSwap#0
predef dgrDrawBuf(page)#0
predef dgrColor(clr)#0
end

View File

@@ -18,7 +18,27 @@ import fileio
const FILE_ERR_INT_TBL_FULL = $25
const FILE_ERR_IO = $27
//
// File entry struc
//
struc t_fileentry
byte store_namelen
byte entry_name[15]
byte entry_type
word entry_keyptr
word entry_blocks
word entry_EOFL
byte entry_EOFH
word entry_create[2]
byte entry_version
byte entry_minver
byte entry_access
word entry_aux
word entry_mod
word entry_headptr
end
//
// File info struc
//
struc t_fileinfo
byte file_access
byte file_type
@@ -37,7 +57,9 @@ import fileio
word getpfx
word setpfx
word getfileinfo
word setfileinfo
word geteof
word seteof
word iobufalloc
word open
word close
@@ -45,7 +67,9 @@ import fileio
word write
word create
word destroy
word rename
word newline
word online
word readblock
word writeblock
end

16
src/inc/grlib.plh Normal file
View File

@@ -0,0 +1,16 @@
import grlib
predef grPlot(x, y)#0
predef grHLin(x1, x2, y)#0
predef grVLin(y1, y2, x)#0
predef grBLT(x, y, width, height, src)#0
predef grTile(x, y, src)#0
predef grTileStr(x, y, tilestr, strlen, tilebuff)#0
predef grFill(x, y, tile)#0
predef grClear(clr)#0
predef grMode#1
predef txtMode#0
predef grShow(page)#1
predef grSwap#0
predef grDrawBuf(page)#0
predef grColor(clr)#0
end

21
src/inc/hgrlib.plh Normal file
View File

@@ -0,0 +1,21 @@
import hgrlib
predef divmod7(x)#2
predef hgrPlot(x, y)#0
predef hgrXorPlot(x, y)#0
predef hgrHLin(x1, x2, y)#0
predef hgrVLin(y1, y2, x)#0
predef hgrRect(x1, x2, y1, y2)#0
predef hgrBLT(x, y, width, height, srcptr)#0
predef hgrCopySrc(ofst, y, w, h, srcptr)#0
predef hgrAndSrc(ofst, y, w, h, srcptr)#0
predef hgrXorSrc(ofst, y, w, h, srcptr)#0
predef hgrOrSrc(ofst, y, w, h, srcptr)#0
predef hgrCopyDst(ofst, y, w, h, dstptr)#0
predef hgrMode#1
predef txtMode#0
predef hgrClear#0
predef hgrShow(page)#1
predef hgrSwap#1
predef hgrDrawBuf(page)#1
predef hgrColor(clr)#0
end

17
src/inc/hgrsprite.plh Normal file
View File

@@ -0,0 +1,17 @@
import hgrsprite
predef spriteCompile(w, h, xcenter, ycenter, srcptr)#1
predef spriteDup(sprtsrc)#1
predef spriteRead(filestr)#1
predef spriteSave(filestr, sprtptr)#1
predef spriteDraw(sprtptr)#0
predef spriteDrawXor(sprtptr)#0
predef spriteUnDraw(sprtptr)#0
predef spriteUnDrawXor(sprtptr)#0
predef spritePos(x, y, sprtptr)#0
predef spritePosIndex(x, y, i)#0
predef spriteDrawList#0
predef spriteDrawXorList#0
predef spriteAdd(i, sprtptr)#1
predef spriteDel(i)#1
predef spriteDrawBuf(page)#0
end

32
src/inc/int32.plh Normal file
View File

@@ -0,0 +1,32 @@
import int32
const t_i32 = 4
predef zero32#0
predef zext16to32#0
predef neg32#0
predef load32(i32ptr)#0
predef loadi16(imm16)#0
predef store32(i32ptr)#0
predef add32(i32ptr)#0
predef addi16(imm16)#0
predef sub32(i32ptr)#0
predef subi16(imm16)#0
predef shl32(imm8)#0
predef shr32(imm8)#0
predef mul32(i32ptr)#0
predef muli16(imm16)#0
predef div32(i32ptr)#2
predef divi16(imm16)#2
predef iseq32(i32ptr)#1
predef iseqi16(imm16)#1
predef isge32(i32ptr)#1
predef isgei16(imm16)#1
predef isle32(i32ptr)#1
predef islei16(imm16)#1
predef isgt32(i32ptr)#1
predef isgti16(imm16)#1
predef islt32(i32ptr)#1
predef islti16(imm16)#1
predef i32tos(i32ptr, strptr)#1
predef puti32(i32ptr)#0
end

6
src/inc/lines.plh Normal file
View File

@@ -0,0 +1,6 @@
import lines
predef setlinespans(h, v)#0
predef linespans(x1, y1, x2, y2)#0
predef setlineplot(p)#0
predef line(x1, y1, x2, y2)#0
end

3
src/inc/lz4.plh Normal file
View File

@@ -0,0 +1,3 @@
import lz4
predef lz4Unpack(seq, seqend, buff, buffend)
end

32
src/inc/mouse.plh Normal file
View File

@@ -0,0 +1,32 @@
import mouse
//
// Status bits
//
const BUTTON_DOWN = $80
const BUTTON_LAST_DOWN = $40
const MOUSE_MOVED = $20
const VBL_INT = $08
const BUTTON_INT = $04
const MOVE_INT = $02
//
// Mode bits
//
const VBL_INT_ENABLE = $08
const BUTTON_INT_ENABLE= $04
const MOVE_INT_ENABLE = $02
const MOUSE_ENABLE = $01
//
// Mouse API
//
struc t_mouse
word chkVBL
word chkMouse
word readMouse // readMouse()#3
word setMouse // setMouse(mode)
word clearMouse
word posMouse // posMouse(x, y)
word clampMouse // clampMouse(xMin, xMax, yMin, yMax)
word homeMouse
word detachMouse
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
include "inc/cmdsys.plh"
sysflags nojitc // Keep tone() from compiling and sounding different
//
// Handy constants.
//

View File

@@ -1,5 +1,4 @@
include "inc/cmdsys.plh"
sysflags restxt1|restxt2|resxtxt1|resxtxt2 // Reserve all text pages
//
// Apple II hardware constants.
//
@@ -24,13 +23,15 @@ const page2 = 1
//
// Screen row address arrays.
//
word[] dgr1rows = $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[] dgr2rows = $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
export word[] dgrbuff = @dgr1rows, @dgr2rows
word[] dgr1row = $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[] dgr2row = $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
word[] dgrbuff = @dgr1row, @dgr2row
word drawbuff
byte drawpage
//
// Color mapping.
//
@@ -49,13 +50,13 @@ end
//
// Plot pixel
//
export asm dgrPlot(buff, x, y)#0
; GET BUFFER ADDRESS
STX ESP
LDA ESTKL+2,X
export asm dgrPlot(x, y)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA ESTKH+2,X
STA SRCH
LDA $3001
STA SRCH
STX ESP
LDA ESTKL,X ; Y COORD
AND #$FE
TAY
@@ -76,22 +77,21 @@ asm _dgrPlotPix
LDX ESP
INX
INX
INX
RTS
end
//
// Plot horizontal row of pixels
//
export asm dgrHLin(buff, x1, x2, y)#0
; GET BUFFER ADDRESS
STX ESP
LDA ESTKL+3,X
export asm dgrHLin(x1, x2, y)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA ESTKH+3,X
STA SRCH
LDA $3001
STA SRCH
STX ESP
LDA ESTKL+1,X ; X2 COORD
STA TMPH
LDA ESTKL,X ; Y COORD
LDA ESTKL+0,X ; Y COORD
AND #$FE
TAY
LDA (SRC),Y
@@ -102,7 +102,7 @@ export asm dgrHLin(buff, x1, x2, y)#0
LDY ESTKL+2,X ; X1 COORD
PHP
SEI
- LDA ESTKL,X
- LDA ESTKL+0,X ; Y COORD
LSR
TYA
LDX GCLR ; COLOR
@@ -119,20 +119,19 @@ asm _dgrHLinPix
INX
INX
INX
INX
RTS
end
//
// Plot horizontal row of pixels
//
export asm dgrVLin(buff, x, y1, y2)#0
; GET BUFFER ADDRESS
STX ESP
LDA ESTKL+3,X
export asm dgrVLin(y1, y2, x)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA ESTKH+3,X
STA SRCH
LDA ESTKL+1,X ; Y1 COORD
LDA $3001
STA SRCH
STX ESP
LDA ESTKL+2,X ; Y1 COORD
PHP
SEI
- AND #$FE
@@ -142,38 +141,38 @@ export asm dgrVLin(buff, x, y1, y2)#0
INY
LDA (SRC),Y
STA GBASH
LDA ESTKL+1,X
LDA ESTKL+2,X
LSR
LDA ESTKL+2,X ; X COORD
LDA ESTKL+0,X ; X COORD
LDX GCLR ; COLOR
end
asm _dgrVLinPix
JSR $3000 ; _dgrSetPix
LDX ESP
INC ESTKL+1,X ; Y1 COORD
LDA ESTKL+1,X
CMP ESTKL,X ; Y2 COORD
INC ESTKL+2,X ; Y1 COORD
LDA ESTKL+2,X
CMP ESTKL+1,X ; Y2 COORD
BCC -
BEQ -
PLP
INX
INX
INX
INX
RTS
end
//
// Draw sprite
//
export asm dgrBLT(buff, x, y, width, height, src)#0
export asm dgrBLT(x, y, width, height, src)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA DSTL
LDA $3001
STA DSTH
LDA ESTKL,X ; SPRITE
STA SRCL
LDA ESTKH,X
STA SRCH
LDA ESTKL+5,X
STA DSTL
LDA ESTKH+5,X
STA DSTH
LDA ESTKL+4,X ; X1 COORD
CMP #80
BPL ++++
@@ -245,7 +244,6 @@ asm _dgrBLTPix
INX
INX
INX
INX
RTS
end
//
@@ -326,16 +324,17 @@ end
//
// Draw 8x8 tile (forced to 2x2 block address)
//
export asm dgrTile(buff, x, y, src)#0
export asm dgrTile(x, y, src)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA DSTL
LDA $3001
STA DSTH
STX ESP
LDA ESTKL,X ; TILE
STA SRCL
LDA ESTKH,X
STA SRCH
LDA ESTKL+3,X
STA DSTL
LDA ESTKH+3,X
STA DSTH
LDA ESTKL+2,X ; X1 COORD
CMP #80
BPL ++++
@@ -392,9 +391,9 @@ export asm dgrTile(buff, x, y, src)#0
STA (GBASE),Y
++ INC TMPH ; X COORD
INC TMPH ; X COORD
LDX ESP
LDA TMPH
BMI --
LDX ESP
CMP ESTKH+2,X ; X2 COORD
BCC --
PLP
@@ -405,7 +404,6 @@ export asm dgrTile(buff, x, y, src)#0
CMP ESTKH+1,X ; Y2 COORD
BCC -
++++ INX
INX
INX
INX
RTS
@@ -413,22 +411,17 @@ end
//
// Draw a string of tiles
//
export asm dgrTileStr(buff, x, y, tilestr, strlen, tilebuff)#0
export asm dgrTileStr(x, y, tilestr, strlen, tilebuff)#0
- DEX
DEX
DEX
DEX
LDA ESTKL+9,X ; BUFF
STA ESTKL+3,X
LDA ESTKH+9,X
STA ESTKH+3,X
LDA ESTKL+8,X ; X COORD
LDA ESTKL+7,X ; X COORD
STA ESTKL+2,X
LDA ESTKL+7,X ; Y COORD
LDA ESTKL+6,X ; Y COORD
STA ESTKL+1,X
LDA ESTKL+4,X ; TILE
LDA ESTKL+3,X ; TILE
STA ESTKL,X
LDA ESTKH+4,X ; TILE
LDA ESTKH+3,X ; TILE
STA ESTKH,X
end
asm _dgrTileTile
@@ -441,16 +434,17 @@ asm _dgrTileTile
STA ESTKL+4,X
DEC ESTKL+1,X ; DEC STRLEN
BNE -
+ TXA
CLC
ADC #6
TAX
+ INX
INX
INX
INX
INX
RTS
end
//
// Fill a buffer with tiles
//
export asm dgrFill(buff, x, y, tile)#0
export asm dgrFill(x, y, tile)#0
LDA ESTKL+2,X
AND #$0F
STA ESTKL+2,X
@@ -469,18 +463,13 @@ export asm dgrFill(buff, x, y, tile)#0
- DEX
DEX
DEX
DEX
LDA ESTKL+7,X ; BUFF
STA ESTKL+3,X
LDA ESTKH+7,X
STA ESTKH+3,X
LDA ESTKL+6,X ; X COORD
LDA ESTKL+5,X ; X COORD
STA ESTKL+2,X
LDA ESTKL+5,X ; Y COORD
LDA ESTKL+4,X ; Y COORD
STA ESTKL+1,X
LDA ESTKL+4,X ; TILE
LDA ESTKL+3,X ; TILE
STA ESTKL,X
LDA ESTKH+4,X ; TILE
LDA ESTKH+3,X ; TILE
STA ESTKH,X
end
asm _dgrFillTile
@@ -502,7 +491,6 @@ asm _dgrFillTile
INX
INX
INX
INX
RTS
end
//
@@ -516,6 +504,16 @@ asm vlbWait#0
RTS
end
//
// Clear the buffer
//
export def dgrClear(clr)#0
byte[32] clrtile
clr = evnclr[clr&$0F] | (oddclr[clr&$0F] << 8)
memset(@clrtile, clr, 32)
dgrFill(0, 0, @clrtile)
end
//
// Set double lores graphics, return draw buffer
//
export def dgrMode#1
@@ -526,6 +524,8 @@ export def dgrMode#1
^ena80 = 0
^show80 = 0
^an3on
drawpage = 1
drawbuff = dgrbuff[1]
return 1
end
//
@@ -548,6 +548,15 @@ export def dgrShow(page)#1
^(showpage1 + page)
return page ^ 1
end
export def dgrSwap#0
^(showpage1 + drawpage)
drawpage = drawpage ^ 1
drawbuff = dgrbuff[drawpage]
end
export def dgrDrawBuf(page)#0
drawpage = page
drawbuff = dgrbuff[drawpage]
end
//
// Set color for clear & plot routines
//
@@ -555,91 +564,6 @@ export def dgrColor(clr)#0
^$30 = clr & $0F
end
//
// Draw line
//
export def dgrLine(buff, x1, y1, x2, y2)#0
byte dx, dy, dx2, dy2, pp
word sx, sy, err, dd2
if x1 < x2
sx = 1
dx = x2 - x1
else
sx = -1
dx = x1 - x2
fin
if y1 < y2
sy = 1
dy = y2 - y1
else
sy = -1
dy = y1 - y2
fin
dx2 = dx << 1
dy2 = dy << 1
if dx >= dy // Horizontal line
if sx < 0
x1, x2 = x2, x1
y1, y2 = y2, y1
sy = -sy
fin
dd2 = dx2 - dy2
err = dx - dy2
sx = 1
while dy
if err < 0
dgrHLin(buff, x1, x1 + sx - 1, y1)
x1 = x1 + sx
y1 = y1 + sy
sx = 1
dy--
err = err + dd2
else
sx++
err = err - dy2
fin
loop
if y2 == y1
dgrHLin(buff, x1, x2, y1)
fin
else // Vertical line
if sy < 0
x1, x2 = x2, x1
y1, y2 = y2, y1
sx = -sx
fin
dd2 = dy2 - dx2
err = dy - dx2
sy = 1
while dx
if err < 0
dgrVLin(buff, x1, y1, y1 + sy - 1)
x1 = x1 + sx
y1 = y1 + sy
sy = 1
dx--
err = err + dd2
else
sy++
err = err - dx2
fin
loop
if x2 == x1
dgrVLin(buff, x1, y1, y2)
fin
fin
end
//
// Clear the buffer
//
export def dgrClear(buff, clr)#0
byte[32] clrtile
clr = evnclr[clr&$0F] | (oddclr[clr&$0F] << 8)
memset(@clrtile, clr, 32)
dgrFill(buff, 0, 0, @clrtile)
end
//
// Make sure we are a 128K //e or //c
//
if MACHID & $F0 <> $B0
@@ -661,6 +585,19 @@ _dgrSetEvnEvn:1 = @evnclr
_dgrSetEvnOdd:1 = @oddclr
_dgrSetOddEvn:1 = @evnclr
_dgrSetOddOdd:1 = @oddclr
//
// Fixups for drawbuff
//
dgrPlot:1 = @drawbuff
dgrPlot:6 = @drawbuff+1
dgrHLin:1 = @drawbuff
dgrHLin:6 = @drawbuff+1
dgrVLin:1 = @drawbuff
dgrVLin:6 = @drawbuff+1
dgrBLT:1 = @drawbuff
dgrBLT:6 = @drawbuff+1
dgrTile:1 = @drawbuff
dgrTile:6 = @drawbuff+1
// Put read AUX mem routine in scary location
memcpy($0100, @auxRead, 9)
done

View File

@@ -26,7 +26,9 @@ struc t_fileio
word getpfx
word setpfx
word getfileinfo
word setfileinfo
word geteof
word seteof
word iobufalloc
word open
word close
@@ -34,20 +36,22 @@ struc t_fileio
word write
word create
word destroy
word rename
word newline
word online
word readblock
word writeblock
end
predef a2getpfx(path), a23setpfx(path), a2getfileinfo(path, fileinfo), a23geteof(refnum), a2iobufs(iobufs), a2open(path), a2close(refnum)
predef a23read(refnum, buf, len), a2write(refnum, buf, len), a2create(path, type, aux), a23destroy(path)
predef a2newline(refnum, emask, nlchar), a2readblock(unit, buf, block), a2writeblock(unit, buf, block)
predef a2getpfx(path), a23setpfx(path), a2getfileinfo(path, fileinfo), a2setfileinfo(path, fileinfo), a23geteof(refnum)#2, a23seteof(refnum, eofl, eofh), a2iobufs(iobufs), a2open(path), a2close(refnum)
predef a23read(refnum, buf, len), a2write(refnum, buf, len), a2create(path, type, aux), a23destroy(path), a23rename(path, newpath)
predef a2newline(refnum, emask, nlchar), a2online(unit, buf), a2readblock(unit, buf, block), a2writeblock(unit, buf, block)
//
// Exported function table.
//
word fileio[]
word = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2iobufs, @a2open, @a2close
word = @a23read, @a2write, @a2create, @a23destroy
word = @a2newline, @a2readblock, @a2writeblock
word = @a2getpfx, @a23setpfx, @a2getfileinfo, @a2setfileinfo, @a23geteof, @a23seteof, @a2iobufs, @a2open, @a2close
word = @a23read, @a2write, @a2create, @a23destroy, @a23rename
word = @a2newline, @a2online, @a2readblock, @a2writeblock
//
// SOS/ProDOS error code
//
@@ -117,17 +121,53 @@ def a3getfileinfo(path, fileinfo)
perr = syscall($C4, @params)
return perr
end
def a1geteof(refnum)
return 0
def a1setfileinfo(path, fileinfo)
perr = $01
return perr
end
def a23geteof(refnum)
def a2setfileinfo(path, fileinfo)
byte params[14]
params.0 = 7
params:1 = path
memcpy(@params + 3, fileinfo, 11)
perr = syscall($C3, @params)
return perr
end
def a3setfileinfo(path, fileinfo)
byte params[6]
params.0 = 3
params:1 = path
params:3 = fileinfo
params.5 = 15
perr = syscall($C3, @params)
return perr
end
def a1geteof(refnum)#2
return 0, 0
end
def a23geteof(refnum)#2
byte params[5]
params.0 = 2
params.1 = refnum
params:2 = 0
params:4 = 0
params.4 = 0
syscall($D1, @params)
return params:2, params.4
end
def a1seteof(refnum, eofl, eofh)
return 0
end
def a23seteof(refnum, eofl, eofh)
byte params[5]
params.0 = 2
params.1 = refnum
params:2 = eofl
params.4 = eofh
syscall($D0, @params)
return params:2
end
def a1open(path)
@@ -271,7 +311,7 @@ def a2create(path, type, aux)
params.3 = $C3
params.4 = type
params:5 = aux
params.7 = $1
params.7 = type == $0F ?? $0D :: $01
params:8 = 0
params:10 = 0
perr = syscall($C0, @params)
@@ -284,13 +324,15 @@ def a3create(path, type, aux)
params.0 = 3
params:1 = path
params:3 = @options
params.5 = 3
params.5 = 4
options.0 = type
options:1 = aux
options.3 = type == $0F ?? $0D :: $01
perr = syscall($C0, @params)
return perr
end
def a1destroy(path)
perr = $01
return perr
end
def a23destroy(path)
@@ -301,6 +343,19 @@ def a23destroy(path)
perr = syscall($C1, @params)
return perr
end
def a1rename(oldpath, newpath)
perr = $01
return perr
end
def a23rename(path, newpath)
byte params[5]
params.0 = 2
params:1 = path
params:3 = newpath
perr = syscall($C2, @params)
return perr
end
def a1newline(refnum, emask, nlchar)
return perr
end
@@ -324,6 +379,57 @@ def a3newline(refnum, emask, nlchar)
perr = syscall($C9, @params)
return perr
end
def a1online(unit, buf)
perr = $27 // IOERR
return perr
end
def a2online(unit, buf)
byte params[4]
params.0 = 2
params.1 = unit
params:2 = buf
perr = syscall($C5, @params)
return perr
end
def a3volume(unit, volname)
byte devname[17]
byte info[11]
byte params[9]
^volname = 0
params.0 = 4
params.1 = unit
params:2 = @devname
params:4 = @info
params.6 = 11
if syscall($85, @params) == 0
params.0 = 4
params:1 = @devname
params:3 = volname
params:5 = 0
params:7 = 0
return syscall($C5, @params)
fin
return -1
end
def a3online(unit, buf)
byte info[11]
byte volname[17]
byte i
if unit == 0
for i = $01 to $0F
if a3volume(i, buf) == 0
^buf = ^buf | (i << 4)
fin
buf = buf + 16
next
else
return a3volume(unit, buf)
fin
return 0
end
def a13readblock(unit, buf, block)
perr = $27 // IOERR
return perr
@@ -359,12 +465,14 @@ when MACHID & MACHID_MODEL
is MACHID_III
fileio:getpfx = @a3getpfx
fileio:getfileinfo = @a3getfileinfo
fileio:setfileinfo = @a3setfileinfo
fileio:iobufalloc = @a13iobufs
fileio:open = @a3open
fileio:close = @a3close
fileio:write = @a3write
fileio:create = @a3create
fileio:newline = @a3newline
fileio:online = @a3online
fileio:readblock = @a13readblock
fileio:writeblock = @a13writeblock
break
@@ -372,7 +480,9 @@ when MACHID & MACHID_MODEL
fileio:getpfx = @a1getpfx
fileio:setpfx = @a1setpfx
fileio:getfileinfo = @a1getfileinfo
fileio:setfileinfo = @a1setfileinfo
fileio:geteof = @a1geteof
fileio:seteof = @a1seteof
fileio:iobufalloc = @a13iobufs
fileio:open = @a1open
fileio:close = @a1close
@@ -380,7 +490,9 @@ when MACHID & MACHID_MODEL
fileio:write = @a1write
fileio:create = @a1create
fileio:destroy = @a1destroy
fileio:rename = @a1rename
fileio:newline = @a1newline
fileio:online = @a1online
fileio:readblock = @a13readblock
fileio:writeblock = @a13writeblock
break

489
src/libsrc/apple/grlib.pla Normal file
View File

@@ -0,0 +1,489 @@
include "inc/cmdsys.plh"
//
// Apple II hardware constants.
//
const showgraphics = $C050
const showtext = $C051
const showfull = $C052
const showmix = $C053
const showpage1 = $C054
const showpage2 = $C055
const showlores = $C056
const showhires = $C057
const show40 = $C00C
const show80 = $C00D
const mapmain = $C000
const mapaux = $C001
const an3on = $C05E
const an3off = $C05F
const ena80 = $C07E
const dis80 = $C07F
const page1 = 0
const page2 = 1
//
// Screen row address arrays.
//
word[] gr1row = $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[] gr2row = $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
word[] grbuff = @gr1row, @gr2row
word drawbuff
byte drawpage
asm grInc(buff)
!SOURCE "vmsrc/plvmzp.inc"
GBASL = $26
GBASH = $27
GBASE = GBASL
GCLR = $30
end
//
// Plot pixel
//
export asm grPlot(x, y)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA $3001
STA SRCH
LDA ESTKL,X ; Y COORD
AND #$FE
TAY
LDA (SRC),Y
STA GBASL
INY
LDA (SRC),Y
STA GBASH
LDY ESTKL+1,X ; X COORD
LSR ESTKL,X
LDA GCLR ; COLOR
EOR (GBASE),Y
BCS +
; EVEN ROW
AND #$0F
BCC ++
; ODD ROW
+ AND #$F0
++ EOR (GBASE),Y
STA (GBASE),Y
INX
INX
RTS
end
//
// Plot horizontal row of pixels
//
export asm grHLin(x1, x2, y)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA $3001
STA SRCH
LDA ESTKL+1,X ; X2 COORD
STA TMPH
LDA ESTKL+0,X ; Y COORD
AND #$FE
TAY
LDA (SRC),Y
STA GBASL
INY
LDA (SRC),Y
STA GBASH
LDY ESTKL+2,X ; X1 COORD
- LDA ESTKL+0,X ; Y COORD
LSR
LDA GCLR ; COLOR
; EVEN ROW
EOR (GBASE),Y
BCS +
AND #$0F
BCC ++
; ODD ROW
+ AND #$F0
++ EOR (GBASE),Y
STA (GBASE),Y
INC ESTKL+2,X ; X1 COORD
LDY ESTKL+2,X
CPY TMPH ; X2 COORD
BCC -
BEQ -
INX
INX
INX
RTS
end
//
// Plot horizontal row of pixels
//
export asm grVLin(y1, y2, x)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA $3001
STA SRCH
LDA ESTKL+2,X ; Y1 COORD
- AND #$FE
TAY
LDA (SRC),Y
STA GBASL
INY
LDA (SRC),Y
STA GBASH
LDA ESTKL+2,X
LSR
LDY ESTKL+0,X ; X COORD
LDA GCLR ; COLOR
; EVEN ROW
EOR (GBASE),Y
BCS +
AND #$0F
BCC ++
; ODD ROW
+ AND #$F0
++ EOR (GBASE),Y
STA (GBASE),Y
INC ESTKL+2,X ; Y1 COORD
LDA ESTKL+2,X
CMP ESTKL+1,X ; Y2 COORD
BCC -
BEQ -
INX
INX
INX
RTS
end
//
// Draw sprite
//
export asm grBLT(x, y, width, height, src)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA DSTL
LDA $3001
STA DSTH
LDA ESTKL,X ; SPRITE
STA SRCL
LDA ESTKH,X
STA SRCH
LDA ESTKL+4,X ; X1 COORD
CMP #40
BPL ++++
CLC
ADC ESTKL+2,X
BMI ++++
STA ESTKH+2,X ; X2 COORD
LDA ESTKL+3,X ; Y1 COORD
CMP #48
BPL ++++
STA ESTKH+3,X ; Y COORD
CLC
ADC ESTKL+1,X
BMI ++++
STA ESTKH+1,X ; Y2 COORD
STX ESP
LDA ESTKH+3,X
- CMP #48
BCC +
LDA SRCL ; SKIP TO NEXT ROW
CLC
ADC ESTKL+2,X ; WIDTH
STA SRCL
LDA SRCH
ADC #$00
STA SRCH
BNE +++
+ AND #$FE
TAY
LDA (DST),Y
STA GBASL
INY
LDA (DST),Y
STA GBASH
LDA ESTKL+4,X ; X1 COORD
STA ESTKH+4,X ; X COORD
-- CMP #40
BCS ++
STA TMP
LDA ESTKH+3,X ; Y COORD
LSR
LDY #$00
LDA (SRC),Y
BMI ++
LDY TMP
BCS oddBLT
; EVEN ROW
EOR (GBASE),Y
AND #$0F
BCC evnBLT
; ODD ROW
oddBLT ASL
ASL
ASL
ASL
EOR (GBASE),Y
AND #$F0
evnBLT EOR (GBASE),Y
STA (GBASE),Y
++ INC SRCL
BNE +
INC SRCH
+ INC ESTKH+4,X ; X COORD
LDA ESTKH+4,X
BMI --
CMP ESTKH+2,X ; X2 COORD
BCC --
+++ INC ESTKH+3,X ; Y COORD
LDA ESTKH+3,X
BMI -
CMP ESTKH+1,X ; Y2 COORD
BCC -
++++ INX
INX
INX
INX
INX
RTS
end
//
// Draw 8x8 tile (forced to 1x2 block address)
//
export asm grTile(x, y, src)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA DSTL
LDA $3001
STA DSTH
STX ESP
LDA ESTKL,X ; TILE
STA SRCL
LDA ESTKH,X
STA SRCH
LDA ESTKL+2,X ; X1 COORD
CMP #40
BPL ++++
CLC
ADC #$08
BMI ++++
STA ESTKH+2,X ; X2 COORD
LDA ESTKL+1,X ; Y1 COORD
CMP #48
BPL ++++
STA TMPL ; Y COORD
CLC
ADC #$08
BMI ++++
STA ESTKH+1,X ; Y2 COORD
LDA TMPL ; Y COORD
- CMP #48
BCC +
LDA SRCL ; SKIP TO NEXT ROW
ADC #$07 ; CARRY = 1
STA SRCL
LDA SRCH
ADC #$00
STA SRCH
BNE +++
+ AND #$FE
TAY
LDA (DST),Y
STA GBASL
INY
LDA (DST),Y
STA GBASH
LDA ESTKL+2,X ; X1 COORD
STA TMPH ; X COORD
-- TAY
CMP #40
LDX #$00
LDA (SRC,X)
INC SRCL
BNE +
INC SRCH
+ BCS ++
STA (GBASE),Y
++ INC TMPH ; X COORD
LDA TMPH
BMI --
LDX ESP
CMP ESTKH+2,X ; X2 COORD
BCC --
+++ INC TMPL ; Y COORD
INC TMPL ; Y COORD
LDA TMPL
BMI -
CMP ESTKH+1,X ; Y2 COORD
BCC -
++++ INX
INX
INX
RTS
end
//
// Draw a string of tiles
//
export asm grTileStr(x, y, tilestr, strlen, tilebuff)#0
- DEX
DEX
DEX
LDA ESTKL+7,X ; X COORD
STA ESTKL+2,X
LDA ESTKL+6,X ; Y COORD
STA ESTKL+1,X
LDA ESTKL+3,X ; TILE
STA ESTKL,X
LDA ESTKH+3,X ; TILE
STA ESTKH,X
end
asm _grTileTile
JSR $5000
LDA ESTKL+4,X ; UPDATE X COORD
CLC
ADC #$08
CMP #40 ; OFF RIGHT SIDE
BPL +
STA ESTKL+4,X
DEC ESTKL+1,X ; DEC STRLEN
BNE -
+ INX
INX
INX
INX
INX
RTS
end
//
// Fill a buffer with tiles
//
export asm grFill(x, y, tile)#0
LDA ESTKL+2,X
AND #$0F
STA ESTKL+2,X
LDA ESTKL+1,X
AND #$0F
STA ESTKL+1,X
LDA #$00
SEC
SBC ESTKL+2,X ; ORIGINAL X
STA ESTKL+2,X
STA ESTKH+2,X
LDA #$00
SEC
SBC ESTKL+1,X
STA ESTKL+1,X
- DEX
DEX
DEX
LDA ESTKL+5,X ; X COORD
STA ESTKL+2,X
LDA ESTKL+4,X ; Y COORD
STA ESTKL+1,X
LDA ESTKL+3,X ; TILE
STA ESTKL,X
LDA ESTKH+3,X ; TILE
STA ESTKH,X
end
asm _grFillTile
JSR $5000
LDA ESTKL+2,X ; UPDATE X COORD
CLC
ADC #$08
STA ESTKL+2,X
CMP #40 ; OFF RIGHT SIDE?
BMI -
LDA ESTKH+2,X ; RESTORE X COORD
STA ESTKL+2,X
LDA ESTKL+1,X ; UPDATE Y COORD
CLC
ADC #$08
STA ESTKL+1,X
CMP #48 ; OFF BOTTOM?
BMI -
INX
INX
INX
RTS
end
//
// Clear the buffer
//
export def grClear(clr)#0
byte[32] clrtile
clr = (clr & $0F) | (clr << 4)
clr = (clr & $FF) | (clr << 8)
memset(@clrtile, clr, 32)
grFill(0, 0, @clrtile)
end
//
// Set lores graphics, return draw buffer
//
export def grMode#1
^showlores
^showfull
^showgraphics
^showpage1
^ena80 = 0
^show40 = 0
^mapmain = 0
^an3off
drawpage = 1
drawbuff = grbuff[1]
return 1
end
//
// Set text mode
//
export def txtMode#0
^showtext
^showpage1
^ena80 = 0
^show40 = 0
^mapmain = 0
^an3off
call($FC58, 0, 0, 0, 0) // home()
end
//
// Set display page, return other page
//
export def grShow(page)#1
page = page & 1
^(showpage1 + page)
return page ^ 1
end
export def grSwap#0
^(showpage1 + drawpage)
drawpage = drawpage ^ 1
drawbuff = grbuff[drawpage]
end
export def grDrawBuf(page)#0
drawpage = page
drawbuff = grbuff[drawpage]
end
//
// Set color for clear & plot routines
//
export def grColor(clr)#0
^$30 = (clr & $0F) | (clr << 4)
end
//
// Assembly fixups
//
_grTileTile:1 = @grTile
_grFillTile:1 = @grTile
//
// Fixups for drawbuff
//
grPlot:1 = @drawbuff
grPlot:6 = @drawbuff+1
grHLin:1 = @drawbuff
grHLin:6 = @drawbuff+1
grVLin:1 = @drawbuff
grVLin:6 = @drawbuff+1
grBLT:1 = @drawbuff
grBLT:6 = @drawbuff+1
grTile:1 = @drawbuff
grTile:6 = @drawbuff+1
done

1036
src/libsrc/apple/hgrlib.pla Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,328 @@
include "inc/cmdsys.plh"
include "inc/hgrlib.plh"
include "inc/fileio.plh"
struc t_sprite
var s_xpos
var s_ypos
var s_undery[2]
var s_underofst[2]
byte s_undermap[2]
byte s_xcenter
byte s_ycenter
byte s_pitch
byte s_height
var s_size
var s_mask[14]
var s_map[14]
var s_under[14]
end
var drawList[16]
var undrawList0[16]
var undrawList1[16]
var undrawList[2] = @undrawList0, @undrawList1
byte drawpage
//
// Sprite routines
//
asm scanMask(x, y, w, srcptr)#0
!SOURCE "vmsrc/plvmzp.inc"
LDA ESTKL+0,X ; SRC PTR
STA SRCL
LDA ESTKH+0,X
STA SRCH
LDA #$00
- PHA
LSR
TAY
LDA (SRC),Y
AND #$80
BEQ +
LDA #$03
+ DEX
STA ESTKL+0,X
end
asm _scanMaskA
JSR $C000 ; HCOLOR
DEX
DEX
LDA ESTKL+5,X ; X COORDL
STA ESTKL+1,X
LDA ESTKH+5,X ; X COORDH
STA ESTKH+1,X
LDA ESTKL+4,X ; Y COORDL
STA ESTKL+0,X
LDA ESTKH+4,X ; Y COORDH
STA ESTKH+0,X
end
asm _scanMaskB
JSR $D000 ; HPLOT
INC ESTKL+3,X ; X COORDL
BNE +
INC ESTKH+3,X ; X COORDH
+ PLA
CLC
ADC #$01
CMP ESTKL+1,X ; WIDTH
BEQ BLTDONE
PHA
LSR
TAY
LDA (SRC),Y
AND #$08
BEQ +
LDA #$03
+ DEX
STA ESTKL+0,X
end
asm _scanMaskC
JSR $C000 ; HCOLOR
DEX
DEX
LDA ESTKL+5,X ; X COORDL
STA ESTKL+1,X
LDA ESTKH+5,X ; X COORDH
STA ESTKH+1,X
LDA ESTKL+4,X ; Y COORDL
STA ESTKL+0,X
LDA ESTKH+4,X ; Y COORDH
STA ESTKH+0,X
end
asm _scanMaskD
JSR $D000 ; HPLOT
INC ESTKL+3,X ; X COORDL
BNE +
INC ESTKH+3,X ; X COORDH
+ PLA
CLC
ADC #$01
CMP ESTKL+1,X ; WIDTH
BNE -
BLTDONE INX
INX
INX
INX
RTS
end
def spriteBLTMask(x, y, w, h, srcptr)#0
word i, j
byte c
for j = y to y + h - 1
scanMask(x, j, w, srcptr)
// for i = 0 to w - 1
// c = srcptr->[i >> 1]
// if i & 1
// hgrColor(c & $08 ?? 3 :: 0)
// else
// hgrColor(c & $80 ?? 3 :: 0)
// fin
// hgrPlot(x + i, j)
// next
srcptr = srcptr + (w + 1) / 2
next
end
export def spriteCompile(w, h, xcenter, ycenter, srcptr)#1
var sprtptr, bytewidth, spritesize, i
sprtptr = heapalloc(t_sprite)
bytewidth = (w + 7) / 7 + 1
sprtptr->s_pitch = bytewidth
spritesize = bytewidth * h
sprtptr=>s_size = spritesize
sprtptr->s_height = h
sprtptr->s_xcenter = xcenter
sprtptr->s_ycenter = ycenter
sprtptr=>s_under[0] = heapalloc(spritesize)
sprtptr=>s_under[1] = heapalloc(spritesize)
for i = 0 to 13
sprtptr=>s_map[i] = heapalloc(spritesize)
sprtptr=>s_mask[i] = heapalloc(spritesize)
hgrColor(0)
hgrRect(0, w + 21, 0, h - 1)
hgrBLT(i, 0, w, h, srcptr)
hgrCopyDst(i > 6 ?? 1 :: 0, 0, bytewidth, h, sprtptr=>s_map[i])
hgrColor(3)
hgrRect(0, w + 21, h, h * 2 - 1)
spriteBLTMask(i, h, w, h, srcptr)
hgrCopyDst(i > 6 ?? 1 :: 0, h, bytewidth, h, sprtptr=>s_mask[i])
next
return sprtptr
end
export def spriteDup(sprtsrc)#1
var sprtdup, spritesize
byte i
sprtdup = heapalloc(t_sprite)
spritesize = sprtsrc=>s_size
sprtdup=>s_size = spritesize
sprtdup->s_pitch = sprtsrc->s_pitch
sprtdup->s_height = sprtsrc->s_height
sprtdup->s_height = sprtsrc->s_height
sprtdup->s_xcenter = sprtsrc->s_xcenter
sprtdup->s_ycenter = sprtsrc->s_ycenter
sprtdup=>s_under[0] = heapalloc(spritesize)
sprtdup=>s_under[1] = heapalloc(spritesize)
for i = 0 to 13
sprtdup=>s_map[i] = sprtsrc=>s_map[i]
sprtdup=>s_mask[i] = sprtsrc=>s_mask[i]
next
return sprtdup
end
export def spriteRead(filestr)#1
var sprtptr, spritesize
byte refnum, i
sprtptr = 0
refnum = fileio:open(@filestr)
if refnum
sprtptr = heapalloc(t_sprite)
if fileio:read(refnum, sprtptr, t_sprite) == t_sprite
spritesize = sprtptr=>s_size
sprtptr=>s_under[0] = heapalloc(spritesize)
sprtptr=>s_under[1] = heapalloc(spritesize)
for i = 0 to 13
sprtptr=>s_map[i] = heapalloc(spritesize)
sprtptr=>s_mask[i] = heapalloc(spritesize)
fileio:read(refnum, sprtptr=>s_map[i], spritesize)
fileio:read(refnum, sprtptr=>s_mask[i], spritesize)
next
else
heaprelease(sprtptr)
sprtptr = 0
fin
fileio:close(refnum)
fin
return sprtptr
end
export def spriteSave(filestr, sprtptr)#1
var spritesize
byte refnum, i
fileio:destroy(@filestr)
if fileio:create(@filestr, $06, $0000) == FILE_ERR_OK
refnum = fileio:open(@filestr)
if refnum
if fileio:write(refnum, sprtptr, t_sprite) == t_sprite
spritesize = sprtptr=>s_size
for i = 0 to 13
fileio:write(refnum, sprtptr=>s_map[i], spritesize)
fileio:write(refnum, sprtptr=>s_mask[i], spritesize)
next
fin
fileio:close(refnum)
return 0
fin
fin
return -1
end
export def spriteDraw(sprtptr)#0
byte map, pitch, height
var ofst, y
y = sprtptr=>s_ypos
ofst, map = divmod7(sprtptr=>s_xpos)
if ofst & 1
map = map + 7
fin
sprtptr=>s_underofst[drawpage] = ofst
sprtptr=>s_undery[drawpage] = y
pitch = sprtptr->s_pitch
height = sprtptr->s_height
hgrCopyDst(ofst, y, pitch, height, sprtptr=>s_under[drawpage])
hgrAndSrc( ofst, y, pitch, height, sprtptr=>s_mask[map])
hgrXorSrc( ofst, y, pitch, height, sprtptr=>s_map[map])
end
export def spriteUnDraw(sprtptr)#0
hgrCopySrc(sprtptr=>s_underofst[drawpage], sprtptr=>s_undery[drawpage], sprtptr->s_pitch, sprtptr->s_height, sprtptr=>s_under[drawpage])
end
export def spriteDrawXor(sprtptr)#0
byte map, pitch, height
var ofst, y
y = sprtptr=>s_ypos
ofst, map = divmod7(sprtptr=>s_xpos)
if ofst & 1
map = map + 7
fin
sprtptr->s_undermap[drawpage] = map
sprtptr=>s_underofst[drawpage] = ofst
sprtptr=>s_undery[drawpage] = y
pitch = sprtptr->s_pitch
height = sprtptr->s_height
hgrXorSrc( ofst, y, pitch, height, sprtptr=>s_map[map])
end
export def spriteUnDrawXor(sprtptr)#0
hgrXorSrc(sprtptr=>s_underofst[drawpage], sprtptr=>s_undery[drawpage], sprtptr->s_pitch, sprtptr->s_height, sprtptr=>s_map[sprtptr->s_undermap[drawpage]])
end
export def spritePos(x, y, sprtptr)#0
sprtptr=>s_ypos = y - sprtptr->s_ycenter
sprtptr=>s_xpos = x - sprtptr->s_xcenter
end
export def spritePosIndex(x, y, i)#0
i = i & 15
if drawList[i]
drawList[i]=>s_ypos = y - drawList[i]->s_ycenter
drawList[i]=>s_xpos = x - drawList[i]->s_xcenter
fin
end
export def spriteDrawList#0
byte i
var undrawptr
undrawptr = undrawList[drawpage]
for i = 15 downto 0
if undrawptr=>[i]
spriteUnDraw(undrawptr=>[i])
fin
next
for i = 0 to 15
if drawList[i]
spriteDraw(drawList[i])
fin
next
memcpy(undrawptr, @drawList, 16*2)
end
export def spriteDrawXorList#0
byte i
var undrawptr
undrawptr = undrawList[drawpage]
for i = 0 to 15
if undrawptr=>[i]
spriteUnDrawXor(undrawptr=>[i])
fin
if drawList[i]
spriteDrawXor(drawList[i])
fin
next
memcpy(undrawptr, @drawList, 16*2)
end
export def spriteAdd(i, sprtptr)#1
var sprtprev
i = i & 15
sprtprev = drawList[i]
drawList[i] = sprtptr
return sprtprev
end
export def spriteDel(i)#1
var sprtprev
i = i & 15
sprtprev = drawList[i]
drawList[i] = 0
return sprtprev
end
export def spriteDrawBuf(page)#0
drawpage = page & 1
end
//
// Assembly fixups
//
_scanMaskA:1 = @hgrColor
_scanMaskB:1 = @hgrPlot
_scanMaskC:1 = @hgrColor
_scanMaskD:1 = @hgrPlot
done

56
src/libsrc/apple/jit.pla Normal file
View File

@@ -0,0 +1,56 @@
//
// PLASMA JIT bytecode compiler
//
include "inc/cmdsys.plh"
//
// Indirect interpreter DEFinition entrypoint
//
struc t_defentry
byte interpjsr
word interpaddr
word bytecodeaddr
byte callcount
byte bytecodesize
end
//
// JIT compiler constants
//
const jitcomp = $03E2
const jitcodeptr = $03E4
const codemax = $BEE0
const estkh8 = $C000
const estkh = $00C0
const estkl8 = $D000
const estkl = $00D0
const ifpl8 = $E000
const ifph8 = $E100
const jmptmp = $00E6
const tmpl8 = $E700
const tmph8 = $E800
//
// Bytecode interpreter entrypoints
//
const indirectentry = $03DC
const directentry = $03D0
//
// Copy bytecode DEF to main memory
//
def defcpy(dst, defptr)#0
*$003C = defptr=>bytecodeaddr
*$003E = *$003C + defptr->bytecodesize
*$0042 = dst
call($C311, 0, 0, 0, $04) // CALL XMOVE with carry clear (AUX->MAIN) and ints disabled
end
include "libsrc/jitcore.pla"
//
// Install JIT compiler
//
if *jitcomp
return 0
fin
*jitcomp = @compiler
cmdsys.jitcount = 36
cmdsys.jitsize = 96
puts("JITC enabled\n")
return modkeep
done

View File

@@ -0,0 +1,67 @@
//
// PLASMA JIT bytecode compiler
//
include "inc/cmdsys.plh"
//
// Indirect interpreter DEFinition entrypoint
//
struc t_defentry
byte interpjsr
word interpaddr
word bytecodeaddr
byte callcount
byte bytecodesize
end
//
// JIT compiler constants
//
const jitcomp = $03E2
const jitcodeptr = $03E4
const codemax = $BEE0
const estkh8 = $C000
const estkh = $00C0
const estkl8 = $D000
const estkl = $00D0
const ifp8 = $E000
const ifpl8 = $E000
const ifph8 = $E100
const jmptmp = $00E6
const tmp8 = $E700
const tmpl8 = $E700
const tmph8 = $E800
const fetchop = $00F1
const ip8 = $F200
const ip = $00F2
//
// Bytecode interpreter entrypoints
//
const indirectentry = $03DC
const directentry = $03D0
//
// Copy bytecode DEF to main memory
//
def defcpy(dst, defptr)#0
*$003C = defptr=>bytecodeaddr
*$003E = *$003C + defptr->bytecodesize
*$0042 = dst
call($C311, 0, 0, 0, $04) // CALL XMOVE with carry clear (AUX->MAIN) and ints disabled
end
//
// Identify hardware addresses for certain byte sized access operations
//
def is_hwaddr(addr)
return isuge(addr, $C000) and isult(addr, $C100)
end
include "libsrc/jit16core.pla"
//
// Install JIT compiler
//
if *jitcomp
return 0
fin
*jitcomp = @compiler
cmdsys.jitcount = 32
cmdsys.jitsize = 96
puts("16-bit VM/JITC enabled\n")
return modkeep
done

583
src/libsrc/apple/mouse.pla Normal file
View File

@@ -0,0 +1,583 @@
include "inc/cmdsys.plh"
//
// Mouse driver interface
//
predef chkVbl, chkMouse, readMouse#3, setMouse(mode), clearMouse, posMouse(x, y), clampMouse(xMin, xMax, yMin, yMax), homeMouse, detachMouse
word = @chkVbl, @chkMouse, @readMouse, @setMouse, @clearMouse, @posMouse, @clampMouse, @homeMouse, @detachMouse
word rom
byte params[]
byte slot, index, page
word setMouseFW
byte vblDiv, vblInt, mouInt, bttnPrev
asm equates
!SOURCE "vmsrc/plvmzp.inc"
end
//
// Serve Mouse/VBL IRQ
//
asm serviceMouse#0
VBLINT = $400 ; DUMMY VALUES TO BE FIXED-UP
MOUINT = $401
LASTBTTN= $402
CLD
JSR $C400
BCC +
RTS ; NOT MOUSE INT
+ LDY $0778+4 ; CHECK MOUSE INT CAUSE
TYA ; WAS IT VBL?
AND #$08
BEQ + ; NOPE, MOVE OR BUTTON
end
asm vblEvent
INC VBLINT ; INC VBL EVENT
+ TYA ; MOUSE MOVE OR BUTTON ACTIVE
AND #$82
end
asm bttnEvent
EOR LASTBTTN
BEQ +
end
asm mouseEvent
INC MOUINT ; INC MOUSE EVENT
+ TYA
AND #$80
end
asm updateBttn
STA LASTBTTN
end
asm updateMouse
LDX #$C4
LDY #$40
JMP $C400 ; IIGS REQUIRES THIS HAPPEN IN IRQ
end
asm serviceCYA#0
CLC
RTS
end
//
// Check for VBL (timer) and Mouse events (atomic read and reset)
//
asm chkEvt(addr)
LDA ESTKL,X
STA ESTKH-1,X
SEI
LDA (ESTKH-1,X) ; READ INT COUNT
TAY
LDA #$00
STA (ESTKH-1,X) ; CLEAR INT COUNT
CLI
STY ESTKL,X ; RETURN INT COUNT
STA ESTKH,X
RTS
end
asm readMouse#3
LDY #$04
DEX
DEX
DEX
PHP
SEI
LDA $0478,Y
STA ESTKL+2,X
LDA $0578,Y
STA ESTKH+2,X
LDA $04F8,Y
STA ESTKL+1,X
LDA $05F8,Y
STA ESTKH+1,X
LDA $0778,Y
STA ESTKL,X
LDA #$00
STA ESTKH,X
PLP
RTS
end
//
// Convert VBL interrupts into millisecond timer increment
//
def chkVblTimer
byte count
word msec
msec = 0
count = chkEvt(@vblInt)
while count
if vblDiv & 2
msec = msec + 16
vblDiv = 0
else
msec = msec + 17
vblDiv++
fin
count--
loop
return msec
end
//
// Check for VBL/Mouse interrupt events
//
def chkVbl
return chkEvt(@vblInt)
end
def chkMouse
return chkEvt(@mouInt)
end
//
// Mouse routines
//
def setMouse(mode)
return call(setMouseFW, mode, slot, page, $04)
end
def clearMouse
return call(rom + rom->$15, $00, slot, page, $04) // clearMouseFW
end
def posMouse(x, y)
//
// Fill screen holes
//
^($0478 + index) = x
^($0578 + index) = x >> 8
^($04F8 + index) = y
^($05F8 + index) = y >> 8
return call(rom + rom->$16, $00, slot, page, $04) // posMouseFW
end
def clampMouse(xMin, xMax, yMin, yMax)
^$0478 = xMin
^$0578 = xMin >> 8
^$04F8 = xMax
^$05F8 = xMax >> 8
call(rom + rom->$17, $00, slot, page, $04) // clampMouseFW
^$0478 = yMin
^$0578 = yMin >> 8
^$04F8 = yMax
^$05F8 = yMax >> 8
return call(rom + rom->$17, $01, slot, page, $04)) // clampMouseFW
end
def homeMouse
return call(rom + rom->$18, $00, slot, page, $04) // homeMouseFW
end
//
// Detach mouse from interrupts
//
def detachMouse
setMouse(0)
params.0 = 1
params.1 = 0
return syscall($41, @params)
end
//
// Identify Mouse card/slot and initialize
//
for rom = $C100 to $C700 step $0100
if rom->5 == $38 and rom->7 == $18 and rom->11 == $01 and rom->12 == $20
puts("Found Mouse in slot #"); putc('0' + ((rom >> 8) & $07)); putln
//
// Hook mouse IRQ handler into ProDOS IRQ chain
//
params.0 = 2
params.1 = 0
params:2 = @serviceMouse
syscall($40, @params)
//
// Hook CYA IRQ handler into ProDOS IRQ chain
//
params.0 = 2
params.1 = 3
params:2 = @serviceCYA
syscall($40, @params)
//
// Set values
//
slot = rom >> 8
index = slot & $07
page = index << 4
setMouseFW = rom + rom->$12
//
// Fix-up IRQ routine
//
serviceMouse:2 = rom + rom->$13 // serveMouseFW
serviceMouse:8 = $0778+index
vblEvent:1 = @vblInt
bttnEvent:1 = @bttnPrev
mouseEvent:1 = @mouInt
updateBttn:1 = @bttnPrev
updateMouse.1 = slot
updateMouse.3 = page
updateMouse:5 = rom + rom->$14 // readMouseFW
readMouse.1 = index
call(rom + rom->$19, $00, slot, page, $04) // initMouseFW
return modkeep
fin
next
//
// Not found
//
return -1
done
What follows is the relevant parts to the mouse driver for VM02
CHKMOUSE: LDX #$20 ; LOOK FOR MOUSE
LDA #$01
JSR SCAN_SLOTS
BCS NOMOUSE
PHA ; SAVE SLOT
LDY #$13
LDA (TMPTR),Y
STA SERVEMOUSE+1 ; FIXUP IRQ HANDLER
STX SERVEMOUSE+2
LDY #$14
LDA (TMPTR),Y
STA READMOUSE+1 ; FIXUP IRQ HANDLER
STX READMOUSE+2
TXA
AND #$07
STA MOUSE_SLOT
TAY
JSR MOUSE_INIT ; MAKE SURE MOUSE IS OFF, INTS OFF
LDA WARM_INIT
BNE :+
JSR PUTS
.ASCIIZ "Mouse in slot #"
LDA MOUSE_SLOT
JSR PRBYTE
JSR CROUT
: PLA
TAY
LDA #<MOUSE_DRIVER ; LOAD MOUSE DRIVER
LDX #>MOUSE_DRIVER
JSR LOAD_DRIVER
;
; SCAN SLOTS FOR MATCHING CARD ID
; ENTRY: A = START SLOT SCAN
; X = CARD ID
; EXIT: A = SLOT # :: C = 0
; X = SLOT PAGE
;
SCAN_SLOTS: ORA #$C0
STA TMPTR+1
LDA #$00
STA TMPTR
CHKSIG: LDY #$05
LDA (TMPTR),Y
CMP #$38 ; LOOK FOR PASCAL COMPAT SIG
BNE :+
LDY #$07
LDA (TMPTR),Y
CMP #$18
BNE :+
LDY #$0B
LDA (TMPTR),Y
CMP #$01
BNE :+
LDY #$0C
TXA ; LOOK FOR MATCHING ID
CMP (TMPTR),Y
BNE :+
LDA TMPTR+1
TAX
AND #$07
CLC
RTS
: INC TMPTR+1
LDA TMPTR+1
CMP #$C8
BCC CHKSIG
SEC
RTS
;*
;* TURN VBL INTS ON AFTER INIT
;*
VBL_INIT: LDA MOUSE_SLOT
BEQ NOVBL
ASL
TAX
LSR
ORA #MOUSECTL_CALLFW
TAY
SEI ; TURN OFF INTERRUPTS
LDA LINK_DEVCTRL,X
STA CALLVBLPROC+1
LDA LINK_DEVCTRL+1,X
STA CALLVBLPROC+2
LDA #$08 ; TURN MOUSE OFF, LEAVE VBL ON
LDX #$12
CALLVBLPROC: JSR $0000
CLI ; BACK ON
LDA WARM_INIT
BNE NOVBL
JSR PUTSLN
.ASCIIZ "VBlank timer active"
NOVBL: RTS
JSR PRODOS
.BYTE $40 ; ALLOC INTERRUPT
.ADDR ALLOCINTPARMS
.IFDEF DEBUG
BCC :+
JSR PUTSLN
.ASCIIZ "FAILED TO ALLOCATE INTERRUPT"
:
.ENDIF
RTS
ALLOCINTPARMS: .BYTE $02
.BYTE $00 ; INT NUM
.ADDR IO_INTERRUPT ; INT CODE
;*
;* I/O INTERRUPT ROUTINE
;*
IO_INTERRUPT: CLD
LDY #$02 ; SLOT #1 * 2
FNDIRQPROC: LDA LINK_DEVIRQ+1,Y
BEQ NXTIRQPROC
STA CALLIRQPROC+2
LDA LINK_DEVIRQ,Y
STA CALLIRQPROC+1
TYA
LSR
PHA
CALLIRQPROC: JSR $0000
BCS :+
PLA
TAY
PHA
JSR THREAD_NOTIFYIO
: PLA
ASL
TAY
NXTIRQPROC: INY
INY
CPY #$10
BCC FNDIRQPROC
CLC
RTS
;*
;* MOUSE DEVICE DRIVER
;*
MOUSE_INIT: ORA #$C0
STA XREGMOUSE1+1
STA XREGMOUSE2+1
ASL
ASL
ASL
ASL
STA YREGMOUSE1+1
STA YREGMOUSE2+1
LDA #$00
PHA ; DISABLE ALL MOUSE INTS
LDX #$12 ; FW INDEX FOR SETMOUSE
BNE CALLMOUSEFW
MOUSE_DRIVER:
MOUSE_DRVR_SZ: .WORD MOUSE_DRVR_END - MOUSE_DRVR_START
MOUSE_READ_OFS: .WORD MOUSE_READ - MOUSE_DRVR_START
MOUSE_WRITE_OFS: .WORD MOUSE_WRITE - MOUSE_DRVR_START
MOUSE_CTRL_OFS: .WORD MOUSE_CTRL - MOUSE_DRVR_START
MOUSE_IRQ_OFS: .WORD MOUSE_IRQ - MOUSE_DRVR_START
MOUSE_DRVR_START:
MOUSE_READ:
MOUSE_WRITE: SEC
RTS
MOUSE_X: .WORD $0000
MOUSE_Y: .WORD $0000
MOUSE_STATUS: .BYTE $00
MOUSE_CTRL: PHA
TYA
AND #$F8 ; MASK OFF SLOT #
CMP #MOUSECTL_CALLFW
BNE :+
CALLMOUSEFW: STX OPADDR
XREGMOUSE2: LDX #$C4
STX OPADDR+1
LDY #$00
LDA (OPADDR),Y ; GET ENTRYPOINT OFFSET
STA OPADDR
YREGMOUSE2: LDY #$40
PLA
SEI
JMP (OPADDR) ; CALL FIXED UP FUNCTION POINTER
: CMP #MOUSECTL_READMOUSE ; COPY MOUSE STATUS/POSITION INTO EASILY ACCESSIBLE MEMORY
BNE :+
PLA
TYA
AND #$07
TAX ; SAVE MOUSE PARAMETERS
ASL
TAY
LDA LINK_DEVREAD,Y
STA TMPTR
LDA LINK_DEVREAD+1,Y
STA TMPTR+1
SEI
LDY #$02
LDA $0478,X
STA (TMPTR),Y
PHA
INY
LDA $0578,X
STA (TMPTR),Y
INY
LDA $04F8,X
STA (TMPTR),Y
PHA
INY
LDA $05F8,X
STA (TMPTR),Y
INY
LDA $0778,X
STA (TMPTR),Y
STA TMP
PLA
TAY
PLA
TAX
LDA TMP
RTS
: CMP #MOUSECTL_CLAMPX
BEQ :+
CMP #MOUSECTL_CLAMPY
BNE :++
: PLA
STA $04F8
STX $05F8
LDA #$00
STA $0478
STA $0578
TYA
LSR
LSR
LSR
AND #$01
PHA
LDX #$17 ; FW INDEX FOR CLAMPMOUSE
BNE CALLMOUSEFW
SETMOUSE: PHA
LDX #$12 ; FW INDEX FOR SETMOUSE
BNE CALLMOUSEFW
: PLA
TYA
AND #$F8 ; MASK OFF SLOT #
CMP #IOCTL_OPEN
BNE :+
LDA #<THREAD_YIELD ; REMOVE SOFTWARE TIMER
STA LINK_YIELD
LDA #>THREAD_YIELD
STA LINK_YIELD+1
LDA #$0F ; TURN MOUSE INTS ON
BNE SETMOUSE
: CMP #IOCTL_CLOSE
BNE :+
LDA #$08 ; TURN MOUSE OFF
BNE SETMOUSE
: CMP #IOCTL_DEACTIVATE
BNE :+
LDA #MOUSECTL_NOIRQ
: CMP #MOUSECTL_NOIRQ ; UNINSTALL IRQ HANDLER
BNE :+
SEI
LDA #<SW_TIMER ; RE-INSTALL SW TIMER
STA LINK_YIELD
LDA #>SW_TIMER
STA LINK_YIELD+1
BNE SETMOUSE
: CMP #IOCTL_ID
BEQ :+
SEC
RTS
: LDA #$20 ; MOUSE ID
CLC
RTS
;
; VBLANK TIMER AND MOUSE IRQ
;
MOUSE_IRQ: STA TMP
SERVEMOUSE: JSR $C400
BCS VBLEXIT ; NOT MOUSE INT
LDY TMP ; CHECK MOUSE INT CAUSE
LDA $0778,Y
PHA
AND #$08 ; WAS IT VLB?
BEQ MOUSEEXIT ; NOPE, MOVE OR BUTTON
VBLTIC: LDX #$00
LDA #$11 ; 17 MSEC (2/3 OF THE TIME)
DEC TIMERADJUST
BNE :+
LDA #$02
STA TIMERADJUST
LDA #$10 ; 16 MSEC (1/3 OF THE TIME)
: JSR SYSTEM_TIC
MOUSEEXIT: PLA
AND #$86 ; MOUSE MOVE OR BUTTON ACTIVE
BEQ VBLEXIT
XREGMOUSE1: LDX #$C4
YREGMOUSE1: LDY #$40
READMOUSE: JSR $C400 ; IIGS REQUIRES THIS HAPPEN IN IRQ
CLC
RTS
VBLEXIT: SEC
RTS
MOUSE_DRVR_END EQU *
package apple2;
/*
* This class interfaces directly with the mouse device driver.
*/
public class Mouse
{
static private int slot, mouseSlot, mouseCtrl, ctrlRead, addrXPos, addrYPos;
static public int xPos, yPos, status;
public static boolean enable()
{
//
// Search for mouse card and disable VBL interrupts
//
for (slot = 1; slot < 8; slot++)
{
int mouse = vm02.call((1 << 19), 0x90 + (slot << 1)); // ID device
if ((mouse & 0x010000FF) == 0x20) // CARRY clear == valid device IOCTL, 0x20 == mouse card ID
{
mouseCtrl = 0x90 + (slot << 1);
mouseSlot = slot << 16;
ctrlRead = mouseSlot | 0x801400;
addrXPos = vm02.peekWord(0x0370 + (slot << 1)) + 2;
addrYPos = addrXPos + 2;
return (vm02.call(mouseSlot | (3 << 19), mouseCtrl) & 0x01000000) == 0; // open port
}
}
slot = 0;
return false;
}
public static void disable()
{
vm02.call(mouseSlot | (4<<19), mouseCtrl); // close port
}
public static void disableIRQ()
{
int vblSlot, vbl;
//
// Search for mouse card and disable/remove interrupts
//
for (vblSlot = 1; vblSlot < 8; vblSlot++)
{
vbl = vm02.call((1 << 19), 0x90 + (vblSlot << 1)); // ID device
if ((vbl & 0x010000FF) == 0x20) // CARRY clear == valid device IOCTL, 0x20 == mouse card ID
{
vm02.call((vblSlot << 16) | (17 << 19), 0x90 + (vblSlot << 1)); // MOUSECTL_UNVBL
break;
}
}
}
public static int slotMask()
{
return (1 << slot);
}
public static void update()
{
status = vm02.call(ctrlRead, mouseCtrl) & 0xFF; // CALL_FW ReadMouse
xPos = vm02.peekWord(addrXPos);
yPos = vm02.peekWord(addrYPos);
}
}

View File

@@ -11,10 +11,10 @@ end
//
// Uthernet register offsets
//
const TX_DATA = $00
const RX_DATA = $00
const TX_CMD = $04
const TX_LEN = $06
const TX_DATA = $00
const RX_DATA = $00
const TX_CMD = $04
const TX_LEN = $06
const INT_STATUS = $08
const PREG_INDEX = $0A
const PREG_DATA = $0C
@@ -22,13 +22,14 @@ const AUTO_INC = $8000
//
// Uthernet register addresses
//
byte[] slot // Init time only
byte rxdata_lo, rxdata_hi
byte txcmd
byte txlen
byte isq
word rom[]
byte pregidx
byte pregdata
byte[] slot // Init time only
//
// Uthernet MAC address
//
@@ -37,156 +38,155 @@ byte[6] utherMAC = $00,$0A,$99,$1E,$02,$A0
// Defines for ASM routines
//
asm equates
!SOURCE "vmsrc/plvmzp.inc"
!SOURCE "vmsrc/plvmzp.inc"
end
//
// Uthernet I/O functions
//
asm _pokeiow(val)
LDA ESTKL,X
asm _pokeiow(val)#0
LDA ESTKL,X
end
asm _pokeiowl
STA $C000
LDA ESTKH,X
STA $C000
LDA ESTKH,X
end
asm _pokeiowh
STA $C000
RTS
STA $C000
INX
RTS
end
//
// PEEK BYTE FROM I/O SPACE
// _peekio()
//
asm _peekio
DEX
asm _peekio#1
DEX
end
asm _peekiol
LDA $C000
STA ESTKL,X
LDA #$00
STA ESTKH,X
RTS
LDA $C000
STA ESTKL,X
LDA #$00
STA ESTKH,X
RTS
end
//
// PEEK WORD FROM I/O SPACE
// _peekiow()
//
asm _peekiow
DEX
asm _peekiow#1
DEX
end
asm _peekiowl
LDA $C000
STA ESTKL,X
LDA $C000
STA ESTKL,X
end
asm _peekiowh
LDA $C000
STA ESTKH,X
RTS
LDA $C000
STA ESTKH,X
RTS
end
//
// WRITE FRAME DATA INTO I/O SPACE
// pokefrm(BUF, LEN)
//
asm pokefrm(buf, len)
LDY #$00
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ +
!BYTE $A9
- CLC
INC ESTKH,X
+ BCS -
POKELP LDA (SRC),Y
asm pokefrm(buf, len)#1
LDY #$00
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ +
INC ESTKH,X
+ BCC POKELP
INC ESTKH,X
POKELP LDA (SRC),Y
end
asm _pokefrml
STA $C000
INY
LDA (SRC),Y
STA $C000
INY
LDA (SRC),Y
end
asm _pokefrmh
STA $C000
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE POKELP
DEC ESTKH,X
BNE POKELP
INX
RTS
STA $C000
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE POKELP
DEC ESTKH,X
BNE POKELP
INX
RTS
end
//
// READ FRAME DATA FROM I/O SPACE
// peekfrm(BUF, LEN)
//
asm peekfrm(buf, len)
LDY #$00
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ +
!BYTE $A9
- CLC
INC ESTKH,X
+ BCS -
asm peekfrm(buf, len)#1
LDY #$00
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ +
INC ESTKH,X
+ BCC PEEKLP
INC ESTKH,X
end
asm _peekfrml
PEEKLP LDA $C000
STA (DST),Y
INY
PEEKLP LDA $C000
STA (DST),Y
INY
end
asm _peekfrmh
+ LDA $C000
STA (DST),Y
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE PEEKLP
DEC ESTKH,X
BNE PEEKLP
EXPSW INX
RTS
LDA $C000
STA (DST),Y
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE PEEKLP
DEC ESTKH,X
BNE PEEKLP
EXPSW INX
RTS
end
def pokeiow(io, data)
def pokeiow(io, data)#0
_pokeiowl.1 = io
_pokeiowh.1 = io+1
return _pokeiow(data)
_pokeiow(data)
end
def peekio(io)
def peekio(io)#1
_peekiol.1 = io
return _peekio()
end
def peekiow(io)
def peekiow(io)#1
_peekiowl.1 = io
_peekiowh.1 = io+1
return _peekiow()
end
def pokepreg(reg, data)
def pokepreg(reg, data)#0
pokeiow(pregidx, reg)
return pokeiow(pregdata, data)
pokeiow(pregdata, data)
end
def peekpreg(reg)
def peekpreg(reg)#1
pokeiow(pregidx, reg)
return peekiow(pregdata)
end
//
// Set the length of the next packet to send and wait for data space availability
//
def pokefrmlen(len)
def pokefrmlen(len)#1
pokeiow(txcmd, $C0)
pokeiow(txlen, len)
repeat; until peekpreg($0138) & $0100
@@ -195,7 +195,7 @@ end
//
// Return the length of awaiting packet, 0 otherwise
//
def peekfrmlen
def peekfrmlen#1
word len
len = 0
if peekiow(isq) & $3F == $04
@@ -214,35 +214,37 @@ end
// Identify Uthernet card and initialize
//
for slot = $90 to $F0 step $10
if (peekiow(slot+TX_CMD) & $CC3F) == $09
pokeiow(slot+PREG_INDEX, 0)
if peekiow(slot+PREG_DATA) == $630E
pokepreg($0114, $40) // RESET
rxdata_hi = slot + 1
txcmd = slot + TX_CMD
txlen = slot + TX_LEN
isq = slot + INT_STATUS
pregidx = slot + PREG_INDEX
pregdata = slot + PREG_DATA
_pokefrml.1 = slot
_pokefrmh.1 = slot+1
_peekfrml.1 = slot
_peekfrmh.1 = slot+1
pokepreg($0158, utherMAC:0) // MAC addr
pokepreg($015A, utherMAC:2) // MAC addr
pokepreg($015C, utherMAC:4) // MAC addr
pokepreg($0102, $0100) // Recv cfg
pokepreg($0104, $0D00) // Recv ctrl
pokepreg($0106, $8200) // Xmit cfg
pokepreg($0112, $00C0) // Line ctrl
//
// Install etherip driver
//
puts("Found Uthernet I in slot #")
putc('0' + ((slot - $80) >> 4))
putln
setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm)
return modkeep
rom = ((slot & $70) << 4) | $C000
if rom=>$06 <> $3C86 or (slot == $0B or (rom->$05 <> $38 and rom->$07 <> $18)) // Skip slots with signature
if (peekiow(slot+TX_CMD) & $CC3F) == $0009
pokeiow(slot+PREG_INDEX, 0)
if peekiow(slot+PREG_DATA) == $630E
pregidx = slot + PREG_INDEX
pregdata = slot + PREG_DATA
pokepreg($0114, $40) // RESET
rxdata_lo = slot + RX_DATA
rxdata_hi = slot + RX_DATA + 1
txcmd = slot + TX_CMD
txlen = slot + TX_LEN
isq = slot + INT_STATUS
_pokefrml.1 = slot + TX_DATA
_pokefrmh.1 = slot + TX_DATA + 1
_peekfrml.1 = slot + RX_DATA
_peekfrmh.1 = slot + RX_DATA + 1
pokepreg($0158, utherMAC:0) // MAC addr
pokepreg($015A, utherMAC:2) // MAC addr
pokepreg($015C, utherMAC:4) // MAC addr
pokepreg($0102, $0100) // Recv cfg
pokepreg($0104, $0D00) // Recv ctrl
pokepreg($0106, $8200) // Xmit cfg
pokepreg($0112, $00C0) // Line ctrl
//
// Install etherip driver
//
puts("Found Uthernet I in slot #"); putc('0' + ((slot - $80) >> 4)); putln
setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm)
return modkeep
fin
fin
fin
next

View File

@@ -71,10 +71,11 @@ const WIZ_RXMEM3 = $7800
//
// Wiznet indirect registers
//
byte slot
word saveidx
byte regidx
byte regdata
word[] rom
word saveidx
byte regidx
byte regdata
byte slot
//
// Wiznet MAC address
//
@@ -137,16 +138,15 @@ word bcast = IP_BROADCAST, IP_BROADCAST
//
// ICMP type/codes
//
const IP_PROTO_ICMP = 1
const ICMP_ECHO_REQST = 8
const ICMP_ECHO_REPLY = 0
//
// ICMP message format
//
struc t_icmp
byte icmp_type
byte icmp_code
word icmp_chksm
byte icmp_type
byte icmp_code
word icmp_chksm
word[2] icmp_header
end
//
@@ -155,9 +155,9 @@ end
struc t_piphdr
byte[IP4ADR_SIZE] pip_src
byte[IP4ADR_SIZE] pip_dst
byte pip_zero
byte pip_proto
word pip_len
byte pip_zero
byte pip_proto
word pip_len
end
//
// UDP header
@@ -184,11 +184,11 @@ const MAX_WIZ_CHANNELS = 4
//
// Channel protocols
//
const WIZ_PROTO_CLOSED = 0
const WIZ_PROTO_TCP = 1
const WIZ_PROTO_UDP = 2
const WIZ_PROTO_IP = 3
const WIZ_PROTO_RAW = 4
const WIZ_PROTO_CLOSED = 0
const WIZ_PROTO_TCP = 1
const WIZ_PROTO_UDP = 2
const WIZ_PROTO_IP = 3
const WIZ_PROTO_RAW = 4
//
// State transistions
//
@@ -212,7 +212,7 @@ struc t_channel
word channel_recv_func
word channel_recv_parm
end
byte[t_channel * MAX_WIZ_CHANNELS] wizChannel
byte[t_channel] wizChannel[MAX_WIZ_CHANNELS]
//
// Service ICMP hook
//
@@ -221,17 +221,17 @@ export word hookICMP
// Defines for ASM routines
//
asm equates
!SOURCE "vmsrc/plvmzp.inc"
!SOURCE "vmsrc/plvmzp.inc"
end
//
// Swap bytes in word
//
asm swab(val)
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
STY ESTKL,X
RTS
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
STY ESTKL,X
RTS
end
//
// Wiznet I/O functions
@@ -239,118 +239,122 @@ end
// POKE WORD TO I/O SPACE
// Note: Big Endian format
//
asm _pokeiow(val)
LDA ESTKH,X
asm _pokeiow(val)#0
LDA ESTKH,X
end
asm _pokeiowl
STA $C000
LDA ESTKL,X
STA $C000
LDA ESTKL,X
end
asm _pokeiowh
STA $C000
RTS
STA $C000
INX
RTS
end
//
// POKE BYTE TO I/O SPACE
//
asm _pokeio(val)
LDA ESTKL,X
asm _pokeio(val)#0
LDA ESTKL,X
end
asm _pokeiol
STA $C000
RTS
STA $C000
INX
RTS
end
//
// PEEK BYTE FROM I/O SPACE
//
asm _peekio
DEX
DEX
end
asm _peekiol
LDA $C000
STA ESTKL,X
LDA #$00
STA ESTKH,X
RTS
LDA $C000
STA ESTKL,X
LDA #$00
STA ESTKH,X
RTS
end
//
// PEEK WORD FROM I/O SPACE
// Note: Big Endian format
//
asm _peekiow
DEX
DEX
end
asm _peekiowl
LDA $C000
STA ESTKH,X
LDA $C000
STA ESTKH,X
end
asm _peekiowh
LDA $C000
STA ESTKL,X
RTS
LDA $C000
STA ESTKL,X
RTS
end
//
// WRITE DATA INTO I/O SPACE
// pokedata(BUF, LEN)
//
asm pokedata(buf, len)
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDY ESTKL,X
BEQ POKELP
LDY #$00
INC ESTKH,X
POKELP LDA (SRC),Y
asm pokedata(buf, len)#0
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDY ESTKL,X
BEQ POKELP
LDY #$00
INC ESTKH,X
POKELP LDA (SRC),Y
end
asm _pokedata
STA $C000
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE POKELP
DEC ESTKH,X
BNE POKELP
INX
RTS
STA $C000
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE POKELP
DEC ESTKH,X
BNE POKELP
INX
INX
RTS
end
//
// READ DATA FROM I/O SPACE
// peekdata(BUF, LEN)
//
asm peekdata(buf, len)
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LDY ESTKL,X
BEQ PEEKLP
LDY #$00
INC ESTKH,X
asm peekdata(buf, len)#0
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LDY ESTKL,X
BEQ PEEKLP
LDY #$00
INC ESTKH,X
end
asm _peekdata
PEEKLP LDA $C000
STA (DST),Y
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE PEEKLP
DEC ESTKH,X
BNE PEEKLP
INX
RTS
PEEKLP LDA $C000
STA (DST),Y
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE PEEKLP
DEC ESTKH,X
BNE PEEKLP
INX
INX
RTS
end
def pokeiow(io, data)
def pokeiow(io, data)#0
_pokeiowl.1 = io
_pokeiowh.1 = io+1
return _pokeiow(data)
_pokeiow(data)
end
def pokeio(io, data)
def pokeio(io, data)#0
_pokeiol.1 = io
return _pokeio(data)
_pokeio(data)
end
def peekio(io)
_peekiol.1 = io
@@ -361,26 +365,26 @@ def peekiow(io)
_peekiowh.1 = io+1
return _peekiow()
end
def pokereg(reg, data)
def pokereg(reg, data)#0
_pokeiow(reg)
return _pokeio(data)
_pokeio(data)
end
def peekreg(reg)
_pokeiow(reg)
return _peekio()
end
def pokeregs(reg, buf, len)
def pokeregs(reg, buf, len)#0
_pokeiow(reg)
return pokedata(buf, len)
pokedata(buf, len)
end
def peekregs(reg, buf, len)
def peekregs(reg, buf, len)#0
_pokeiow(reg)
return peekdata(buf, len)
peekdata(buf, len)
end
def pokeregw(reg, dataw)
def pokeregw(reg, dataw)#0
_pokeiow(reg)
_pokeio(dataw.1)
return _pokeio(dataw.0)
_pokeio(dataw.0)
end
def peekregw(reg)
word dataw
@@ -415,7 +419,7 @@ def wizSendUDP(wiz, ipdst, portdst, data, len)
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
else
else
pokeregs(wizdata + txrr, data, len)
fin
//
@@ -470,9 +474,9 @@ def wizOpenUDP(localport, callback, param)
wiz=>channel_lclport = localport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $02) // UDP protocol
pokeregw(wiz=>channel_regs + WIZ_SnPORT, localport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $02) // UDP protocol
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
return wiz
end
//
@@ -480,14 +484,14 @@ end
//
def wizCloseUDP(wiz)
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_UDP
wiz->channel_proto = WIZ_PROTO_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
return 0
fin
return 0
fin
fin
//
// Invalid port
@@ -508,8 +512,8 @@ def wizListenTCP(lclport, callback, param)
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == WIZ_PROTO_TCP and wiz->channel_state == TCP_STATE_LISTEN and wiz=>channel_lclport == lclport
break
fin
wiz = wiz + t_channel
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
//
@@ -519,8 +523,8 @@ def wizListenTCP(lclport, callback, param)
for i = 1 to MAX_WIZ_CHANNELS
if !wiz->channel_proto
break
fin
wiz = wiz + t_channel
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
return 0
@@ -537,9 +541,9 @@ def wizListenTCP(lclport, callback, param)
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
while peekreg(wiz=>channel_regs + WIZ_SnSR) <> $13; loop // Wait for init
pokereg(wiz=>channel_regs + WIZ_SnCR, $02) // LISTEN
return wiz
@@ -619,7 +623,7 @@ def wizSendTCP(wiz, data, len)
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
//putc('(');puti(splitlen);putc(',');puti(len-splitlen);putc(')')
else
else
pokeregs(wizdata + txrr, data, len)
fin
//
@@ -634,9 +638,9 @@ end
//
def wizCloseTCP(wiz)
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_TCP
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wiz->channel_proto = WIZ_PROTO_CLOSED
@@ -670,10 +674,10 @@ end
def wizSetParam(wiz, param)
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
//
// Update param on this port
//
wiz=>channel_recv_parm = param
return 0
// Update param on this port
//
wiz=>channel_recv_parm = param
return 0
fin
//
// Invalid port
@@ -698,7 +702,7 @@ def wizServiceIP
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_rxmem
sir = peekreg(wizregs + WIZ_SnIR)
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
pokereg(wizregs + WIZ_SnIR, sir) // Clear SnIR
when wiz->channel_proto
is WIZ_PROTO_UDP
if sir & $04
@@ -735,63 +739,63 @@ def wizServiceIP
wiz->channel_state = TCP_STATE_OPEN
wend
fin
if sir & $04
//
// Receive TCP packet
//
if wiz->channel_state == TCP_STATE_OPEN
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
if sir & $04
//
// Receive TCP packet
//
if wiz->channel_state == TCP_STATE_OPEN
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
fin
if sir & $02
//
// Close TCP socket
//
if wiz->channel_state == TCP_STATE_OPEN // Notify callback w/ len = 0
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
if sir & $02
//
// Close TCP socket
//
if wiz->channel_state == TCP_STATE_OPEN // Notify callback w/ len = 0
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
fin
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
fin
if sir & $08
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wend
fin
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
fin
if sir & $08
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wend
fin
wend
fin
wiz = wiz + t_channel
next
if ir & $80
if ir & $80
//
// IP conflict
//
pokereg(WIZ_IR, $80)
// IP conflict
//
pokereg(WIZ_IR, $80)
fin
if ir & $40
//
@@ -839,71 +843,77 @@ end
// Identify Uthernet II card and initialize
//
for slot = $90 to $F0 step $10
regdata = peekio(slot)
if (regdata & $E4) == $00
pokeio(slot, $03) // Try setting auto-increment indirect I/F
if peekio(slot) == $03
saveidx = peekiow(slot + 1)
peekio(slot + 3) // Dummy read to data register should increment index
if peekiow(slot + 1) == saveidx + 1
//
// Good chance this is it
//
pokeio(slot, $80) // RESET
regidx = slot + 1
regdata = slot + 3
_pokedata.1 = regdata
_peekdata.1 = regdata
pokeio(slot, $03) // Auto-increment indirect I/F + enable ping
//
// The following looks redundant, but it sets up the peek/poke locations
// for peekreg(s)/pokereg(s)
//
pokeiow(regidx, WIZ_MR)
pokeio(regdata, $03) // Auto-increment indirect I/F + enable ping
peekio(regdata)
//
// Initialize common registers
//
pokeregs(WIZ_SHAR, @wizMAC, 6) // MAC addr
pokeregw(WIZ_RTR, 5000) // Timeout period to 500ms
pokereg(WIZ_RMSR, $55) // 2K Rx memory/channel
pokereg(WIZ_TMSR, $55) // 2K Tx memory/channel
//
// Print settings
//
puts("Found Uthernet II in slot #")
putc('0' + ((slot - $80) >> 4))
putln
//
// Fill channel structure
//
saveidx = @wizChannel
for slot = 0 to 3
saveidx=>channel_regs = WIZ_SREGS + (WIZ_SSIZE * slot)
saveidx=>channel_txmem = WIZ_TXMEM + (WIZ_TXSIZE * slot)
saveidx=>channel_rxmem = WIZ_RXMEM + (WIZ_RXSIZE * slot)
saveidx = saveidx + t_channel
next
//
// Fill in Net class
//
iNet:serviceIP = @wizServiceIP
iNet:openUDP = @wizOpenUDP
iNet:sendUDP = @wizSendUDP
iNet:closeUDP = @wizCloseUDP
iNet:listenTCP = @wizListenTCP
iNet:connectTCP = @wizConnectTCP
iNet:sendTCP = @wizSendTCP
iNet:closeTCP = @wizCloseTCP
iNet:setInterfaceIP = @setWizIP
iNet:getInterfaceHA = @getWizHA
iNet:setCallback = @wizSetCallback
iNet:setParam = @wizSetParam
return modkeep
rom = ((slot & $70) << 4) | $C000
if rom=>$06 <> $3C86 or (slot == $0B or (rom->$05 <> $38 and rom->$07 <> $18)) // Skip slots with signature
regdata = peekio(slot)
if (regdata & $E4) == $00
pokeio(slot, $03) // Try setting auto-increment indirect I/F
if peekio(slot) == $03
saveidx = peekiow(slot + 1)
peekio(slot + 3) // Dummy read to data register should increment index
if peekiow(slot + 1) == saveidx + 1
//
// Good chance this is it
//
pokeio(slot, $80) // RESET
regidx = slot + 1
regdata = slot + 3
_pokedata.1 = regdata
_peekdata.1 = regdata
repeat
pokeio(slot, $03) // Auto-increment indirect I/F + enable ping
until peekio(slot) == $03
//
// The following looks redundant, but it sets up the peek/poke locations
// for peekreg(s)/pokereg(s)
//
pokeiow(regidx, WIZ_MR)
pokeio(regdata, $03) // Auto-increment indirect I/F + enable ping
peekio(regdata)
//
// Initialize common registers
//
wizMAC[5] = slot >> 4 // Slighty unique MAC address
pokeregs(WIZ_SHAR, @wizMAC, 6) // MAC addr
pokeregw(WIZ_RTR, 5000) // Timeout period to 500ms
pokereg(WIZ_RMSR, $55) // 2K Rx memory/channel
pokereg(WIZ_TMSR, $55) // 2K Tx memory/channel
//
// Print settings
//
puts("Found Uthernet II in slot #")
putc('0' + ((slot - $80) >> 4))
putln
//
// Fill channel structure
//
saveidx = @wizChannel
for slot = 0 to 3
saveidx=>channel_regs = WIZ_SREGS + (WIZ_SSIZE * slot)
saveidx=>channel_txmem = WIZ_TXMEM + (WIZ_TXSIZE * slot)
saveidx=>channel_rxmem = WIZ_RXMEM + (WIZ_RXSIZE * slot)
saveidx = saveidx + t_channel
next
//
// Fill in Net class
//
iNet:serviceIP = @wizServiceIP
iNet:openUDP = @wizOpenUDP
iNet:sendUDP = @wizSendUDP
iNet:closeUDP = @wizCloseUDP
iNet:listenTCP = @wizListenTCP
iNet:connectTCP = @wizConnectTCP
iNet:sendTCP = @wizSendTCP
iNet:closeTCP = @wizCloseTCP
iNet:setInterfaceIP = @setWizIP
iNet:getInterfaceHA = @getWizHA
iNet:setCallback = @wizSetCallback
iNet:setParam = @wizSetParam
return modkeep
fin
fin
pokeio(slot, regdata) // Restore register
fin
pokeio(slot, regdata) // Restore register
fin
next
//

View File

@@ -1,4 +1,5 @@
include "inc/cmdsys.plh"
sysflags nojitc // No need to speed this up
def argDelim(str)
byte n

View File

@@ -3,6 +3,7 @@
//
include "inc/cmdsys.plh"
include "inc/inet.plh"
sysflags nojitc // No need to JITC this temp loaded module
//
// Needed to init subnet
//
@@ -137,7 +138,7 @@ end
def recvDHCP(remip, remport, pkt, len, param)
word servopts, maskopts, gwopts, dnsopts
//putip(remip);putc(':');puti(remport);putln
//puts("recvDHCP: ");putip(remip);putc(':');puti(remport);putln
//dumpdhcp(pkt)
if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 == $0403
when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2]
@@ -155,10 +156,10 @@ def recvDHCP(remip, remport, pkt, len, param)
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @endDHCP - @DHCP)
break
is DHCP_ACK
optsOP.2 = DHCP_ACK
//
// Copy parameters to working copy
//
optsOP.2 = DHCP_ACK
memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE)
maskopts = parseopts(@pkt->dhcp_opts, 1) + 2
if maskopts >= 0
@@ -187,7 +188,7 @@ iNet:getInterfaceHA(@optsCID.3)
//
// Clear our local IP address
//
iNet:setInterfaceIP(@zeros,@ones, @zeros)
iNet:setInterfaceIP(@zeros, @ones, @zeros)
//
// Prepare to receive DHCP packets from a server
//
@@ -206,17 +207,17 @@ repeat
optsSRV = 255
DHCP.dhcp_secs.1 = retry
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @optsSRV - @DHCP + 1)
for timeout = 0 to 1000
for timeout = 0 to 4000
iNet:serviceIP()
if optsOP.2 == DHCP_ACK
break
fin
next
retry = retry + 1
retry++
until retry > 4 or optsOP.2 == DHCP_ACK
iNet:closeUDP(portDHCP)
iNet:setInterfaceIP(@localip, @localnet, @localgw)
puts("Apple II bound to:\n");putip(@localip);putc('/');putip(@localnet);putln
iNet:setDNS(@localdns)
//puts("DNS: ");putip(@localdns);putln
puts("DNS:");putip(@localdns);putln
done

View File

@@ -52,7 +52,6 @@ const IP_PROTO_TCP = $06
//
// ICMP type/codes
//
const IP_PROTO_ICMP = 1
const ICMP_ECHO_REQST = 8
const ICMP_ECHO_REPLY = 0
//
@@ -101,7 +100,7 @@ const ARP_REQST = $0100 // BE format
const ARP_REPLY = $0200 // BE format
struc t_arp
word arp_hw
word arp_proto
word arp_prot
byte arp_hlen
byte arp_plen
word arp_op
@@ -155,8 +154,8 @@ struc t_notify
word notify_func
word notify_parm
end
byte[t_notify * MAX_UDP_NOTIFIES] portsUDP
byte[t_notify * MAX_TCP_NOTIFIES] portsTCP
byte[t_notify] portsUDP[MAX_UDP_NOTIFIES]
byte[t_notify] portsTCP[MAX_TCP_NOTIFIES]
//
// Service ICMP hook
//
@@ -379,12 +378,14 @@ end
// Open TCP socket in SERVER mode
//
def etherListenTCP(lclport, callback, param)
puts("TCP/IP not yet implented for this hardware.\n")
return 0
end
//
// Open TCP socket in CLIENT mode
//
def etherConnectTCP(remip, remport, lclport, callback, param)
puts("TCP/IP not yet implented for this hardware.\n")
return 0
end
//
@@ -500,7 +501,7 @@ def etherServiceIP
lclport = swab(rxptr=>udp_dst)
for i = 1 to MAX_UDP_NOTIFIES
if port=>notify_port == lclport
port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm)
port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len)-t_udphdr,port=>notify_parm)
break
fin
port = port + t_notify
@@ -586,7 +587,6 @@ def getEtherHA(ha)
if ha; memcpy(ha, @myMAC, MAC_SIZE); fin
return MAC_SIZE
end
//
// Fill in iNet class
//

View File

@@ -33,7 +33,7 @@ end
//
// External interface to net class. Must be first.
//
export byte[t_inet] iNet
res[t_inet] iNet
//
// List of loadable network device drivers
//
@@ -54,12 +54,6 @@ def iNetSetDNS(ipptr)
return 0
end
//def putb(hexb)
// return call($FDDA, hexb, 0, 0, 0)
//end
//def puth(hex)
// return call($F941, hex >> 8, hex, 0, 0)
//end
//def dumpbytes(buf, len)
// word i
//
@@ -87,14 +81,14 @@ def parseIP(ipstr, ipaddr)
endstr = ipstr + ^ipstr
for i = 0 to 3
ipstr = ipstr + 1
while ^ipstr >= '0' and ^ipstr <= '9' and ipstr <= endstr
ipaddr->[i] = ipaddr->[i] * 10 + ^ipstr - '0'
ipstr = ipstr + 1
loop
if ^ipstr <> '.' and ipstr < endstr
return 0
fin
while ^ipstr >= '0' and ^ipstr <= '9' and ipstr <= endstr
ipaddr->[i] = ipaddr->[i] * 10 + ^ipstr - '0'
ipstr = ipstr + 1
loop
if ^ipstr <> '.' and ipstr < endstr
return 0
fin
next
return i == 3
end
@@ -105,11 +99,11 @@ def parseDomain(domstr, msgptr)
l = 0
for i = 1 to ^domstr
if domstr->[i] == '.'
msgptr->[l] = i - l - 1
l = i
else
msgptr->[i] = domstr->[i]
fin
msgptr->[l] = i - l - 1
l = i
else
msgptr->[i] = domstr->[i]
fin
next
msgptr->[l] = i - l - 1
msgptr = msgptr + i
@@ -154,7 +148,7 @@ def recvDNS(remip, remport, pkt, len, ipaddr)
resptr = resptr + 8
//dumpbytes(resptr + 2, ^(resptr + 1))
resptr = resptr + 2 + ^(resptr + 1); putln
r = r - 1
r--
loop
fin
stateDNS = DNS_ANSWER
@@ -171,7 +165,7 @@ def iNetResolve(namestr, ipaddr)
//
// Query Domain Name Server for address
//
dnspkt = heapmark // Use heap as working DNS query packet
dnspkt = heapalloc(^namestr + t_dnshdr + 8) // Use heap as working DNS query packet
msgptr = dnspkt
msgptr=>dnsID = $BEEF
msgptr=>dnsCode = $0001 // RD (Recursion Desired)
@@ -181,9 +175,8 @@ def iNetResolve(namestr, ipaddr)
msgptr=>dnsArCount = 0
msgptr = parseDomain(namestr, msgptr + t_dnshdr)
msgptr=>0 = $0100 // BE TYPE = Address
msgptr=>2 = $0100 // BE CLASS = INternet
msgptr=>2 = $0100 // BE CLASS = Internet
msglen = msgptr - dnspkt + 4
heapalloc(msglen)
//
// Prepare to receive DNS answer from server
//
@@ -204,29 +197,27 @@ def iNetResolve(namestr, ipaddr)
fin
return ipaddr=>0 <> 0 or ipaddr=>2 <> 0
end
//
// Initialze network stack
//
def iNetInit
//
// Look for net hardware
//
while ^driver
//puts(driver);putln
if cmdsys:modexec(driver) >= 0
break
//
// Get an IP address
//
cmdsys:modexec("DHCP")
iNet:resolveIP = @iNetResolve
return @iNet
fin
driver = driver + ^driver + 1
loop
if !^driver
return 0
fin
//
// Get an IP address
//
cmdsys:modexec("DHCP")
iNet:resolveIP = @iNetResolve
return @iNet
puts("No network adapters found.\n")
return NULL
end
//
// Fill iNet class
//

682
src/libsrc/int32.pla Normal file
View File

@@ -0,0 +1,682 @@
//
// 32 bit integer math routines
//
include "inc/cmdsys.plh"
const t_i32 = 4
//
// Include zero page definitions
//
asm int32Inc
!SOURCE "vmsrc/plvmzp.inc"
ACCUM32 = DSTH+1
DVSIGN = TMP+3
end
export asm zero32#0
LDA #$00
STA ACCUM32+0
STA ACCUM32+1
STA ACCUM32+2
STA ACCUM32+3
RTS
end
export asm zext16to32#0
LDA #$00
STA ACCUM32+2
STA ACCUM32+3
RTS
end
export asm neg32#0
LDA #$00
SEC
SBC ACCUM32+0
STA ACCUM32+0
LDA #$00
SBC ACCUM32+1
STA ACCUM32+1
LDA #$00
SBC ACCUM32+2
STA ACCUM32+2
LDA #$00
SBC ACCUM32+3
STA ACCUM32+3
RTS
end
export asm load32(i32ptr)#0
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$00
LDA (TMP),Y
STA ACCUM32+0
INY
LDA (TMP),Y
STA ACCUM32+1
INY
LDA (TMP),Y
STA ACCUM32+2
INY
LDA (TMP),Y
STA ACCUM32+3
INX
RTS
end
export asm loadi16(imm16)#0
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA ACCUM32+0
LDA ESTKH+0,X ; IMM16H
STA ACCUM32+1
BPL + ; SIGN EXTEND
DEY
+ STY ACCUM32+2
STY ACCUM32+3
INX
RTS
end
export asm store32(i32ptr)#0
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$00
LDA ACCUM32+0
STA (TMP),Y
INY
LDA ACCUM32+1
STA (TMP),Y
INY
LDA ACCUM32+2
STA (TMP),Y
INY
LDA ACCUM32+3
STA (TMP),Y
INX
RTS
end
export asm add32(i32ptr)#0
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$00
LDA (TMP),Y
CLC
ADC ACCUM32+0
STA ACCUM32+0
INY
LDA (TMP),Y
ADC ACCUM32+1
STA ACCUM32+1
INY
LDA (TMP),Y
ADC ACCUM32+2
STA ACCUM32+2
INY
LDA (TMP),Y
ADC ACCUM32+3
STA ACCUM32+3
INX
RTS
end
export asm addi16(imm16)#0
LDY #$00
LDA ESTKL+0,X ; IMM16L
CLC
ADC ACCUM32+0
STA ACCUM32+0
LDA ESTKH+0,X ; IMM16H
BPL +
DEY
+ ADC ACCUM32+1
STA ACCUM32+1
TYA
ADC ACCUM32+2
STA ACCUM32+2
TYA
ADC ACCUM32+3
STA ACCUM32+3
INX
RTS
end
export asm sub32(i32ptr)#0
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
BMI _SUB
end
export asm subi16(imm16)#0
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
_SUB LDA ACCUM32+0
SEC
SBC SRC+0
STA ACCUM32+0
LDA ACCUM32+1
SBC SRC+1
STA ACCUM32+1
LDA ACCUM32+2
SBC SRC+2
STA ACCUM32+2
LDA ACCUM32+3
SBC SRC+3
STA ACCUM32+3
INX
RTS
end
export asm shl32(imm8)#0
LDA ESTKL+0,X ; IMM8
AND #$1F
CMP #16
BCC +
LDY ACCUM32+1
STY ACCUM32+3
LDY ACCUM32+0
STY ACCUM32+2
LDY #$00
STY ACCUM32+1
STY ACCUM32+0
SBC #16
+ CMP #8
BCC +
LDY ACCUM32+2
STY ACCUM32+3
LDY ACCUM32+1
STY ACCUM32+2
LDY ACCUM32+0
STY ACCUM32+1
LDY #$00
STY ACCUM32+0
SBC #8
+ TAY
BEQ ++
- ASL ACCUM32+0
ROL ACCUM32+1
ROL ACCUM32+2
ROL ACCUM32+3
DEY
BNE -
++ INX
RTS
end
export asm shr32(imm8)#0
LDA ESTKL+0,X ; IMM8
AND #$1F
BEQ +
TAY
LDA #$80
- CMP ACCUM32
ROR ACCUM32+3
ROR ACCUM32+2
ROR ACCUM32+1
ROR ACCUM32+0
DEY
BNE -
+ INX
RTS
end
export asm mul32(i32ptr)#0
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _MUL
end
export asm muli16(imm16)#0
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
LDY #$00
_MUL LDA ACCUM32+0
STA ESTKL-1,X
LDA ACCUM32+1
STA ESTKH-1,X
LDA ACCUM32+2
STA ESTKL+0,X
LDA ACCUM32+3
STA ESTKH+0,X
STY ACCUM32+0
STY ACCUM32+1
STY ACCUM32+2
STY ACCUM32+3
LDY #$03
LDA #$80
STA TMPL
- AND SRC,Y
BEQ +
CLC
LDA ESTKL-1,X
ADC ACCUM32+0
STA ACCUM32+0
LDA ESTKH-1,X
ADC ACCUM32+1
STA ACCUM32+1
LDA ESTKL+0,X
ADC ACCUM32+2
STA ACCUM32+2
LDA ESTKH+0,X
ADC ACCUM32+3
STA ACCUM32+3
+ LSR TMPL
BCC +
DEY
BMI ++
ROR TMPL
+ ASL ACCUM32+0
ROL ACCUM32+1
ROL ACCUM32+2
ROL ACCUM32+3
LDA TMPL
BNE -
++ INX
RTS
end
export asm div32(i32ptr)#2
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03 ; DVSR = SRC..SRC+3
LDA (TMP),Y
BMI +
STA SRC+3
DEY
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _DIV
+ SEC
- LDA #$00
SBC (TMP),Y
STA SRC,Y
DEY
BPL -
LDY #$01
BNE _DIV
end
export asm divi16(imm16)#2
LDY #$00 ; DVSR = SRC..SRC+3
STY SRC+2
STY SRC+3
LDA ESTKH+0,X ; IMM16H
BPL +
TYA ; DVSR IS NEG
SEC
SBC ESTKL+0,X ; IMM16L
STA SRC+0
TYA
SBC ESTKH+0,X ; IMM16L
STA SRC+1
INY
BNE _DIV
+ STA SRC+1
LDA ESTKL+0,X ; IMM16L
STA SRC+0
_DIV STY DVSIGN ; LSB = SIGN OF DVSR
DEX ; REMNDR = ESTK..ESTK+1
LDY #$00
STY ESTKL+0,X
STY ESTKH+0,X
STY ESTKL+1,X
STY ESTKH+1,X
LDA SRC+0 ; DIVIDE BY 0?
ORA SRC+1
ORA SRC+2
ORA SRC+3
BNE +
STA ACCUM32+0 ; SET TO 0 AND EXIT
STA ACCUM32+1
STA ACCUM32+2
STA ACCUM32+3
- RTS
+ LDA ACCUM32+0 ; DIVIDE 0?
ORA ACCUM32+1
ORA ACCUM32+2
ORA ACCUM32+3
BEQ -
LDA ACCUM32+3 ; DVDND = ACCUM32
BPL +
LDA #$81 ; DVDND IS NEG
CLC
ADC DVSIGN
STA DVSIGN
TYA
SEC
SBC ACCUM32+0
STA ACCUM32+0
TYA
SBC ACCUM32+1
STA ACCUM32+1
TYA
SBC ACCUM32+2
STA ACCUM32+2
TYA
SBC ACCUM32+3
STA ACCUM32+3
+ LDY #$21 ; #BITS+1
- ASL ACCUM32+0 ; SKIP DVDND LEADING 0 BITS
ROL ACCUM32+1
ROL ACCUM32+2
ROL ACCUM32+3
DEY
BCC -
- ROL ESTKL+0,X ; REMNDR
ROL ESTKH+0,X
ROL ESTKL+1,X
ROL ESTKH+1,X
LDA ESTKL+0,X ; REMNDR
CMP SRC+0 ; DVSR
LDA ESTKH+0,X ; COMPARE
SBC SRC+1
LDA ESTKL+1,X
SBC SRC+2
LDA ESTKH+1,X
SBC SRC+3
BCC + ; IS LESS THAN?
STA ESTKH+1,X
LDA ESTKL+0,X ; REMNDR
SBC SRC+0 ; DVSR
STA ESTKL+0,X ; SUBTRACT
LDA ESTKH+0,X
SBC SRC+1
STA ESTKH+0,X
LDA ESTKL+1,X
SBC SRC+2
STA ESTKL+1,X
SEC
+ ROL ACCUM32+0 ; DVDND
ROL ACCUM32+1 ; ROTATE IN RESULT
ROL ACCUM32+2
ROL ACCUM32+3
DEY
BNE -
LDA DVSIGN ; SET SIGNS OF RESULTS
BPL +
TYA
SEC
SBC ESTKL+0,X
STA ESTKL+0,X
TYA
SBC ESTKH+0,X
STA ESTKH+0,X
TYA
SBC ESTKL+1,X
STA ESTKL+1,X
TYA
SBC ESTKH+1,X
STA ESTKH+1,X
LDA DVSIGN
+ LSR
BCC +
TYA
SBC ACCUM32+0
STA ACCUM32+0
TYA
SBC ACCUM32+1
STA ACCUM32+1
TYA
SBC ACCUM32+2
STA ACCUM32+2
TYA
SBC ACCUM32+3
STA ACCUM32+3
+ RTS
end
export asm iseq32(i32ptr)#1
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _ISEQ
end
export asm iseqi16(imm16)#1
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
LDY #$00
_ISEQ LDA ACCUM32+0
CMP SRC+0
BNE +
LDA ACCUM32+1
CMP SRC+1
BNE +
LDA ACCUM32+2
CMP SRC+2
BNE +
LDA ACCUM32+3
CMP SRC+3
BNE +
DEY
+ STY ESTKL+0,X
STY ESTKH+0,X
RTS
end
export asm isge32(i32ptr)#1
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _ISGE
end
export asm isgei16(imm16)#1
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
LDY #$00
_ISGE LDA ACCUM32+0
CMP SRC+0
LDA ACCUM32+1
SBC SRC+1
LDA ACCUM32+2
SBC SRC+2
LDA ACCUM32+3
SBC SRC+3
BVC +
EOR #$80
+ BMI +
DEY
+ STY ESTKL+0,X
STY ESTKH+0,X
RTS
end
export asm isle32(i32ptr)#1
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _ISLE
end
export asm islei16(imm16)#1
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
LDY #$00
_ISLE LDA SRC+0
CMP ACCUM32+0
LDA SRC+1
SBC ACCUM32+1
LDA SRC+2
SBC ACCUM32+2
LDA SRC+3
SBC ACCUM32+3
BVC +
EOR #$80
+ BMI +
DEY
+ STY ESTKL+0,X
STY ESTKH+0,X
RTS
end
export asm isgt32(i32ptr)#1
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _ISGT
end
export asm isgti16(imm16)#1
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
LDY #$00
_ISGT LDA SRC+0
CMP ACCUM32+0
LDA SRC+1
SBC ACCUM32+1
LDA SRC+2
SBC ACCUM32+2
LDA SRC+3
SBC ACCUM32+3
BVC +
EOR #$80
+ BPL +
DEY
+ STY ESTKL+0,X
STY ESTKH+0,X
RTS
end
export asm islt32(i32ptr)#1
LDA ESTKL+0,X ; I32PTR
STA TMPL
LDA ESTKH+0,X ; I32PTR
STA TMPH
LDY #$03
- LDA (TMP),Y
STA SRC,Y
DEY
BPL -
INY
BEQ _ISLT
end
export asm islti16(imm16)#1
LDY #$00
LDA ESTKL+0,X ; IMM16L
STA SRC+0
LDA ESTKH+0,X ; IMM16H
STA SRC+1
BPL + ; SIGN EXTEND
DEY
+ STY SRC+2
STY SRC+3
LDY #$00
_ISLT LDA ACCUM32+0
CMP SRC+0
LDA ACCUM32+1
SBC SRC+1
LDA ACCUM32+2
SBC SRC+2
LDA ACCUM32+3
SBC SRC+3
BVC +
EOR #$80
+ BPL +
DEY
+ STY ESTKL+0,X
STY ESTKH+0,X
RTS
end
export def i32tos(i32ptr, strptr)#1
res[t_i32] save
word iptr, rem
char[12] istr
iptr = @istr.11
store32(@save)
load32(i32ptr)
if i32ptr->3 & $80
neg32()
putc('-')
fin
repeat
drop, rem = divi16(10) // Only care about LSW of remainder
^iptr = rem + '0'
iptr--
until iseqi16(0)
^iptr = @istr.11 - iptr
strcpy(strptr, iptr)
load32(@save)
return strptr
end
export def puti32(i32ptr)#0
char[12] i32str
puts(i32tos(i32ptr, @i32str))
end
done

1321
src/libsrc/jit16core.pla Normal file

File diff suppressed because it is too large Load Diff

1548
src/libsrc/jitcore.pla Normal file

File diff suppressed because it is too large Load Diff

494
src/libsrc/lines.pla Normal file
View File

@@ -0,0 +1,494 @@
include "inc/cmdsys.plh"
predef nopLin(a, b, c)#0
predef nopPix(a, b)#0
byte jmpplot = $4C // Sneaky!
var plot = @nopPix
var hspan = @nopLin
var vspan = @nopLin
var err, shorterr, shortlen, longerr, longlen
//def nopLin(a, b, c)#0
//end
//def majorline(majorstart, major, majorend, minor, dir, majorspan)#0
// //
// // Initial half-span step
// //
// err = err + shorterr
// repeat
// majorspan(majorstart, major, minor)#0
// minor = minor + dir // Move to next span
// majorstart = major + 1 // Start of next span = end of previous + 1
// if err >= 0 // Short span
// err = err + shorterr
// major = major + shortlen
// else // Long span
// err = err + longerr
// major = major + longlen
// fin
// until major >= majorend
// //
// // Final half-span step
// //
// majorspan(majorstart, majorend, minor)#0
//end
asm majorline(majorstart, major, majorend, minor, dir, majorspan)#0
!SOURCE "vmsrc/plvmzp.inc"
LDA $1000 ; ERRL
CLC
ADC $2000 ; SHORTERRL
STA $1000 ; ERRL
LDA $1001 ; ERRH
ADC $2001 ; SHORTERRH
STA $1001 ; ERRH
LDA ESTKL+0,X ; MAJORSPANL
STA $A000
STA $B000
LDA ESTKH+0,X ; MAJORSPANH
STA $A001
STA $B001
end
asm _majorlineA
- DEX
DEX
DEX
LDA ESTKL+8,X ; MAJORSTARTL
STA ESTKL+2,X
LDA ESTKH+8,X ; MAJORSTARTH
STA ESTKH+2,X
LDA ESTKL+7,X ; MAJORL
STA ESTKL+1,X
LDA ESTKH+7,X ; MAJORH
STA ESTKH+1,X
LDA ESTKL+5,X ; MINORL
STA ESTKL+0,X
LDA ESTKH+5,X ; MINORH
STA ESTKH+0,X
JSR $A000
LDA ESTKL+2,X ; MINORL
CLC
ADC ESTKL+1,X ; DIRL
STA ESTKL+2,X
LDA ESTKH+2,X ; MINORH
ADC ESTKH+1,X ; DIRH
STA ESTKH+2,X
LDA ESTKL+4,X ; MAJORL
CLC
ADC #$01
STA ESTKL+5,X ; MAJORSTARTL
LDA ESTKH+4,X ; MAJORH
ADC #$00
STA ESTKH+5,X ; MAJORSTARTH
end
asm _majorlineB
LDY $1001 ; ERRH
BMI +
end
asm _majorlineC
LDA $1000 ; ERRL
CLC
ADC $2000 ; SHORTERRL
STA $1000 ; ERRL
TYA ; ERRH
ADC $2001 ; SHORTERRH
STA $1001 ; ERRH
LDA ESTKL+4,X ; MAJORL
CLC
ADC $3000 ; SHORTLENL
STA ESTKL+4,X
LDA ESTKH+4,X ; MAJORH
ADC $3001 ; SHORTLENH
STA ESTKH+4,X
BCC ++
BCS ++
end
asm _majorlineD
+ LDA $1000 ; ERRL
CLC
ADC $4000 ; LONGERRL
STA $1000 ; ERRL
TYA ; ERRH
ADC $4001 ; LONGERRL
STA $1001 ; ERRH
LDA ESTKL+4,X ; MAJORL
CLC
ADC $5000 ; LONGLENL
STA ESTKL+4,X
LDA ESTKH+4,X ; MAJORH
ADC $5001 ; LONGLENH
STA ESTKH+4,X
++ LDA ESTKL+4,X ; MAJORL
CMP ESTKL+3,X ; MAJORENDL
LDA ESTKH+4,X ; MAJORH
SBC ESTKH+3,X ; MAJORENDH
BCS +
end
asm _majorlineE
JMP $6000
+ DEX
DEX
DEX
LDA ESTKL+8,X ; MAJORSTARTL
STA ESTKL+2,X
LDA ESTKH+8,X ; MAJORSTARTH
STA ESTKH+2,X
LDA ESTKL+6,X ; MAJORENDL
STA ESTKL+1,X
LDA ESTKH+6,X ; MAJORENDH
STA ESTKH+1,X
LDA ESTKL+5,X ; MINORL
STA ESTKL+0,X
LDA ESTKH+5,X ; MINORH
STA ESTKH+0,X
JSR $B000
TXA
CLC
ADC #$06
TAX
RTS
end
asm nopLin(a, b, c)#0
INX
end
asm nopPix(a, b)#0
INX
INX
RTS
end
//def hline(x1, x2, dx2, y, dy2, sy)#0
// var dyx2, x
//
// err = dy2 - dx2 / 2
// dyx2 = dy2 - dx2
// for x = x1 to x2
// plot(x, y)#0
// if err >= 0
// y = y + sy
// err = err + dyx2
// else
// err = err + dy2
// fin
// next
//end
asm hline(x1, x2, dx2, y, dy2, sy)#0
LDA ESTKH+3,X ; DX2H
LSR
STA TMPH
LDA ESTKL+3,X ; DX2L
ROR
STA TMPL
LDA ESTKL+1,X ; DY2L
SEC
SBC TMPL
STA $1000 ; ERRL
LDA ESTKH+1,X ; DY2H
SBC TMPH
STA $1001 ; ERRH
LDA ESTKL+1,X ; DY2L
SEC
SBC ESTKL+3,X ; DX2L
STA ESTKL+3,X ; DYX2L
LDA ESTKH+1,X ; DY2H
SBC ESTKH+3,X ; DX2H
STA ESTKH+3,X ; DYX2H
- DEX
DEX
LDA ESTKL+7,X ; XL
STA ESTKL+1,X
LDA ESTKH+7,X ; XH
STA ESTKH+1,X
LDA ESTKL+4,X ; YL
STA ESTKL+0,X
LDA ESTKH+4,X ; YH
STA ESTKH+0,X
end
asm _hlineA
JSR $2000 ; PLOT
LDA $1001 ; ERRH
BMI +
LDA ESTKL+2,X ; YL
CLC
ADC ESTKL+0,X ; SYL
STA ESTKL+2,X
LDA ESTKH+2,X ; YH
ADC ESTKH+0,X ; SYH
STA ESTKH+2,X
LDA ESTKL+3,X ; DYX2L
LDY ESTKH+3,X ; DYX2H
BEQ ++
BNE ++
end
asm _hlineB
+ LDA ESTKL+1,X ; DY2L
LDY ESTKH+1,X ; DY2H
++ CLC
ADC $1000 ; ERRL
STA $1000 ; ERRL
TYA
ADC $1001 ; ERRH
STA $1001 ; ERRH
LDA ESTKL+5,X ; X1L
CMP ESTKL+4,X ; X2L
LDA ESTKH+5,X
SBC ESTKH+4,X
BCS +
INC ESTKL+5,X ; XL
BNE -
INC ESTKH+5,X ; XH
BCC -
+ TXA
ADC #$05
TAX
RTS
end
//def vline(y1, y2, dy2, x, dx2, sx)#0
// var dxy2, y
//
// err = dx2 - dy2 / 2
// dxy2 = dx2 - dy2
// for y = y1 to y2
// plot(x, y)#0
// if err >= 0
// x = x + sx
// err = err + dxy2
// else
// err = err + dx2
// fin
// next
//end
asm vline(y1, y2, dy2, x, dx2, sx)#0
LDA ESTKH+3,X ; DY2H
LSR
STA TMPH
LDA ESTKL+3,X ; DY2L
ROR
STA TMPL
LDA ESTKL+1,X ; DX2L
SEC
SBC TMPL
STA $1000 ; ERRL
LDA ESTKH+1,X ; DX2H
SBC TMPH
STA $1001 ; ERRH
LDA ESTKL+1,X ; DX2L
SEC
SBC ESTKL+3,X ; DX2L
STA ESTKL+3,X ; DXY2L
LDA ESTKH+1,X ; DX2H
SBC ESTKH+3,X ; DY2H
STA ESTKH+3,X ; DXY2H
- DEX
DEX
LDA ESTKL+4,X ; XL
STA ESTKL+1,X
LDA ESTKH+4,X ; XH
STA ESTKH+1,X
LDA ESTKL+7,X ; YL
STA ESTKL+0,X
LDA ESTKH+7,X ; YH
STA ESTKH+0,X
end
asm _vlineA
JSR $2000 ; PLOT
LDA $1001 ; ERRH
BMI +
LDA ESTKL+2,X ; XL
CLC
ADC ESTKL+0,X ; SXL
STA ESTKL+2,X
LDA ESTKH+2,X ; XH
ADC ESTKH+0,X ; SXH
STA ESTKH+2,X
LDA ESTKL+3,X ; DXY2L
LDY ESTKH+3,X ; DXY2H
BEQ ++
BNE ++
end
asm _vlineB
+ LDA ESTKL+1,X ; DX2L
LDY ESTKH+1,X ; DX2H
++ CLC
ADC $1000 ; ERRL
STA $1000 ; ERRL
TYA
ADC $1001 ; ERRH
STA $1001 ; ERRH
LDA ESTKL+5,X ; Y1L
CMP ESTKL+4,X ; Y2L
LDA ESTKH+5,X
SBC ESTKH+4,X
BCS +
INC ESTKL+5,X ; YL
BNE -
INC ESTKH+5,X ; YH
BCC -
+ TXA
ADC #$05
TAX
RTS
end
export def setlinespans(h, v)#0
hspan = h
vspan = v
end
export def linespans(x1, y1, x2, y2)#0
var dx, dy, dx2, dy2, halflen, rem, sx, sy
sx = 1
sy = 1
dx = x2 - x1
if dx < 0
sx = -1; dx = -dx
fin
dy = y2 - y1
if dy < 0
sy = -1; dy = -dy
fin
if dx >= dy
if sx < 0
y1, y2 = y2, y1
x1, x2 = x2, x1
sy = -sy
fin
if dy == 0
hspan(x1, x2, y1)#0; return
fin
//
// Half-span length and error
//
dy2 = dy * 2
halflen, rem = divmod(dx, dy2)
err = dy2 - rem
//
// Long-span length = half-span length * 2
//
longlen = (halflen + 1) * 2
longerr = err * 2
if longerr >= dy2
longerr = longerr - dy2
longlen--
fin
//
// Short-span length = long-span length - 1
//
shortlen = longlen - 1
shorterr = longerr - dy2
//
// JIT optimize inner loop
//
majorline(x1, x1 + halflen, x2, y1, sy, hspan)
else
if sy < 0
x1, x2 = x2, x1
y1, y2 = y2, y1
sx = -sx
fin
if dx == 0
vspan(y1, y2, x1)#0; return
fin
//
// Half-span length and error
//
dx2 = dx * 2
halflen, rem = divmod(dy, dx2)
err = dx2 - rem
//
// Long-span length = half-span length * 2
//
longlen = (halflen + 1) * 2
longerr = err * 2
if longerr >= dx2
longerr = longerr - dx2
longlen--
fin
shortlen = longlen - 1
shorterr = longerr - dx2
//
// JIT optimize inner loop
//
majorline(y1, y1 + halflen, y2, x1, sx, vspan)
fin
end
export def setlineplot(p)#0
plot = p
end
export def line(x1, y1, x2, y2)#0
var sx, sy, dx2, dy2
sx = 1
sy = 1
dx2 = (x2 - x1) * 2
if dx2 < 0
sx = -1; dx2 = -dx2
fin
dy2 = (y2 - y1) * 2
if dy2 < 0
sy = -1; dy2 = -dy2
fin
if dx2 >= dy2
if sx < 0
x1, x2 = x2, x1
y1, y2 = y2, y1
sy = -sy
fin
hline(x1, x2, dx2, y1, dy2, sy)
else
if sy < 0
y1, y2 = y2, y1
x1, x2 = x2, x1
sx = -sx
fin
vline(y1, y2, dy2, x1, dx2, sx)
fin
end
//
// Assembly fixups
//
majorline:1 = @err
majorline:5 = @shorterr
majorline:8 = @err
majorline:11 = @err.1
majorline:14 = @shorterr.1
majorline:17 = @err.1
majorline:22 = @_majorlineA.28
majorline:25 = @_majorlineE.31
majorline:30 = @_majorlineA.29
majorline:33 = @_majorlineE.32
_majorlineB:1 = @err.1
_majorlineC:1 = @err
_majorlineC:5 = @shorterr
_majorlineC:8 = @err
_majorlineC:12 = @shorterr.1
_majorlineC:15 = @err.1
_majorlineC:21 = @shortlen
_majorlineC:28 = @shortlen.1
_majorlineD:1 = @err
_majorlineD:5 = @longerr
_majorlineD:8 = @err
_majorlineD:12 = @longerr.1
_majorlineD:15 = @err.1
_majorlineD:21 = @longlen
_majorlineD:28 = @longlen.1
_majorlineE:1 = @_majorlineA
hline:16 = @err
hline:23 = @err.1
_hlineA:1 = @jmpplot
_hlineA:4 = @err.1
_hlineB:6 = @err
_hlineB:9 = @err
_hlineB:13 = @err.1
_hlineB:16 = @err.1
vline:16 = @err
vline:23 = @err.1
_vlineA:1 = @jmpplot
_vlineA:4 = @err.1
_vlineB:6 = @err
_vlineB:9 = @err
_vlineB:13 = @err.1
_vlineB:16 = @err.1
done

91
src/libsrc/lz4.pla Normal file
View File

@@ -0,0 +1,91 @@
include "inc/cmdsys.plh"
asm incs
!SOURCE "vmsrc/plvmzp.inc"
end
//
// Always forward copy memory - important for overlapping match sequences
//
asm bcpy(dst, src, len)#0
INX
INX
INX
LDA ESTKL-3,X
ORA ESTKH-3,X
BEQ CPYEX
LDA ESTKL-1,X
STA DSTL
LDA ESTKH-1,X
STA DSTH
LDA ESTKL-2,X
STA SRCL
LDA ESTKH-2,X
STA SRCH
LDY ESTKL-3,X
BEQ CPYLP
INC ESTKH-3,X
LDY #$00
CPYLP LDA (SRC),Y
STA (DST),Y
INY
BNE +
INC DSTH
INC SRCH
+ DEC ESTKL-3,X
BNE CPYLP
DEC ESTKH-3,X
BNE CPYLP
CPYEX RTS
end
//
// Unpack LZ4 sequence into buffer, return unpacked length
//
export def lz4Unpack(seq, seqend, buff, buffend)
word data, len, match, i
byte token
data = buff
while isult(seq, seqend)
token = ^seq
seq++
len = token >> 4
if len
//
// Literal sequence
//
if len == 15
while ^seq == 255
len = len + 255
seq++
loop
len = len + ^seq
seq++
fin
if isuge(data + len, buffend); return 0; fin
bcpy(data, seq, len)
data = data + len
seq = seq + len
fin
len = token & $0F
if len or isult(seq, seqend)
//
// Match sequence
//
match = data - *seq
seq = seq + 2
len = len + 4
if len == 19 // $0F + 4
while ^seq == 255
len = len + 255
seq++
loop
len = len + ^seq
seq++
fin
if isuge(data + len, buffend); return 0; fin
bcpy(data, match, len)
data = data + len
fin
loop
return data - buff
end
done

View File

@@ -544,7 +544,7 @@ export def hmemNew(size)
//
// Allocate 3/4 of available heap on 128K machine, 1/2 on 64K machine
//
poolsize = ((@page - heapmark) >> 1) & $7FFF
poolsize = (heapavail >> 1) & $7FFF
if MACHID & $30 == $30
poolsize = poolsize + (poolsize >> 1)
fin
@@ -666,7 +666,7 @@ end
// !!! Does this work on Apple ///???
//
sysbuf = $0800 // heapallocalign(1024, 8, 0)
initdata = heapmark // Use data at top of heap for initialization
initdata = heapalloc(t_initdata) // Use data on heap for initialization
initdata=>volparms.0 = 2
initdata=>volparms.1 = 0
initdata=>volparms:2 = sysbuf
@@ -733,5 +733,6 @@ repeat
fin
until !initdata->filecnt
fileio:close(initdata->catref)
heaprelease(initdata)
//puts(@swapvol); putln
done

View File

@@ -734,19 +734,21 @@ def loadcode(codefile)
ref = fileio:open(strcat(strcpy(@filepath, cmdsys:syspath), codefile))
//puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln
if ref
pcode = heapmark
pcode = heapalloc(512)
fileio:read(ref, pcode, 512)
//puts("Read header bytes: "); puti(seglen)
//if seglen == 0; puts(" perr = "); prbyte(perr); fin
//getc; putln
//dumpheader(pcode)
//putname(pcode + segname + 8); putc('='); prword(pcode); putln
heaprelease(pcode + (pcode + t_diskinfo)=>codeaddr) // REserve heap to end of buffer
seglen = fileio:read(ref, pcode, (pcode + t_diskinfo)=>codeaddr)
//puts("Read segment bytes: "); puti(seglen); putln
fileio:close(ref)
if !fp6502 and (MACHID & $F0 == $B0) // 128K Apple //e or //c
seglen = fixup(AUXADDR, pcode + seglen - 2) - pcode
auxmove(AUXADDR, pcode, seglen)
heaprelease(pcode)
pcode = AUXADDR
else
heaprelease(fixup(pcode, pcode + seglen - 2)) // Set heap to beginning of relocation list

View File

@@ -1,993 +0,0 @@
//
// Wiznet 5100 based ethernet card
//
// TCP/IP is built into hardware, so no dependencies on the software
// layers, like the Uthernet
//
include "inc/cmdsys.plh"
//
// Net object
//
import inet
word iNet
end
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
word setCallback
word setParam
end
//
// Module don't free memory
//
const modkeep = $2000
const modinitkeep = $4000
//
// Wiznet registers
//
const WIZ_MR = $00
const WIZ_GWR = $01
const WIZ_SUBR = $05
const WIZ_SHAR = $09
const WIZ_SIPR = $0F
const WIZ_IR = $15
const WIZ_IMR = $16
const WIZ_RTR = $17
const WIZ_RCR = $19
const WIZ_RMSR = $1A
const WIZ_TMSR = $1B
const WIZ_PATR = $1C
const WIZ_PTMR = $28
const WIZ_PMGC = $29
const WIZ_UIPR = $2A
const WIZ_UPRT = $2E
//
// Wiznet socket registers
//
const WIZ_SREGS = $0400
const WIZ_SSIZE = $0100
const WIZ_SOCK0 = $0400
const WIZ_SOCK1 = $0500
const WIZ_SOCK2 = $0600
const WIZ_SOCK3 = $0700
const WIZ_SnMR = $00
const WIZ_SnCR = $01
const WIZ_SnIR = $02
const WIZ_SnSR = $03
const WIZ_SnPORT = $04
const WIZ_SnDHAR = $06
const WIZ_SnDIPR = $0C
const WIZ_SnDPORT = $10
const WIZ_SnMSSR = $12
const WIZ_SnPROTO = $14
const WIZ_SnTOS = $15
const WIZ_SnTTL = $16
const WIZ_SnFSR = $20
const WIZ_SnTXRD = $22
const WIZ_SnTXWR = $24
const WIZ_SnRSR = $26
const WIZ_SnRXRD = $28
//
// Wiznet socket data
//
const WIZ_TXMEM = $4000
const WIZ_TXSIZE = $0800
const WIZ_TXMASK = WIZ_TXSIZE-1
const WIZ_TXMEM0 = $4000
const WIZ_TXMEM1 = $4800
const WIZ_TXMEM2 = $5000
const WIZ_TXMEM3 = $5800
const WIZ_RXMEM = $6000
const WIZ_RXSIZE = $0800
const WIZ_RXMASK = WIZ_RXSIZE-1
const WIZ_RXMEM0 = $6000
const WIZ_RXMEM1 = $6800
const WIZ_RXMEM2 = $7000
const WIZ_RXMEM3 = $7800
//
// Wiznet indirect registers
//
byte regidx, regdata
word slot, saveidx
//
// Wiznet MAC address
//
byte[6] wizMAC = $00,$0A,$99,$1E,$02,$B0
//
// Wiznet IP addresses
//
byte[4] localip
byte[4] subnet
byte[4] gateway
//
// Predefine service routine
//
predef wizServiceIP
//
// Segment list element
//
struc t_segment
word seg_buf
word seg_len
end
//
// Max Ethernet frame size
//
const MAX_FRAME_SIZE = 1518
const MAC_BROADCAST = $FFFF
const MAC_SIZE = 6
//
// Ethernet header
//
struc t_ethrhdr
byte[MAC_SIZE] ethr_dst
byte[MAC_SIZE] ethr_src
word ethr_payload
end
const PAYLOAD_IP = $0008 // BE format
const PAYLOAD_ARP = $0608 // BE format
//
// IP datagram header
//
const IP4ADR_SIZE = 4
struc t_iphdr
byte ip_vers_hlen
byte ip_service
word ip_length
word ip_id
word ip_flags_fragofst
byte ip_ttl
byte ip_proto
word ip_chksm
byte[IP4ADR_SIZE] ip_src
byte[IP4ADR_SIZE] ip_dst
byte[] ip_options
end
const IP_BROADCAST = $FFFF
const IP_PROTO_ICMP = $01
const IP_PROTO_UDP = $11
const IP_PROTO_TCP = $06
word bcast = IP_BROADCAST, IP_BROADCAST
//
// ICMP type/codes
//
const IP_PROTO_ICMP = 1
const ICMP_ECHO_REQST = 8
const ICMP_ECHO_REPLY = 0
//
// ICMP message format
//
struc t_icmp
byte icmp_type
byte icmp_code
word icmp_chksm
word[2] icmp_header
end
//
// UDP IPv4 psuedo header
//
struc t_piphdr
byte[IP4ADR_SIZE] pip_src
byte[IP4ADR_SIZE] pip_dst
byte pip_zero
byte pip_proto
word pip_len
end
//
// UDP header
//
struc t_udphdr
word udp_src
word udp_dst
word udp_len
word udp_chksm
end
//
// TCP header
//
struc t_tcphdr
word tcp_src
word tcp_dst
word tcp_len
word tcp_chksm
end
//
// Local network parameters
//
const MAX_WIZ_CHANNELS = 4
//
// Channel protocols
//
const WIZ_PROTO_CLOSED = 0
const WIZ_PROTO_TCP = 1
const WIZ_PROTO_UDP = 2
const WIZ_PROTO_IP = 3
const WIZ_PROTO_RAW = 4
//
// State transistions
//
const TCP_STATE_CLOSED = 0
const TCP_STATE_CLOSING = 1
const TCP_STATE_LISTEN = 2
const TCP_STATE_CONNECT = 3
const TCP_STATE_OPEN = 4
//
// HW channels
//
struc t_channel
byte channel_proto
byte channel_state
word channel_regs
word channel_txmem
word channel_rxmem
word channel_lclport
word channel_remport
byte[4] channel_remip
word channel_recv_func
word channel_recv_parm
end
byte[t_channel * MAX_WIZ_CHANNELS] wizChannel
//
// Service ICMP hook
//
export word hookICMP
//
// Defines for ASM routines
//
asm equates
!SOURCE "vmsrc/plvmzp.inc"
end
//
// Swap bytes in word
//
asm swab
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
STY ESTKL,X
RTS
end
//
// Wiznet I/O functions
//
// POKE WORD TO I/O SPACE
// Note: Big Endian format
//
asm _pokeiow
LDA ESTKH,X
end
asm _pokeiowl
STA $C000
LDA ESTKL,X
end
asm _pokeiowh
STA $C000
RTS
end
//
// POKE BYTE TO I/O SPACE
//
asm _pokeio
LDA ESTKL,X
end
asm _pokeiol
STA $C000
RTS
end
//
// PEEK BYTE FROM I/O SPACE
//
asm _peekio
DEX
end
asm _peekiol
LDA $C000
STA ESTKL,X
LDA #$00
STA ESTKH,X
RTS
end
//
// PEEK WORD FROM I/O SPACE
// Note: Big Endian format
//
asm _peekiow
DEX
end
asm _peekiowl
LDA $C000
STA ESTKH,X
end
asm _peekiowh
LDA $C000
STA ESTKL,X
RTS
end
//
// WRITE DATA INTO I/O SPACE
// pokedata(BUF, LEN)
//
asm pokedata
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDY ESTKL,X
BEQ POKELP
LDY #$00
INC ESTKH,X
POKELP LDA (SRC),Y
end
asm _pokedata
STA $C000
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE POKELP
DEC ESTKH,X
BNE POKELP
INX
RTS
end
//
// READ DATA FROM I/O SPACE
// peekdata(BUF, LEN)
//
asm peekdata
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LDY ESTKL,X
BEQ PEEKLP
LDY #$00
INC ESTKH,X
end
asm _peekdata
PEEKLP LDA $C000
STA (DST),Y
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE PEEKLP
DEC ESTKH,X
BNE PEEKLP
INX
RTS
end
def pokeiow(io, data)
_pokeiowl.1 = io
_pokeiowh.1 = io+1
return _pokeiow(data)
end
def pokeio(io, data)
_pokeiol.1 = io
return _pokeio(data)
end
def peekio(io)
_peekiol.1 = io
return _peekio()
end
def peekiow(io)
_peekiowl.1 = io
_peekiowh.1 = io+1
return _peekiow()
end
def pokereg(reg, data)
_pokeiow(reg)
return _pokeio(data)
end
def peekreg(reg)
_pokeiow(reg)
return _peekio()
end
def pokeregs(reg, buf, len)
// _pokeiow(reg)
// return pokedata(buf, len)
word i
len = len - 1
for i = 0 to len
_pokeiow(reg + i)
_pokeio(buf->[i])
next
end
def peekregs(reg, buf, len)
// _pokeiow(reg)
// return peekdata(buf, len)
// There is an issue missing data on back-to-back reads
word i
len = len - 1
for i = 0 to len
_pokeiow(reg + i)
buf->[i] = _peekio()
next
end
def pokeregw(reg, dataw)
_pokeiow(reg)
_pokeio(dataw.1)
return _pokeio(dataw.0)
end
def peekregw(reg)
word dataw
_pokeiow(reg)
dataw.1 = _peekio()
_pokeiow(reg + 1)
dataw.0 = _peekio()
return dataw
end
//
// DEBUG
//
def putb(hexb)
return call($FDDA, hexb, 0, 0, 0)
end
def puth(hex)
return call($F941, hex >> 8, hex, 0, 0)
end
def putip(ipptr)
byte i
for i = 0 to 2
puti(ipptr->[i]); putc('.')
next
return puti(ipptr->[i])
end
//
// Send UDP datagram
//
def wizSendUDP(wiz, ipdst, portdst, data, len)
word wizregs, wizdata, txrr, txwr, splitlen
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_txmem
if !ipdst
ipdst = @bcast
fin
//
// Wait for Tx room
//
repeat; until peekregw(wizregs + WIZ_SnFSR) >= len
//
// Calc new write ptr, check for split
//
txwr = peekregw(wizregs + WIZ_SnTXWR)
txrr = txwr & WIZ_TXMASK
if txrr + len > WIZ_TXSIZE
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
else
pokeregs(wizdata + txrr, data, len)
fin
//
// Set destination address/port
//
pokeregs(wizregs + WIZ_SnDIPR, ipdst, IP4ADR_SIZE)
pokeregw(wizregs + WIZ_SnDPORT, portdst)
//
// Update write pointer and send
//
pokeregw(wizregs + WIZ_SnTXWR, txwr + len)
pokereg(wizregs + WIZ_SnCR, $20) // SEND
end
//
// Open UDP channel and set datagram received callback
//
def wizOpenUDP(localport, callback, param)
word wiz
byte i
if !localport; return -1; fin // invalid port
//
// Look for an existing notification on localport
//
//putc('O')
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == IP_PROTO_UDP and wiz=>channel_lclport == localport
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
//
// Add notification on localport if room
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if !wiz->channel_proto
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
return 0
fin
fin
//putc('0' + i);putln
//
// Fill in this channel and open it
//
wiz->channel_proto = WIZ_PROTO_UDP
wiz=>channel_lclport = localport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokeregw(wiz=>channel_regs + WIZ_SnPORT, localport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $02) // UDP protocol
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
return wiz
end
//
// Close UDP port
//
def wizCloseUDP(wiz)
//putc('S')
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_UDP
//putc('1' + ((wiz=>channel_regs - WIZ_SREGS) >> 8));putln
wiz->channel_proto = WIZ_PROTO_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
return 0
fin
fin
//putc('!');putln
//
// Invalid port
//
return -1
end
//
// Open TCP socket in SERVER mode
//
def wizListenTCP(lclport, callback, param)
word wiz
byte i
//
// Look for an existing notification on localport
//
//putc('L')
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == WIZ_PROTO_TCP and wiz->channel_state == TCP_STATE_LISTEN and wiz=>channel_lclport == lclport
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
//
// Add notification on localport if room
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if !wiz->channel_proto
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
return 0
fin
fin
//putc('0' + i);putln
//
// Fill in this channel and open it
//
wiz->channel_proto = WIZ_PROTO_TCP
wiz->channel_state = TCP_STATE_LISTEN
wiz=>channel_remip:0 = 0
wiz=>channel_remip:2 = 0
wiz=>channel_remport = 0
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
while peekreg(wiz=>channel_regs + WIZ_SnSR) <> $13; loop // Wait for init
pokereg(wiz=>channel_regs + WIZ_SnCR, $02) // LISTEN
return wiz
end
//
// Open TCP socket in CLIENT mode
//
def wizConnectTCP(remip, remport, lclport, callback, param)
word wiz
byte i
//
// Look for an existing notification on localport
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == WIZ_PROTO_TCP and wiz->channel_state == TCP_STATE_CONNECT and wiz=>channel_lclport == lclport
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
//
// Add notification on localport if room
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if !wiz->channel_proto
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
return 0
fin
fin
//
// Fill in this channel and open it
//
wiz->channel_proto = WIZ_PROTO_TCP
wiz->channel_state = TCP_STATE_CONNECT
wiz=>channel_remip:0 = remip=>0
wiz=>channel_remip:2 = remip=>2
wiz=>channel_remport = remport
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokeregs(wiz=>channel_regs + WIZ_SnDIPR, remip, IP4ADR_SIZE)
pokeregw(wiz=>channel_regs + WIZ_SnDPORT, remport)
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
while peekreg(wiz=>channel_regs + WIZ_SnSR) <> $13; loop // Wait for init
pokereg(wiz=>channel_regs + WIZ_SnCR, $04) // CONNECT
return wiz
end
//
// Write to TCP socket
//
def wizSendTCP(wiz, data, len)
word wizregs, wizdata, txrr, txwr, splitlen
if wiz->channel_state <> TCP_STATE_OPEN; return -1; fin
//putc('W');puti(len);putc(':')
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_txmem
//
// Wait for Tx room
//
repeat; until peekregw(wizregs + WIZ_SnFSR) >= len
//
// Calc new write ptr, check for split
//
txwr = peekregw(wizregs + WIZ_SnTXWR)
txrr = txwr & WIZ_TXMASK
if txrr + len > WIZ_TXSIZE
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
//putc('(');puti(splitlen);putc(',');puti(len-splitlen);putc(')')
else
pokeregs(wizdata + txrr, data, len)
fin
//puth(txrr);putc('-');putc('>');puth(txwr+len);putln
//
// Update write pointer and send
//
pokeregw(wizregs + WIZ_SnTXWR, txwr + len)
pokereg(wizregs + WIZ_SnCR, $20) // SEND
end
//
// Close TCP socket
//
def wizCloseTCP(wiz)
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_TCP and (wiz->channel_state == TCP_STATE_OPEN or wiz->channel_state == TCP_STATE_CLOSING)
wiz->channel_state = TCP_STATE_CLOSING
pokereg(wiz=>channel_regs + WIZ_SnCR, $08) // DISCON
repeat
wizServiceIP()
until wiz->channel_state == TCP_STATE_CLOSED
wiz->channel_proto = WIZ_PROTO_CLOSED
return 0
fin
fin
//
// Invalid port
//
return -1
end
//
// Update notify callback
//
def wizSetCallback(wiz, callback)
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
//
// Update callback on this port
//
wiz=>channel_recv_func = callback
return 0
fin
//
// Invalid port
//
return -1
end
//
// Update notify param
//
def wizSetParam(wiz, param)
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
//
// Update param on this port
//
wiz=>channel_recv_parm = param
return 0
fin
//
// Invalid port
//
return -1
end
//
// Service incoming packets
//
def wizServiceIP
word wiz, wizregs, wizdata, rxlen, rxrr, rxwr, rxpkt, splitlen
byte ir, i, sir
ir = peekreg(WIZ_IR)
if ir and ir <> $FF // Ignore spurious read of IR
//putc('I');putb(ir)
wiz = @wizChannel
for i = 0 to 3
when ir & (1 << i)
is 1
is 2
is 4
is 8
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_rxmem
sir = peekreg(wizregs + WIZ_SnIR)
when wiz->channel_proto
is WIZ_PROTO_TCP
if sir & $01
//putc('C')
//
// Connect TCP socket
//
when wiz->channel_state
is TCP_STATE_LISTEN
peekregs(wiz=>channel_regs + WIZ_SnDIPR, @wiz=>channel_remip, IP4ADR_SIZE)
wiz=>channel_remport = peekregw(wiz=>channel_regs + WIZ_SnDPORT)
is TCP_STATE_CONNECT
wiz->channel_state = TCP_STATE_OPEN
break
otherwise
//putc('?')
wend
fin
if sir & $04
//putc('R')
//
// Receive TCP packet
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
//puti(rxlen);putc(':')
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
//putc('(');puti(splitlen);putc(',');puti(rxlen-splitlen);putc(')')
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
//puth(rxwr);putc('-');putc('>');puth(rxwr+rxlen);putln
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
if sir & $02
//putc('S')
//
// Close TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
break
otherwise
//putc('?')
wend
fin
if sir & $08
//putc('T')
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
break
otherwise
//putc('?')
wend
fin
//if sir & $10
//putc('W');putc('O');putc('K');puth(peekregw(wiz=>channel_regs+WIZ_SnTXWR));putln
//
// Write TCP socket OK
//
//fin
break
is WIZ_PROTO_UDP
//putc('U');putb(sir)
if sir & $04
//putc('R')
//
// Receive UDP packet
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen >= WIZ_RXSIZE
//putc('!')
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
//putc('=');putip(rxpkt);putc(' ');puti(rxlen)
//putc('/');puti(swab(rxpkt=>6))
//putc(' ');puth(rxrr);putc(' ');puth(rxwr);putln
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(rxpkt,swab(rxpkt=>4),rxpkt+8,rxlen-8,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
break
otherwise
wend
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
ir = ir ^ (1 << i)
break
wend
wiz = wiz + t_channel
next
if ir
//
// Clear IR for now
//
pokereg(WIZ_IR, ir)
fin
fin
end
//
// Set the local IP addresses
//
def setWizIP(newIP, newSubnet, newGateway)
if newIP
localip:0 = newIP=>0; localip:2 = newIP=>2
pokeregs(WIZ_SIPR, newIP, IP4ADR_SIZE)
fin
if newSubnet
subnet:0 = newSubnet=>0; subnet:2 = newSubnet=>2
pokeregs(WIZ_SUBR, newSubnet, IP4ADR_SIZE)
fin
if newGateway
gateway:0 = newGateway=>0; gateway:2 = newGateway=>2
pokeregs(WIZ_GWR, newGateway, IP4ADR_SIZE)
fin
end
//
// Get the interface hardware address
//
def getWizHA(ha)
if ha
ha=>0 = wizMAC:0; ha=>2 = wizMAC:2; ha=>4 = wizMAC:4
fin
return MAC_SIZE
end
//
// Identify Wiznet card and initialize
//
for slot = $90 to $F0 step $10
regdata = peekio(slot)
if (regdata & $E4) == $00
pokeio(slot, $03) // Try setting auto-increment indirect I/F
if peekio(slot) == $03
saveidx = peekiow(slot + 1)
peekio(slot + 3) // Dummy read to data register should increment index
if peekiow(slot + 1) == saveidx + 1
//
// Good chance this is it
//
pokeio(slot, $80) // RESET
regidx = slot + 1
regdata = slot + 3
_pokedata.1 = regdata
_peekdata.1 = regdata
pokeio(slot, $03) // Auto-increment indirect I/F + enable ping
//
// The following looks redundant, but it sets up the peek/poke locations
// for peekreg(s)/pokereg(s)
//
pokeiow(regidx, WIZ_MR)
pokeio(regdata, $03) // Auto-increment indirect I/F + enable ping
peekio(regdata)
//
// Initialize common registers
//
pokeregs(WIZ_SHAR, @wizMAC, 6) // MAC addr
pokeregw(WIZ_RTR, 5000) // Timeout period to 500ms
pokereg(WIZ_RMSR, $55) // 2K Rx memory/channel
pokereg(WIZ_TMSR, $55) // 2K Tx memory/channel
//
// Fill channel structure
//
saveidx = @wizChannel
for slot = 0 to 3
saveidx=>channel_regs = WIZ_SREGS + (WIZ_SSIZE * slot)
saveidx=>channel_txmem = WIZ_TXMEM + (WIZ_TXSIZE * slot)
saveidx=>channel_rxmem = WIZ_RXMEM + (WIZ_RXSIZE * slot)
saveidx = saveidx + t_channel
next
//
// Fill in Net class
//
iNet:serviceIP = @wizServiceIP
iNet:openUDP = @wizOpenUDP
iNet:sendUDP = @wizSendUDP
iNet:closeUDP = @wizCloseUDP
iNet:listenTCP = @wizListenTCP
iNet:connectTCP = @wizConnectTCP
iNet:sendTCP = @wizSendTCP
iNet:closeTCP = @wizCloseTCP
iNet:setInterfaceIP = @setWizIP
iNet:getInterfaceHA = @getWizHA
iNet:setCallback = @wizSetCallback
iNet:setParam = @wizSetParam
return modkeep
fin
fin
pokeio(slot, regdata) // Restore register
fin
next
//
// Not found
//
return -1
done

View File

@@ -4,15 +4,30 @@ PLVM = plvm
PLVMZP_APL = vmsrc/apple/plvmzp.inc
PLVM01 = rel/apple/A1PLASMA\#060280
PLVM02 = rel/apple/PLASMA.SYSTEM\#FF2000
PLVM802 = rel/apple/PLASMA16.SYSTEM\#FF2000
PLVMJIT = rel/apple/PLVM.128\#FF2000
PLVM802 = rel/apple/PLVM16\#FF2000
PLVM03 = rel/apple/SOS.INTERP\#050000
PLVMJIT03 = rel/apple/SOS.INTERPJIT\#050000
SOSCMD = rel/apple/SOS.CMD\#FE1000
SOSCMDJIT = rel/apple/SOS.CMDJIT\#FE1000
CMD = rel/apple/CMD\#061000
CMDJIT = rel/apple/CMD128\#061000
PLVMZP_C64 = vmsrc/c64/plvmzp.inc
PLVMC64 = rel/c64/PLASMA
ED = rel/ED\#FE1000
JIT = rel/apple/JIT\#FE1000
JIT16 = rel/apple/JIT16\#FE1000
JITUNE = rel/apple/JITUNE\#FE1000
SOS = rel/apple/SOS\#FE1000
ROD = rel/ROD\#FE1000
ROD = rel/apple/ROD\#FE1000
COPY = rel/apple/COPY\#FE1000
DEL = rel/apple/DEL\#FE1000
REN = rel/apple/REN\#FE1000
CAT = rel/apple/CAT\#FE1000
NEWDIR = rel/apple/NEWDIR\#FE1000
TYPE = rel/apple/TYPE\#FE1000
SIEVE = rel/SIEVE\#FE1000
PRIMEGAP = rel/PRIMEGAP\#FE1000
ARGS = rel/ARGS\#FE1000
SPIPORT = rel/apple/SPIPORT\#FE1000
SDFAT = rel/apple/SDFAT\#FE1000
@@ -23,6 +38,8 @@ FATWDSK = rel/apple/FATWRITEDSK\#FE1000
FATRDSK = rel/apple/FATREADDSK\#FE1000
FILEIO_APL = rel/apple/FILEIO\#FE1000
CONIO_APL = rel/apple/CONIO\#FE1000
INT32 = rel/INT32\#FE1000
INT32TEST = rel/INT32TEST\#FE1000
SANE = rel/SANE\#FE1000
FPSTR = rel/FPSTR\#FE1000
FPU = rel/FPU\#FE1000
@@ -30,13 +47,21 @@ SNDSEQ = rel/apple/SNDSEQ\#FE1000
PLAYSEQ = rel/apple/PLAYSEQ\#FE1000
SANITY = rel/SANITY\#FE1000
RPNCALC = rel/RPNCALC\#FE1000
LZ4 = rel/LZ4\#FE1000
LZ4CAT = rel/LZ4CAT\#FE1000
MOUSE = rel/apple/MOUSE\#FE1000
UTHERNET2 = rel/apple/UTHERNET2\#FE1000
UTHERNET = rel/apple/UTHERNET\#FE1000
ETHERIP = rel/ETHERIP\#FE1000
INET = rel/INET\#FE1000
DHCP = rel/DHCP\#FE1000
HTTPD = rel/HTTPD\#FE1000
DGR = rel/apple/DGR\#FE1000
TFTPD = rel/TFTPD\#FE1000
HGRLIB = rel/apple/HGRLIB\#FE1000
GRLIB = rel/apple/GRLIB\#FE1000
DGRLIB = rel/apple/DGRLIB\#FE1000
HGRSPRITE = rel/apple/HGRSPRITE\#FE1000
LINES = rel/LINES\#FE1000
GRAFIX = rel/apple/GRAFIX\#FE1000
GFXDEMO = rel/apple/GFXDEMO\#FE1000
JOYBUZZ = rel/apple/JOYBUZZ\#FE1000
@@ -45,6 +70,8 @@ ROGUE = rel/ROGUE\#FE1000
ROGUEMAP = rel/ROGUEMAP\#FE1000
ROGUECOMBAT= rel/ROGUECOMBAT\#FE1000
MON = rel/apple/MON\#FE1000
HGRTEST = rel/apple/HGRTEST\#FE1000
GRTEST = rel/apple/GRTEST\#FE1000
DGRTEST = rel/apple/DGRTEST\#FE1000
MEMMGR = rel/MEMMGR\#FE1000
MEMTEST = rel/MEMTEST\#FE1000
@@ -75,7 +102,8 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(PLVMJIT03) $(CMD) $(CMDJIT) $(JIT) $(JIT17) $(JITUNE) $(SOSCMD) $(SOSCMDJIT) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(COPY) $(DEL) $(REN) $(CAT) $(NEWDIR) $(TYPE) $(SOS) $(ROD) $(SIEVE) $(PRIMEGAP) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(LINES) $(HGRSPRITE) $(HGRLIB) $(HGRTEST) $(GRLIB) $(DGRLIB) $(GRTEST) $(DGRTEST) $(HGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(INT32) $(INT32TEST) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
-rm vmsrc/plvmzp.inc
c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64)
@@ -84,10 +112,8 @@ c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64)
all: apple c64
clean:
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
-rm rel/*
-rm rel/apple/*
-rm rel/c64/*
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM03)
-rm -rf rel
-rm samplesrc/*.o samplesrc/*~ samplesrc/*.a
-rm toolsrc/*.o toolsrc/*~ toolsrc/*.a
-rm toolsrc/apple/*.o toolsrc/apple/*~ toolsrc/apple/*.a
@@ -98,7 +124,9 @@ clean:
-rm libsrc/*.o libsrc/*~ libsrc/*.a
-rm libsrc/apple/*.o libsrc/apple/*~ libsrc/apple/*.a
-rm libsrc/c64/*.o libsrc/c64/*~ libsrc/c64/*.a
-rm libsrc/*.o libsrc/*~ libsrc/*.a
-rm utilsrc/*.o utilsrc/*~ utilsrc/*.a
-rm utilsrc/apple/*.o utilsrc/apple/*~ utilsrc/apple/*.a
-rm utilsrc/c64/*.o utilsrc/c64/*~ utilsrc/c64/*.a
#
# PLASMA compiler: plasm
@@ -150,18 +178,38 @@ $(CMD): vmsrc/apple/cmd.pla vmsrc/apple/cmdstub.s $(PLVM02) $(PLASM)
./$(PLASM) -AOW < vmsrc/apple/cmd.pla > vmsrc/apple/cmd.a
acme --setpc 8192 -o $(CMD) vmsrc/apple/cmdstub.s
$(CMDJIT): vmsrc/apple/cmdjit.pla vmsrc/apple/cmdjitstub.s $(PLVMJIT) $(PLASM)
./$(PLASM) -AOW < vmsrc/apple/cmdjit.pla > vmsrc/apple/cmdjit.a
acme --setpc 8192 -o $(CMDJIT) vmsrc/apple/cmdjitstub.s
$(SOSCMD): vmsrc/apple/soscmd.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < vmsrc/apple/soscmd.pla > vmsrc/apple/soscmd.a
acme --setpc 4094 -o $(SOSCMD) vmsrc/apple/soscmd.a
$(SOSCMDJIT): vmsrc/apple/soscmdjit.pla libsrc/jitcore.pla $(PLVMJIT03) $(PLASM)
./$(PLASM) -AMOW < vmsrc/apple/soscmdjit.pla > vmsrc/apple/soscmdjit.a
acme --setpc 4094 -o $(SOSCMDJIT) vmsrc/apple/soscmdjit.a
$(PLVM02): vmsrc/apple/plvm02.s
acme -o $(PLVM02) -l vmsrc/apple/plvm02.sym vmsrc/apple/plvm02.s
$(PLVMJIT): vmsrc/apple/plvmjit02.s
acme -o $(PLVMJIT) -l vmsrc/apple/plvmjit02.sym vmsrc/apple/plvmjit02.s
$(PLVM802): vmsrc/apple/plvm802.s
acme -o $(PLVM802) -l vmsrc/apple/plvm802.sym vmsrc/apple/plvm802.s
vmsrc/apple/soscmd.a: vmsrc/apple/soscmd.pla $(PLASM)
./$(PLASM) -AOW < vmsrc/apple/soscmd.pla > vmsrc/apple/soscmd.a
vmsrc/apple/sossys.a: vmsrc/apple/sossys.pla $(PLASM)
./$(PLASM) -AOW < vmsrc/apple/sossys.pla > vmsrc/apple/sossys.a
$(PLVM03): vmsrc/apple/plvm03.s vmsrc/apple/soscmd.a
$(PLVM03): vmsrc/apple/plvm03.s vmsrc/apple/sossys.a
acme -o $(PLVM03) -l vmsrc/apple/plvm03.sym vmsrc/apple/plvm03.s
vmsrc/apple/sossysjit.a: vmsrc/apple/sossysjit.pla $(PLASM)
./$(PLASM) -AOW < vmsrc/apple/sossysjit.pla > vmsrc/apple/sossysjit.a
$(PLVMJIT03): vmsrc/apple/plvmjit03.s vmsrc/apple/sossysjit.a
acme -o $(PLVMJIT03) -l vmsrc/apple/plvmjit03.sym vmsrc/apple/plvmjit03.s
#
# Sample code
#
@@ -192,6 +240,10 @@ $(FIBER): libsrc/fiber.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/fiber.pla > libsrc/fiber.a
acme --setpc 4094 -o $(FIBER) libsrc/fiber.a
$(LINES): libsrc/lines.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/lines.pla > libsrc/lines.a
acme --setpc 4094 -o $(LINES) libsrc/lines.a
$(FIBERTEST): samplesrc/fibertest.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/fibertest.pla > samplesrc/fibertest.a
acme --setpc 4094 -o $(FIBERTEST) samplesrc/fibertest.a
@@ -217,13 +269,25 @@ hello: samplesrc/hello.pla $(PLVM) $(PLASM)
acme --setpc 4094 -o $(HELLO) samplesrc/hello.a
./$(PLVM) HELLO
$(ROD): samplesrc/rod.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMO < samplesrc/rod.pla > samplesrc/rod.a
./$(PLASM) -AMOW < samplesrc/rod.pla > samplesrc/rod.a
acme --setpc 4094 -o $(ROD) samplesrc/rod.a
$(SIEVE): samplesrc/sieve.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMW < samplesrc/sieve.pla > samplesrc/sieve.a
acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a
$(PRIMEGAP): samplesrc/primegap.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMW < samplesrc/primegap.pla > samplesrc/primegap.a
acme --setpc 4094 -o $(PRIMEGAP) samplesrc/primegap.a
$(INT32): libsrc/int32.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/int32.pla > libsrc/int32.a
acme --setpc 4094 -o $(INT32) libsrc/int32.a
$(INT32TEST): samplesrc/int32test.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/int32test.pla > samplesrc/int32test.a
acme --setpc 4094 -o $(INT32TEST) samplesrc/int32test.a
$(SANE): libsrc/sane.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/sane.pla > libsrc/sane.a
acme --setpc 4094 -o $(SANE) libsrc/sane.a
@@ -240,6 +304,14 @@ $(SANITY): samplesrc/sanity.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/sanity.pla > samplesrc/sanity.a
acme --setpc 4094 -o $(SANITY) samplesrc/sanity.a
$(LZ4): libsrc/lz4.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/lz4.pla > libsrc/lz4.a
acme --setpc 4094 -o $(LZ4) libsrc/lz4.a
$(LZ4CAT): samplesrc/lz4cat.pla inc/lz4.plh $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/lz4cat.pla > samplesrc/lz4cat.a
acme --setpc 4094 -o $(LZ4CAT) samplesrc/lz4cat.a
$(RPNCALC): samplesrc/rpncalc.pla libsrc/fpu.pla inc/fpu.plh libsrc/fpstr.pla inc/fpstr.plh inc/conio.plh $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/rpncalc.pla > samplesrc/rpncalc.a
acme --setpc 4094 -o $(RPNCALC) samplesrc/rpncalc.a
@@ -260,6 +332,14 @@ $(HTTPD): samplesrc/httpd.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/httpd.pla > samplesrc/httpd.a
acme --setpc 4094 -o $(HTTPD) samplesrc/httpd.a
$(TFTPD): utilsrc/tftpd.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < utilsrc/tftpd.pla > utilsrc/tftpd.a
acme --setpc 4094 -o $(TFTPD) utilsrc/tftpd.a
$(MOUSE): libsrc/apple/mouse.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/mouse.pla > libsrc/apple/mouse.a
acme --setpc 4094 -o $(MOUSE) libsrc/apple/mouse.a
$(UTHERNET): libsrc/apple/uthernet.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/uthernet.pla > libsrc/apple/uthernet.a
acme --setpc 4094 -o $(UTHERNET) libsrc/apple/uthernet.a
@@ -336,19 +416,76 @@ $(PORTIO): libsrc/apple/portio.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/portio.pla > libsrc/apple/portio.a
acme --setpc 4094 -o $(PORTIO) libsrc/apple/portio.a
$(DGR): libsrc/apple/dgr.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/dgr.pla > libsrc/apple/dgr.a
acme --setpc 4094 -o $(DGR) libsrc/apple/dgr.a
$(HGRLIB): libsrc/apple/hgrlib.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/hgrlib.pla > libsrc/apple/hgrlib.a
acme --setpc 4094 -o $(HGRLIB) libsrc/apple/hgrlib.a
$(GRLIB): libsrc/apple/grlib.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/grlib.pla > libsrc/apple/grlib.a
acme --setpc 4094 -o $(GRLIB) libsrc/apple/grlib.a
$(DGRLIB): libsrc/apple/dgrlib.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/dgrlib.pla > libsrc/apple/dgrlib.a
acme --setpc 4094 -o $(DGRLIB) libsrc/apple/dgrlib.a
$(HGRSPRITE): libsrc/apple/hgrsprite.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/hgrsprite.pla > libsrc/apple/hgrsprite.a
acme --setpc 4094 -o $(HGRSPRITE) libsrc/apple/hgrsprite.a
$(HGRTEST): samplesrc/hgrtest.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/hgrtest.pla > samplesrc/hgrtest.a
acme --setpc 4094 -o $(HGRTEST) samplesrc/hgrtest.a
$(GRTEST): samplesrc/grtest.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/grtest.pla > samplesrc/grtest.a
acme --setpc 4094 -o $(GRTEST) samplesrc/grtest.a
$(DGRTEST): samplesrc/dgrtest.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/dgrtest.pla > samplesrc/dgrtest.a
acme --setpc 4094 -o $(DGRTEST) samplesrc/dgrtest.a
$(MON): samplesrc/mon.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/mon.pla > samplesrc/mon.a
acme --setpc 4094 -o $(MON) samplesrc/mon.a
$(MON): utilsrc/apple/mon.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/mon.pla > utilsrc/apple/mon.a
acme --setpc 4094 -o $(MON) utilsrc/apple/mon.a
$(COPY): utilsrc/apple/copy.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/copy.pla > utilsrc/apple/copy.a
acme --setpc 4094 -o $(COPY) utilsrc/apple/copy.a
$(DEL): utilsrc/apple/del.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/del.pla > utilsrc/apple/del.a
acme --setpc 4094 -o $(DEL) utilsrc/apple/del.a
$(REN): utilsrc/apple/ren.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/ren.pla > utilsrc/apple/ren.a
acme --setpc 4094 -o $(REN) utilsrc/apple/ren.a
$(CAT): utilsrc/apple/cat.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/cat.pla > utilsrc/apple/cat.a
acme --setpc 4094 -o $(CAT) utilsrc/apple/cat.a
$(NEWDIR): utilsrc/apple/newdir.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/newdir.pla > utilsrc/apple/newdir.a
acme --setpc 4094 -o $(NEWDIR) utilsrc/apple/newdir.a
$(TYPE): utilsrc/apple/type.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/type.pla > utilsrc/apple/type.a
acme --setpc 4094 -o $(TYPE) utilsrc/apple/type.a
$(SOS): utilsrc/apple/sos.pla $(PLVM03) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/sos.pla > utilsrc/apple/sos.a
acme --setpc 4094 -o $(SOS) utilsrc/apple/sos.a
$(JIT): libsrc/apple/jit.pla libsrc/jitcore.pla $(PLVMJIT) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/jit.pla > libsrc/apple/jit.a
acme --setpc 4094 -o $(JIT) libsrc/apple/jit.a
$(JIT16): libsrc/apple/jit16.pla libsrc/jit16core.pla $(PLVMJIT) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/jit16.pla > libsrc/apple/jit16.a
acme --setpc 4094 -o $(JIT16) libsrc/apple/jit16.a
$(JITUNE): utilsrc/apple/jitune.pla $(PLVMJIT) $(PLASM)
./$(PLASM) -AMOW < utilsrc/apple/jitune.pla > utilsrc/apple/jitune.a
acme --setpc 4094 -o $(JITUNE) utilsrc/apple/jitune.a
$(SOS): libsrc/apple/sos.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMO < libsrc/apple/sos.pla > libsrc/apple/sos.a
acme --setpc 4094 -o $(SOS) libsrc/apple/sos.a

225
src/mkrel
View File

@@ -1,63 +1,105 @@
cp rel/apple/CMD#061000 prodos/CMD.BIN
cp rel/apple/CMD#061000 prodos/CMD.BIN
cp rel/apple/CMD128#061000 prodos/CMD128.BIN
cp rel/apple/PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS
cp rel/apple/PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS
cp rel/apple/SOS.INTERP#050000 prodos/SOS.INTERP.\$05
cp ../doc/Editor.md prodos/EDITOR.README.TXT
cp rel/apple/PLVM.128#FF2000 prodos/PLVM.128.SYS
cp rel/apple/PLVM16#FF2000 prodos/PLVM16.SYS
cp ../doc/Editor.md prodos/EDITOR.README.TXT
rm -rf prodos/sys
mkdir prodos/sys
cp rel/ARGS#FE1000 prodos/sys/ARGS.REL
cp rel/apple/CONIO#FE1000 prodos/sys/CONIO.REL
cp rel/apple/DGR#FE1000 prodos/sys/DGR.REL
cp rel/DHCP#FE1000 prodos/sys/DHCP.REL
cp rel/ED#FE1000 prodos/sys/ED.REL
cp rel/ETHERIP#FE1000 prodos/sys/ETHERIP.REL
cp rel/FIBER#FE1000 prodos/sys/FIBER.REL
cp rel/apple/FILEIO#FE1000 prodos/sys/FILEIO.REL
cp rel/FPSTR#FE1000 prodos/sys/FPSTR.REL
cp rel/FPU#FE1000 prodos/sys/FPU.REL
cp rel/INET#FE1000 prodos/sys/INET.REL
cp rel/LONGJMP#FE1000 prodos/sys/LONGJMP.REL
cp rel/MEMMGR#FE1000 prodos/sys/MEMMGR.REL
cp rel/apple/PORTIO#FE1000 prodos/sys/PORTIO.REL
cp rel/apple/JOYBUZZ#FE1000 prodos/sys/JOYBUZZ.REL
cp rel/SANE#FE1000 prodos/sys/SANE.REL
cp rel/apple/SDFAT#FE1000 prodos/sys/SDFAT.REL
cp rel/apple/SPIPORT#FE1000 prodos/sys/SPIPORT.REL
cp rel/apple/SNDSEQ#FE1000 prodos/sys/SNDSEQ.REL
cp rel/apple/UTHERNET#FE1000 prodos/sys/UTHERNET.REL
cp rel/apple/UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL
cp rel/apple/SOS#FE1000 prodos/sys/SOS.REL
cp rel/apple/GRAFIX#FE1000 prodos/sys/GRAFIX.REL
cp rel/apple/FILEIO#FE1000 prodos/sys/FILEIO.REL
cp rel/apple/CONIO#FE1000 prodos/sys/CONIO.REL
cp rel/LINES#FE1000 prodos/sys/LINES.REL
cp rel/apple/HGRSPRITE#FE1000 prodos/sys/HGRSPRITE.REL
cp rel/apple/HGRLIB#FE1000 prodos/sys/HGRLIB.REL
cp rel/apple/GRLIB#FE1000 prodos/sys/GRLIB.REL
cp rel/apple/DGRLIB#FE1000 prodos/sys/DGRLIB.REL
cp rel/apple/COPY#FE1000 prodos/sys/COPY.REL
cp rel/apple/DEL#FE1000 prodos/sys/DEL.REL
cp rel/apple/REN#FE1000 prodos/sys/REN.REL
cp rel/apple/CAT#FE1000 prodos/sys/CAT.REL
cp rel/apple/NEWDIR#FE1000 prodos/sys/NEWDIR.REL
cp rel/apple/TYPE#FE1000 prodos/sys/TYPE.REL
cp rel/ARGS#FE1000 prodos/sys/ARGS.REL
cp rel/ED#FE1000 prodos/sys/ED.REL
cp rel/FIBER#FE1000 prodos/sys/FIBER.REL
cp rel/LONGJMP#FE1000 prodos/sys/LONGJMP.REL
cp rel/MEMMGR#FE1000 prodos/sys/MEMMGR.REL
cp rel/INET#FE1000 prodos/sys/INET.REL
cp rel/DHCP#FE1000 prodos/sys/DHCP.REL
cp rel/ETHERIP#FE1000 prodos/sys/ETHERIP.REL
cp rel/apple/MOUSE#FE1000 prodos/sys/MOUSE.REL
cp rel/apple/UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL
cp rel/apple/UTHERNET#FE1000 prodos/sys/UTHERNET.REL
cp rel/apple/PORTIO#FE1000 prodos/sys/PORTIO.REL
cp rel/apple/JOYBUZZ#FE1000 prodos/sys/JOYBUZZ.REL
cp rel/apple/SNDSEQ#FE1000 prodos/sys/SNDSEQ.REL
cp rel/apple/JIT#FE1000 prodos/sys/JIT.REL
cp rel/apple/JIT16#FE1000 prodos/sys/JIT16.REL
cp rel/apple/JITUNE#FE1000 prodos/sys/JITUNE.REL
cp rel/LZ4#FE1000 prodos/sys/LZ4.REL
cp rel/TFTPD#FE1000 prodos/sys/TFTPD.REL
cp rel/INT32#FE1000 prodos/sys/INT32.REL
cp rel/FPSTR#FE1000 prodos/sys/FPSTR.REL
cp rel/FPU#FE1000 prodos/sys/FPU.REL
cp rel/SANE#FE1000 prodos/sys/SANE.REL
cp ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN
cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN
cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN
cp rel/apple/SOS#FE1000 prodos/sys/SOS.REL
cp rel/apple/GRAFIX#FE1000 prodos/sys/GRAFIX.REL
rm -rf prodos/fpsos
mkdir prodos/fpsos
cp ../sysfiles/SOS.KERNEL#0C0000 prodos/fpsos/SOS.KERNEL.\$0C
cp ../sysfiles/SOS.DRIVER#0C0000 prodos/fpsos/SOS.DRIVER.\$0C
cp rel/apple/SOS.INTERP#050000 prodos/fpsos/SOS.INTERP.\$05
cp rel/apple/SOS.CMD#FE1000 prodos/fpsos/SOS.CMD.REL
cp rel/apple/SOS.INTERPJIT#050000 prodos/fpsos/SOS.INTERPJIT.\$05
cp rel/apple/SOS.CMDJIT#FE1000 prodos/fpsos/SOS.CMDJIT.REL
mkdir prodos/fpsos/sys
cp rel/apple/SOS#FE1000 prodos/fpsos/sys/SOS.REL
cp rel/apple/GRAFIX#FE1000 prodos/fpsos/sys/GRAFIX.REL
cp rel/FPSTR#FE1000 prodos/fpsos/sys/FPSTR.REL
cp rel/FPU#FE1000 prodos/fpsos/sys/FPU.REL
cp rel/SANE#FE1000 prodos/fpsos/sys/SANE.REL
cp ../sysfiles/FP6502.CODE#060000 prodos/fpsos/sys/FP6502.CODE.BIN
cp ../sysfiles/ELEMS.CODE#060000 prodos/fpsos/sys/ELEMS.CODE.BIN
rm -rf prodos/demos
mkdir prodos/demos
cp rel/INT32TEST#FE1000 prodos/demos/INT32TEST.REL
cp rel/apple/HGRTEST#FE1000 prodos/demos/HGRTEST.REL
cp rel/apple/GRTEST#FE1000 prodos/demos/GRTEST.REL
cp rel/apple/DGRTEST#FE1000 prodos/demos/DGRTEST.REL
cp rel/RPNCALC#FE1000 prodos/demos/RPNCALC.REL
cp rel/ROD#FE1000 prodos/demos/ROD.REL
cp rel/apple/HGRTEST#FE1000 prodos/demos/HGRTEST.REL
cp rel/apple/ROD#FE1000 prodos/demos/ROD.REL
cp rel/RPNCALC#FE1000 prodos/demos/RPNCALC.REL
cp rel/LZ4CAT#FE1000 prodos/demos/LZ4CAT.REL
cp rel/PRIMEGAP#FE1000 prodos/demos/PRIMEGAP.REL
mkdir prodos/demos/rogue
cp rel/ROGUE#FE1000 prodos/demos/rogue/ROGUE.REL
cp rel/ROGUECOMBAT#FE1000 prodos/demos/rogue/ROGUECOMBAT.REL
cp rel/ROGUEMAP#FE1000 prodos/demos/rogue/ROGUEMAP.REL
cp rel/ROGUE#FE1000 prodos/demos/rogue/ROGUE.REL
cp rel/ROGUECOMBAT#FE1000 prodos/demos/rogue/ROGUECOMBAT.REL
cp rel/ROGUEMAP#FE1000 prodos/demos/rogue/ROGUEMAP.REL
cp samplesrc/LEVEL0#040000 prodos/demos/rogue/LEVEL0.TXT
cp samplesrc/LEVEL1#040000 prodos/demos/rogue/LEVEL1.TXT
mkdir prodos/demos/sdutils
cp rel/apple/FATCAT#FE1000 prodos/demos/sdutils/FATCAT.REL
cp rel/apple/FATGET#FE1000 prodos/demos/sdutils/FATGET.REL
cp rel/apple/FATPUT#FE1000 prodos/demos/sdutils/FATPUT.REL
cp rel/apple/FATREADDSK#FE1000 prodos/demos/sdutils/FATREADDSK.REL
cp rel/apple/SPIPORT#FE1000 prodos/demos/sdutils/SPIPORT.REL
cp rel/apple/SDFAT#FE1000 prodos/demos/sdutils/SDFAT.REL
cp rel/apple/FATCAT#FE1000 prodos/demos/sdutils/FATCAT.REL
cp rel/apple/FATGET#FE1000 prodos/demos/sdutils/FATGET.REL
cp rel/apple/FATPUT#FE1000 prodos/demos/sdutils/FATPUT.REL
cp rel/apple/FATREADDSK#FE1000 prodos/demos/sdutils/FATREADDSK.REL
cp rel/apple/FATWRITEDSK#FE1000 prodos/demos/sdutils/FATWRITEDSK.REL
mkdir prodos/demos/apple3
cp rel/apple/GFXDEMO#FE1000 prodos/demos/apple3/GFXDEMO.REL
cp rel/apple/GFXDEMO#FE1000 prodos/demos/apple3/GFXDEMO.REL
cp samplesrc/APPLE3.PIX#060000 prodos/demos/apple3/APPLE3.PIX.BIN
mkdir prodos/demos/net
cp rel/HTTPD#FE1000 prodos/demos/net/HTTPD.REL
cp rel/HTTPD#FE1000 prodos/demos/net/HTTPD.REL
cp samplesrc/index.html prodos/demos/net/INDEX.HTML.TXT
mkdir prodos/demos/music
@@ -67,45 +109,72 @@ cp mockingboard/startrek.seq prodos/demos/music/STARTREK.SEQ.BIN
rm -rf prodos/bld
mkdir prodos/bld
cp rel/PLASM#FE1000 prodos/bld/PLASM.REL
cp rel/CODEOPT#FE1000 prodos/bld/CODEOPT.REL
cp samplesrc/dgrtest.pla prodos/bld/DGRTEST.PLA.TXT
cp samplesrc/hello.pla prodos/bld/HELLO.PLA.TXT
cp samplesrc/hgr1test.pla prodos/bld/HGR1TEST.PLA.TXT
cp samplesrc/fibertest.pla prodos/bld/FIBERTEST.PLA.TXT
cp samplesrc/mon.pla prodos/bld/MON.PLA.TXT
cp samplesrc/memtest.pla prodos/bld/MEMTEST.PLA.TXT
cp samplesrc/rod.pla prodos/bld/ROD.PLA.TXT
cp samplesrc/sieve.pla prodos/bld/SIEVE.PLA.TXT
cp samplesrc/test.pla prodos/bld/TEST.PLA.TXT
cp samplesrc/testlib.pla prodos/bld/TESTLIB.PLA.TXT
cp samplesrc/playseq.pla prodos/bld/PLAYSEQ.PLA.TXT
cp samplesrc/rpncalc.pla prodos/bld/RPNCALC.PLA.TXT
cp samplesrc/httpd.pla prodos/bld/HTTPD.PLA.TXT
cp samplesrc/fatcat.pla prodos/bld/FATCAT.PLA.TXT
cp samplesrc/rogue.pla prodos/bld/ROGUE.PLA.TXT
cp samplesrc/rogue.map.pla prodos/bld/ROGUE.MAP.PLA.TXT
cp samplesrc/rogue.combat.pla prodos/bld/ROGUE.COMBAT.PLA.TXT
cp samplesrc/gfxdemo.pla prodos/bld/GFXDEMO.PLA.TXT
cp rel/PLASM#FE1000 prodos/bld/PLASM.REL
cp rel/CODEOPT#FE1000 prodos/bld/CODEOPT.REL
mkdir prodos/bld/samples
cp samplesrc/hello.pla prodos/bld/samples/HELLO.PLA.TXT
cp samplesrc/int32test.pla prodos/bld/samples/INT32TEST.PLA.TXT
cp samplesrc/grtest.pla prodos/bld/samples/GRTEST.PLA.TXT
cp samplesrc/dgrtest.pla prodos/bld/samples/DGRTEST.PLA.TXT
cp samplesrc/hgrtest.pla prodos/bld/samples/HGRTEST.PLA.TXT
cp samplesrc/fibertest.pla prodos/bld/samples/FIBERTEST.PLA.TXT
cp samplesrc/mousetest.pla prodos/bld/samples/MOUSETEST.PLA.TXT
cp samplesrc/memtest.pla prodos/bld/samples/MEMTEST.PLA.TXT
cp samplesrc/rod.pla prodos/bld/samples/ROD.PLA.TXT
cp samplesrc/sieve.pla prodos/bld/samples/SIEVE.PLA.TXT
cp samplesrc/test.pla prodos/bld/samples/TEST.PLA.TXT
cp samplesrc/testlib.pla prodos/bld/samples/TESTLIB.PLA.TXT
cp samplesrc/playseq.pla prodos/bld/samples/PLAYSEQ.PLA.TXT
cp samplesrc/rpncalc.pla prodos/bld/samples/RPNCALC.PLA.TXT
cp samplesrc/fatcat.pla prodos/bld/samples/FATCAT.PLA.TXT
cp samplesrc/gfxdemo.pla prodos/bld/samples/GFXDEMO.PLA.TXT
cp samplesrc/lz4cat.pla prodos/bld/samples/Z4CAT.PLA.TXT
#mkdir prodos/bld/examples
#cp samplesrc/examples/ex.1.pla prodos/bld/examples/EX.1.PLA.TXT
#cp samplesrc/examples/ex.2.pla prodos/bld/examples/EX.2.PLA.TXT
#cp samplesrc/examples/ex.3.pla prodos/bld/examples/EX.3.PLA.TXT
#cp samplesrc/examples/ex.4.pla prodos/bld/examples/EX.4.PLA.TXT
#cp samplesrc/examples/ex.5.pla prodos/bld/examples/EX.5.PLA.TXT
#cp samplesrc/examples/ex.6.pla prodos/bld/examples/EX.6.PLA.TXT
#cp samplesrc/examples/ex.7.pla prodos/bld/examples/EX.7.PLA.TXT
#cp samplesrc/examples/ex.8.pla prodos/bld/examples/EX.8.PLA.TXT
#cp samplesrc/examples/ex.9.pla prodos/bld/examples/EX.9.PLA.TXT
#cp samplesrc/examples/ex.10.pla prodos/bld/examples/EX.10.PLA.TXT
#cp samplesrc/examples/ex.11.pla prodos/bld/examples/EX.11.PLA.TXT
#cp samplesrc/examples/ex.12.pla prodos/bld/examples/EX.12.PLA.TXT
#cp samplesrc/examples/ex.13.pla prodos/bld/examples/EX.13.PLA.TXT
#cp samplesrc/examples/ex.14.pla prodos/bld/examples/EX.14.PLA.TXT
#cp samplesrc/examples/ex.15.pla prodos/bld/examples/EX.15.PLA.TXT
#cp samplesrc/examples/ex.16.pla prodos/bld/examples/EX.16.PLA.TXT
#cp samplesrc/examples/ex.17.pla prodos/bld/examples/EX.17.PLA.TXT
mkdir prodos/bld/inc
cp inc/args.plh prodos/bld/inc/ARGS.PLH.TXT
cp inc/cmdsys.plh prodos/bld/inc/CMDSYS.PLH.TXT
cp inc/conio.plh prodos/bld/inc/CONIO.PLH.TXT
cp inc/dgr.plh prodos/bld/inc/DGR.PLH.TXT
cp inc/fiber.plh prodos/bld/inc/FIBER.PLH.TXT
cp inc/fileio.plh prodos/bld/inc/FILEIO.PLH.TXT
cp inc/fpstr.plh prodos/bld/inc/FPSTR.PLH.TXT
cp inc/fpu.plh prodos/bld/inc/FPU.PLH.TXT
cp inc/inet.plh prodos/bld/inc/INET.PLH.TXT
cp inc/longjmp.plh prodos/bld/inc/LONGJMP.PLH.TXT
cp inc/memmgr.plh prodos/bld/inc/MEMMGR.PLH.TXT
cp inc/sane.plh prodos/bld/inc/SANE.PLH.TXT
cp inc/joybuzz.plh prodos/bld/inc/JOYBUZZ.PLH.TXT
cp inc/portio.plh prodos/bld/inc/PORTIO.PLH.TXT
cp inc/sdfat.plh prodos/bld/inc/SDFAT.PLH.TXT
cp inc/sndseq.plh prodos/bld/inc/SNDSEQ.PLH.TXT
cp inc/spiport.plh prodos/bld/inc/SPIPORT.PLH.TXT
cp inc/testlib.plh prodos/bld/inc/TESTLIB.PLH.TXT
cp inc/grafix.plh prodos/bld/inc/GRAFIX.PLH.TXT
cp inc/args.plh prodos/bld/inc/ARGS.PLH.TXT
cp inc/cmdsys.plh prodos/bld/inc/CMDSYS.PLH.TXT
cp inc/conio.plh prodos/bld/inc/CONIO.PLH.TXT
cp inc/lines.plh prodos/bld/inc/LINES.PLH.TXT
cp inc/hgrsprite.plh prodos/bld/inc/HGRSPRITE.PLH.TXT
cp inc/hgrlib.plh prodos/bld/inc/HGRLIB.PLH.TXT
cp inc/grlib.plh prodos/bld/inc/GRLIB.PLH.TXT
cp inc/dgrlib.plh prodos/bld/inc/DGRLIB.PLH.TXT
cp inc/fiber.plh prodos/bld/inc/FIBER.PLH.TXT
cp inc/fileio.plh prodos/bld/inc/FILEIO.PLH.TXT
cp inc/int32.plh prodos/bld/inc/INT32.PLH.TXT
cp inc/fpstr.plh prodos/bld/inc/FPSTR.PLH.TXT
cp inc/fpu.plh prodos/bld/inc/FPU.PLH.TXT
cp inc/mouse.plh prodos/bld/inc/MOUSE.PLH.TXT
cp inc/inet.plh prodos/bld/inc/INET.PLH.TXT
cp inc/longjmp.plh prodos/bld/inc/LONGJMP.PLH.TXT
cp inc/memmgr.plh prodos/bld/inc/MEMMGR.PLH.TXT
cp inc/sane.plh prodos/bld/inc/SANE.PLH.TXT
cp inc/joybuzz.plh prodos/bld/inc/JOYBUZZ.PLH.TXT
cp inc/portio.plh prodos/bld/inc/PORTIO.PLH.TXT
cp inc/sdfat.plh prodos/bld/inc/SDFAT.PLH.TXT
cp inc/sndseq.plh prodos/bld/inc/SNDSEQ.PLH.TXT
cp inc/spiport.plh prodos/bld/inc/SPIPORT.PLH.TXT
cp inc/testlib.plh prodos/bld/inc/TESTLIB.PLH.TXT
cp inc/grafix.plh prodos/bld/inc/GRAFIX.PLH.TXT
cp inc/lz4.plh prodos/bld/inc/LZ4.PLH.TXT
cp vmsrc/apple/plvmzp.inc prodos/bld/inc/PLVMZP.INC.TXT

82
src/opstat Executable file
View File

@@ -0,0 +1,82 @@
echo -n "CN "; grep -c '; CN' $1
echo -n "MINUS1 "; grep -c '; MINUS' $1
echo -n "BREQ "; grep -c '; BREQ' $1
echo -n "BRNE "; grep -c '; BRNE' $1
echo -n "LA "; grep -c '; LA' $1
echo -n "LLA "; grep -c '; LLA' $1
echo -n "CB "; grep -c '; CB' $1
echo -n "CW "; grep -c '; CW' $1
echo -n "CS "; grep -c '; CS' $1
echo -n "DROP "; grep -c '; DROP ' $1
echo -n "DROP2 "; grep -c '; DROP2' $1
echo -n "DUP "; grep -c '; DUP' $1
echo -n "DIVMOD "; grep -c '; DIVMOD' $1
echo -n "ADDI "; grep -c '; ADDI' $1
echo -n "SUBI "; grep -c '; SUBI' $1
echo -n "ANDI "; grep -c '; ANDI' $1
echo -n "ORI "; grep -c '; ORI' $1
echo -n "ISEQ "; grep -c '; ISEQ' $1
echo -n "ISNE "; grep -c '; ISNE' $1
echo -n "ISGT "; grep -c '; ISGT' $1
echo -n "ISLT "; grep -c '; ISLT' $1
echo -n "ISGE "; grep -c '; ISGE' $1
echo -n "ISLE "; grep -c '; ISLE' $1
echo -n "BRFLS "; grep -c '; BRFLS' $1
echo -n "BRTRU "; grep -c '; BRTRU' $1
echo -n "BRNCH "; grep -c '; BRNCH' $1
echo -n "SEL "; grep -c '; SEL' $1
echo -n "CALL "; grep -c '; CALL' $1
echo -n "ICAL "; grep -c '; ICAL' $1
echo -n "ENTER "; grep -c '; ENTER' $1
echo -n "LEAVE "; grep -c '; LEAVE' $1
echo -n "RET "; grep -c '; RET' $1
echo -n "CFFB "; grep -c '; CFFB' $1
echo -n "LB "; grep -c '; LB' $1
echo -n "LW "; grep -c '; LW' $1
echo -n "LLB "; grep -c '; LLB' $1
echo -n "LLW "; grep -c '; LLW' $1
echo -n "LAB "; grep -c '; LAB' $1
echo -n "LAW "; grep -c '; LAW' $1
echo -n "DLB "; grep -c '; DLB' $1
echo -n "DLW "; grep -c '; DLW' $1
echo -n "SB "; grep -c '; SB' $1
echo -n "SW "; grep -c '; SW' $1
echo -n "SLB "; grep -c '; SLB' $1
echo -n "SLW "; grep -c '; SLW' $1
echo -n "SAB "; grep -c '; SAB' $1
echo -n "SAW "; grep -c '; SAW' $1
echo -n "DAB "; grep -c '; DAB' $1
echo -n "DAW "; grep -c '; DAW' $1
echo -n "NOT "; grep -c '; NOT' $1
echo -n "ADD "; grep -c '; ADD ' $1
echo -n "SUB "; grep -c '; SUB ' $1
echo -n "MUL "; grep -c '; MUL' $1
echo -n "DIV "; grep -c '; DIV' $1
echo -n "MOD "; grep -c '; MOD' $1
echo -n "INCR "; grep -c '; INCR' $1
echo -n "DECR "; grep -c '; DECR' $1
echo -n "NEG "; grep -c '; NEG' $1
echo -n "COMP "; grep -c '; COMP' $1
echo -n "AND "; grep -c '; AND ' $1
echo -n "OR "; grep -c '; OR' $1
echo -n "XOR "; grep -c '; XOR' $1
echo -n "SHL "; grep -c '; SHL' $1
echo -n "SHR "; grep -c '; SHR' $1
echo -n "IDXW "; grep -c '; IDXW' $1
echo -n "BRGT "; grep -c '; BRGT' $1
echo -n "BRLT "; grep -c '; BRLT' $1
echo -n "INCBRLE "; grep -c '; INCBRLE' $1
echo -n "ADDBRLE "; grep -c '; ADDBRLE' $1
echo -n "DECBRGE "; grep -c '; DECBRGE' $1
echo -n "SUBBRGE "; grep -c '; SUBBRGE' $1
echo -n "BRAND "; grep -c '; BRAND' $1
echo -n "BROR "; grep -c '; BROR' $1
echo -n "ADDLB "; grep -c '; ADDLB' $1
echo -n "ADDLW "; grep -c '; ADDLW' $1
echo -n "ADDAB "; grep -c '; ADDAB' $1
echo -n "ADDAW "; grep -c '; ADDAW' $1
echo -n "IDXLB "; grep -c '; IDXLB' $1
echo -n "IDXLW "; grep -c '; IDXLW' $1
echo -n "IDXAB "; grep -c '; IDXAB' $1
echo -n "IDXAW "; grep -c '; IDXAW' $1

View File

@@ -1,4 +1,7 @@
include "inc/dgr.plh"
include "inc/cmdsys.plh"
include "inc/dgrlib.plh"
include "inc/lines.plh"
sysflags restxt1|restxt2|resxtxt1|resxtxt2 // Reserve all text pages
byte[] sprite1 = $80,$80,$00,$00,$00,$00,$80,$80
byte[] = $80,$00,$0A,$0A,$0A,$0A,$00,$80
@@ -18,42 +21,45 @@ byte[] = $0A,$05,$0A,$05,$0A,$05,$0A,$00
// Test routine
//
def dgrTest#0
byte b, l, k
word i, j, ii, ij
byte b, l, k
word i, j, ii, ij
b = dgrMode()
for k = 15 downto 0
dgrClear(dgrbuff[0], k)
next
for l = 0 to 79
dgrColor(l)
dgrLine(dgrbuff[0], 0, 0, l, 47)
next
for l = 47 downto 0
dgrColor(l)
dgrLine(dgrbuff[0], 0, 0, 79, l)
next
ii = 2
ij = -1
i = 40
j = 10
^$C010
while ^$C000 < 128
dgrFill(dgrbuff[b], k, k, @tile1)
dgrBLT(dgrbuff[b], i, j, 8, 8, @sprite1)
b = dgrShow(b)
k++
i = i + ii
if i < -3 or i > 75
ii = -ii
fin
j = j + ij
if j < -3 or j > 43
ij = -ij
fin
loop
^$C010
txtMode
b = dgrMode()
dgrDrawBuf(0)
for k = 15 downto 0
dgrClear(k)
next
setlinespans(@dgrHLin, @dgrVLin)
for l = 0 to 79
dgrColor(l)
linespans(0, 0, l, 47)
next
for l = 47 downto 0
dgrColor(l)
linespans(0, 0, 79, l)
next
ii = 2
ij = -1
i = 40
j = 10
^$C010
dgrDrawBuf(1)
while ^$C000 < 128
dgrFill(k, k, @tile1)
dgrBLT(i, j, 8, 8, @sprite1)
dgrSwap
k++
i = i + ii
if i < -3 or i > 75
ii = -ii
fin
j = j + ij
if j < -3 or j > 43
ij = -ij
fin
loop
^$C010
txtMode
end
dgrTest

66
src/samplesrc/grtest.pla Normal file
View File

@@ -0,0 +1,66 @@
include "inc/cmdsys.plh"
include "inc/grlib.plh"
include "inc/lines.plh"
sysflags restxt1|restxt2 // Reserve all text pages
byte[] sprite1 = $80,$80,$00,$00,$00,$00,$80,$80
byte[] = $80,$00,$0A,$0A,$0A,$0A,$00,$80
byte[] = $00,$0A,$0F,$0F,$0F,$0F,$0A,$00
byte[] = $00,$0A,$0F,$80,$80,$0F,$0A,$00
byte[] = $00,$0A,$0F,$80,$80,$0F,$0A,$00
byte[] = $00,$0A,$0F,$0F,$0F,$0F,$0A,$00
byte[] = $80,$00,$0A,$0A,$0A,$0A,$00,$80
byte[] = $80,$80,$00,$00,$00,$00,$80,$80
byte[] tile1 = $11,$11,$11,$11,$11,$11,$55,$00
byte[] = $11,$11,$11,$11,$11,$11,$55,$00
byte[] = $11,$11,$11,$11,$11,$11,$55,$00
byte[] = $05,$05,$05,$05,$05,$05,$05,$00
//
// Test routine
//
def grTest#0
byte b, l, k
word i, j, ii, ij
b = grMode()
grDrawBuf(0)
for k = 15 downto 0
grClear(k)
next
setlinespans(@grHLin, @grVLin)
for l = 0 to 39
grColor(l)
linespans(0, 0, l, 47)
next
for l = 47 downto 0
grColor(l)
linespans(0, 0, 39, l)
next
ii = 2
ij = -1
i = 20
j = 10
^$C010
grDrawBuf(1)
while ^$C000 < 128
grFill(k, k, @tile1)
grBLT(i, j, 8, 8, @sprite1)
grSwap
k++
i = i + ii
if i < -3 or i > 35
ii = -ii
fin
j = j + ij
if j < -3 or j > 43
ij = -ij
fin
loop
^$C010
txtMode
end
grTest
done

View File

@@ -1,56 +0,0 @@
include "inc/cmdsys.plh"
sysflags reshgr1 // Reserve HGR page 1
//
// Hardware addresses
//
const speaker = $C030
const showgraphics = $C050
const showtext = $C051
const showfull = $C052
const showmix = $C053
const showpage1 = $C054
const showpage2 = $C055
const showlores = $C056
const showhires = $C057
const keyboard = $C000
const keystrobe = $C010
const hgr1 = $2000
const hgr2 = $4000
const page1 = 0
const page2 = 1
word hgrpage[] = hgr1, hgr2
word hgrscan[] = $0000,$0400,$0800,$0C00,$1000,$1400,$1800,$1C00
word = $0080,$0480,$0880,$0C80,$1080,$1480,$1880,$1C80
word = $0100,$0500,$0900,$0D00,$1100,$1500,$1900,$1D00
word = $0180,$0580,$0980,$0D80,$1180,$1580,$1980,$1D80
word = $0200,$0600,$0A00,$0E00,$1200,$1600,$1A00,$1E00
word = $0280,$0680,$0A80,$0E80,$1280,$1680,$1A80,$1E80
word = $0300,$0700,$0B00,$0F00,$1300,$1700,$1B00,$1F00
word = $0380,$0780,$0B80,$0F80,$1380,$1780,$1B80,$1F80
word = $0028,$0428,$0828,$0C28,$1028,$1428,$1828,$1C28
word = $00A8,$04A8,$08A8,$0CA8,$10A8,$14A8,$18A8,$1CA8
word = $0128,$0528,$0928,$0D28,$1128,$1528,$1928,$1D28
word = $01A8,$05A8,$09A8,$0DA8,$11A8,$15A8,$19A8,$1DA8
word = $0228,$0628,$0A28,$0E28,$1228,$1628,$1A28,$1E28
word = $02A8,$06A8,$0AA8,$0EA8,$12A8,$16A8,$1AA8,$1EA8
word = $0328,$0728,$0B28,$0F28,$1328,$1728,$1B28,$1F28
word = $03A8,$07A8,$0BA8,$0FA8,$13A8,$17A8,$1BA8,$1FA8
word = $0050,$0450,$0850,$0C50,$1050,$1450,$1850,$1C50
word = $00D0,$04D0,$08D0,$0CD0,$10D0,$14D0,$18D0,$1CD0
word = $0150,$0550,$0950,$0D50,$1150,$1550,$1950,$1D50
word = $01D0,$05D0,$09D0,$0DD0,$11D0,$15D0,$19D0,$1DD0
word = $0250,$0650,$0A50,$0E50,$1250,$1650,$1A50,$1E50
word = $02D0,$06D0,$0AD0,$0ED0,$12D0,$16D0,$1AD0,$1ED0
word = $0350,$0750,$0B50,$0F50,$1350,$1750,$1B50,$1F50
word = $03D0,$07D0,$0BD0,$0FD0,$13D0,$17D0,$1BD0,$1FD0
word hcolor[] = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF
memset(hgr1, 0, $2000) // Clear HGR page 1
^showpage1
^showfull
^showhires
^showgraphics
getc
^showpage1
^showtext
done

95
src/samplesrc/hgrtest.pla Normal file
View File

@@ -0,0 +1,95 @@
include "inc/cmdsys.plh"
include "inc/hgrlib.plh"
include "inc/hgrsprite.plh"
include "inc/lines.plh"
sysflags reshgr1|reshgr2 // Reserve HGR page 1 and 2
byte ball = $88, $83, $33, $38, $88
byte = $88, $33, $11, $33, $88
byte = $83, $31, $11, $13, $38
byte = $33, $11, $11, $11, $33
byte = $33, $11, $11, $11, $33
byte = $33, $11, $11, $11, $33
byte = $33, $11, $11, $11, $33
byte = $83, $31, $11, $13, $38
byte = $88, $33, $11, $33, $88
byte = $88, $83, $33, $38, $88
var sprtBall
def testline#0
var i
setlinespans(@hgrHlin, @hgrVlin)
setlineplot(@hgrXorPlot)
hgrColor(7)
for i = 0 to 191 step 8
linespans(0, i, 279, 191 - i)
//line(0, i, 279, 191 - i)
next
for i = 0 to 279 step 9
linespans(i, 0, 279 - i, 191)
//line(i, 0, 279 - i, 191)
next
end
def testblt(sprtnum)#0
var[16] i, j, ii, jj
byte k
sprtnum = sprtnum - 1
i[0] = 100
ii[0] = 1
j[0] = 80
jj[0] = -1
if sprtnum
for k = 1 to sprtnum
i[k] = ((i[k - 1] ^ 37) + 97) % 270
ii[k] = -ii[k - 1]
j[k] = ((j[k - 1] ^ 29) + 53) % 180
jj[k] = -jj[k - 1]
next
fin
while ^$C000 < 128
for k = 0 to sprtnum
i[k] = i[k] + ii[k]
if i[k] < -5 or i[k] > 284
ii[k] = -ii[k]
fin
j[k] = j[k] + jj[k]
if j[k] < -5 or j[k] > 196
jj[k] = -jj[k]
fin
spritePosIndex(i[k], j[k], k)
next
spriteDrawList()
spriteDrawBuf(hgrSwap())
loop
end
hgrMode
spriteDrawBuf(hgrDrawBuf(0)) // So we can see the compile process
sprtBall = spriteCompile(10, 10, 5, 5, @ball)
hgrColor(0)
hgrClear()
testline
memcpy($4000, $2000, $2000) // Copy to both buffers
spriteDrawBuf(hgrDrawBuf(1))
spriteAdd(0, sprtBall)
spriteAdd(1, spriteDup(sprtBall))
spriteAdd(2, spriteDup(sprtBall))
spriteAdd(3, spriteDup(sprtBall))
spriteAdd(4, spriteDup(sprtBall))
spriteAdd(5, spriteDup(sprtBall))
spriteAdd(6, spriteDup(sprtBall))
spriteAdd(7, spriteDup(sprtBall))
spriteAdd(8, spriteDup(sprtBall))
spriteAdd(9, spriteDup(sprtBall))
spriteAdd(10, spriteDup(sprtBall))
spriteAdd(11, spriteDup(sprtBall))
spriteAdd(12, spriteDup(sprtBall))
spriteAdd(13, spriteDup(sprtBall))
spriteAdd(14, spriteDup(sprtBall))
spriteAdd(15, spriteDup(sprtBall))
testblt(16)
getc
txtMode
done

View File

@@ -0,0 +1,72 @@
include "inc/cmdsys.plh"
include "inc/int32.plh"
def testi32#0
word il, ih
res[t_i32] i32
ih = 0
for il = 0 to 10
load32(@il)
muli16(10)
divi16(2)
store32(@i32)
puti32(@i32); putln
next
muli16(-30000)
store32(@i32)
puti32(@i32); putln
loadi16(100)
if islti16(50)
puts("100 < 50\n")
fin
if islti16(500)
puts("100 < 500\n")
fin
if isgti16(50)
puts("100 > 50\n")
fin
if isgti16(500)
puts("100 > 500\n")
fin
if islei16(50)
puts("100 <= 50\n")
fin
if islei16(500)
puts("100 <= 500\n")
fin
if isgei16(50)
puts("100 >= 50\n")
fin
if isgei16(500)
puts("100 >= 500\n")
fin
if islti16(100)
puts("100 < 100\n")
fin
if islti16(100)
puts("100 < 100\n")
fin
if isgti16(100)
puts("100 > 100\n")
fin
if isgti16(100)
puts("100 > 100\n")
fin
if islei16(100)
puts("100 <= 100\n")
fin
if islei16(100)
puts("100 <= 100\n")
fin
if isgei16(100)
puts("100 >= 100\n")
fin
if isgei16(100)
puts("100 >= 100\n")
fin
end
testi32
done

107
src/samplesrc/lz4cat.pla Normal file
View File

@@ -0,0 +1,107 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
include "inc/lz4.plh"
struc t_header
word magic[2]
byte FLG
byte BD
end
word arg
byte ref
def lz4ReadBlock(flags)#2
word size[2], block, data, len
len = fileio:read(ref, @size, 4)
if len <> 4 or size[0] == 0 or size[1] & $7FFF
return NULL, 0
fin
block = heapalloc(size[0])
if block
len = fileio:read(ref, block, size[0])
if len <> size[0]
heaprelease(block)
return NULL, 0
fin
else
return NULL, 0
fin
if size[1] & $8000
//
// Uncompressed block
//
data = block
else
//
// Decompress block
//
len = heapavail - 256 // Allocate almost entire heap to decompress into
data = heapalloc(len)
if data
len = lz4Unpack(block, block + size[0], data, data + len)
memcpy(block, data, len)
data = block
else
len = 0
fin
heaprelease(block + len)
fin
if flags & $10 // Block Checksum
fileio:read(ref, @size, 4)
fin
return data, len
end
def lz4ReadFrame#0
word data, len
byte header[t_header], opt
fileio:read(ref, @header, t_header)
if header:magic[1] <> $184D or header:magic[0] <> $2204
puts("Not LZ4 file.\n")
return
fin
if header.FLG & $C0 <> $40
puts("Wrong LZ4 version.\n")
return
fin
if header.BD & $70 <> $40
puts("Not 64K block size.\n")
return
fin
opt = 1
if header.FLG & $08 // Content Size
opt = opt + 8
fin
if header.FLG & $01 // Dictionary ID
opt = opt + 4
fin
fileio:read(ref, heapmark, opt) // Read rest of header and throw away
repeat
data, len = lz4ReadBlock(header.FLG)
if len
while len
putc(^data <> $0A ?? ^data :: $0D)
data++
len--
loop
heaprelease(data)
fin
until not data
if header.FLG & $04 // Content Checksun
fileio:read(ref, heapmark, 4)
fin
end
arg = argNext(argFirst)
if ^arg
ref = fileio:open(arg)
if ref
lz4ReadFrame
fileio:close(ref)
else
puts("File not found.\n")
fin
fin
done

View File

@@ -0,0 +1,22 @@
include "inc/cmdsys.plh"
include "inc/conio.plh"
include "inc/mouse.plh"
var count
var xPos, yPos, bttn
Mouse:clampMouse(0, 39, 0, 23)
Mouse:setMouse(VBL_INT_ENABLE|MOVE_INT_ENABLE|BUTTON_INT_ENABLE|MOUSE_ENABLE)
while ^$C000 < 128
if Mouse:chkMouse()
conio:gotoxy(xPos, yPos); putc(' ')
xPos, yPos, bttn = Mouse:readMouse()#3
conio:gotoxy(xPos, yPos); putc(bttn & BUTTON_DOWN ?? '+' :: '^')
fin
if Mouse:chkVBL()
^$400++
fin
loop
getc
Mouse:detachMouse()
done

View File

@@ -6,8 +6,8 @@ include "inc/sndseq.plh"
//
// These are utility sequences/routines needed to test the music sequencer code.
//
word arg
word ref
word arg, seq, len
byte ref
//
// Sample background process to show it's working
//
@@ -19,9 +19,11 @@ arg = argNext(argFirst)
if ^arg
ref = fileio:open(arg)
if ref
fileio:read(ref, heapmark(), heapavail())
seq = heapalloc(heapavail - 256)
len = fileio:read(ref, seq, heapmark - seq)
fileio:close(ref)
musicPlay(heapmark(), TRUE)
heaprelease(seq + len)
musicPlay(seq, TRUE)
musicGetKey(8, @backgroundProc) // Yield every 8/16 second
musicStop
else

View File

@@ -0,0 +1,41 @@
include "inc/cmdsys.plh"
var a, b, i,loprim,hiprim
def getnum
var str, num
num = 0
str = gets(':'|$80) + 1
while ^str >= '0' and ^str <= '9'
num = num * 10 + (^str - '0')
str++
loop
return num
end
def prim(x)
var i
i = 3
while i*i < x and x % i; i = i + 2; loop
return x < i*i
end
puts("Geben Sie den oberen Grenzwert ein")
a = getnum
puts("Geben Sie die minimale Differenz ein")
b = getnum
loprim, hiprim, i = 1, 1, 3
while i <= a and hiprim-loprim < b
if prim(i)
loprim = hiprim
hiprim = i
fin
i = i + 2
loop
if hiprim-loprim < b
puts("keine Loesung gefunden !")
else
puti(hiprim); putc(' '); puti(loprim); putc(' '); puti(hiprim-loprim)
fin
putln
done

View File

@@ -3,8 +3,8 @@ include "inc/conio.plh"
//
// Rod's Colors
//
def rod
var i, j, k, w, fmi, fmk, color
def rod#0
byte i, j, k, w, fmi, fmk, color
while TRUE
for w = 3 to 50
@@ -24,7 +24,8 @@ def rod
conio:grplot(i, fmk)
conio:grplot(fmk, i)
if conio:keypressed()
return getc
getc
return
fin
next
next

View File

@@ -162,48 +162,47 @@ export def fight(player, enemy)
if toupper(conio:getkey()) == 'R'
conio:echo(ECHO_OFF)
return 1
fin
//
// Turn player in random direction
//
player->angle = conio:rnd() & 7
//
// Calculate attack (with a little random variation)
//
p_atck = player->skill + player->energy / 10 - enemy->power / 25 + (conio:rnd() & 7)
e_atck = enemy->power - player->skill / 5 - player->energy / 20 + (conio:rnd() & 7)
if enemy->life > p_atck
enemy->life = enemy->life - p_atck
else
win
enemy->life = 0
p_atck = player->skill + enemy->power / 3
if p_atck > 100 // Limit skill
p_atck = 100
fin
player->skill = p_atck
//
// Turn player in random direction
// Unlink dead enemy from entities list
//
player->angle = conio:rnd() & 7
//
// Calculate attack (with a little random variation)
//
p_atck = player->skill + player->energy / 10 - enemy->power / 25 + (conio:rnd() & 7)
e_atck = enemy->power - player->skill / 5 - player->energy / 20 + (conio:rnd() & 7)
if enemy->life > p_atck
enemy->life = enemy->life - p_atck
else
win
enemy->life = 0
p_atck = player->skill + enemy->power / 3
if p_atck > 100 // Limit skill
p_atck = 100
fin
player->skill = p_atck
//
// Unlink dead enemy from entities list
//
if enemy == entities
entities = enemy=>next_other
fin
if enemy=>next_other
enemy=>next_other=>prev_other = enemy=>prev_other
if enemy == entities
entities = enemy=>next_other
fin
if enemy=>next_other
enemy=>next_other=>prev_other = enemy=>prev_other
fin
if enemy=>prev_other
enemy=>prev_other=>next_other = enemy=>next_other
fin
fin
if enemy=>prev_other
enemy=>prev_other=>next_other = enemy=>next_other
if player->health > e_atck
player->health = player->health - e_atck
else
player->energy = 0
player->health = 0
fin
fin
if player->health > e_atck
player->health = player->health - e_atck
else
player->energy = 0
player->health = 0
fin
if player->energy >= 4
player->energy = player->energy - 4
fin
if player->energy >= 4
player->energy = player->energy - 4
fin
until player->health == 0 or enemy->life == 0
conio:echo(ECHO_OFF)

View File

@@ -260,8 +260,8 @@ end
//
export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
byte o, l, dist, tile, adjtile, occluded, darkness
word ymap, xmap, imap
byte l, dist, tile, adjtile, occluded, darkness
word ymap, xmap, imap, o
byte yscr, xscr
if viewdist > beamdepth
@@ -279,7 +279,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
//
darkness = 1
imap = (yorg << rowshift) + xorg
if ^(map + imap) & LIT_TILE or lightdist
if lightdist or ^(map + imap) & LIT_TILE
//
// Update current spot in viewmap
//
@@ -358,7 +358,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
//
// Run through visible octant beam points
//
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
//
// Check parent visiblity
//
@@ -429,7 +429,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg - xbeam[l]) << rowshift) + xorg + ybeam[l]
tile = ^(map + imap)
@@ -479,7 +479,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + xbeam[l]) << rowshift) + xorg + ybeam[l]
tile = ^(map + imap)
@@ -529,7 +529,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + ybeam[l]) << rowshift) + xorg + xbeam[l]
tile = ^(map + imap)
@@ -579,7 +579,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + ybeam[l]) << rowshift) + xorg - xbeam[l]
tile = ^(map + imap)
@@ -629,7 +629,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + xbeam[l]) << rowshift) + xorg - ybeam[l]
tile = ^(map + imap)
@@ -679,7 +679,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg - xbeam[l]) << rowshift) + xorg - ybeam[l]
tile = ^(map + imap)
@@ -729,7 +729,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
vispix[l] = 0
fin
next
for l = l to dbeam[viewdist]
for l = dbeam[lightdist]+1 to dbeam[viewdist]
imap = ((yorg - ybeam[l]) << rowshift) + xorg - xbeam[l]
if vispix[vbeam[l]]
tile = ^(map + imap)

View File

@@ -11,26 +11,30 @@ def beep#0
putc(7)
end
beep
//for iter = 1 to 10
flag = heapalloc(sizepl)
memset(flag, TRUE, sizepl)
count = 0
for i = 0 to size
if flag->[i]
prime = i + i + 3
k = i + prime
while k <= size
flag->[k] = FALSE
k = k + prime
loop
count = count + 1
puti(prime)
putln
fin
next
//next
beep
def sieve#0
beep
//for iter = 1 to 10
flag = heapalloc(sizepl)
memset(flag, TRUE, sizepl)
count = 0
for i = 0 to size
if flag->[i]
prime = i + i + 3
k = i + prime
while k <= size
flag->[k] = FALSE
k = k + prime
loop
count = count + 1
puti(prime)
putln
fin
next
//next
beep
end
sieve
puti(count)
puts(" primes.\n")
done

View File

@@ -204,5 +204,9 @@ puti(array:0); puts(" > "); puti(array:0); puts (" is ")
puts(array:0 > array:0 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" < "); puti(array:0); puts (" is ")
puts(array:0 < array:0 ?? "TRUE\n" :: "FALSE\n")
ptr = 0
ptr = 5
puts("5*0="); puti(ptr*0); putln
puts("5*1="); puti(ptr*1); putln
puts("5*2="); puti(ptr*2); putln
puts("5/1="); puti(ptr/1); putln
done

74
src/tftpbld Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
# Build tools
echo "BLD/PLASM"; atftp $1 --put -l rel/PLASM#FE1000 -r $2/BLD/PLASM#FE1000
echo "BLD/CODEOPT"; atftp $1 --put -l rel/CODEOPT#FE1000 -r $2/BLD/CODEOPT#FE1000
#Build incs
echo "BLD/INC/ARGS.PLH"; atftp $1 --put -l inc/args.plh -r $2/BLD/INC/ARGS.PLH#040000
echo "BLD/INC/CMDSYS.PLH"; atftp $1 --put -l inc/cmdsys.plh -r $2/BLD/INC/CMDSYS.PLH#040000
echo "BLD/INC/CONIO.PLH"; atftp $1 --put -l inc/conio.plh -r $2/BLD/INC/CONIO.PLH#040000
echo "BLD/INC/LINES.PLH"; atftp $1 --put -l inc/lines.plh -r $2/BLD/INC/LINES.PLH#040000
echo "BLD/INC/HGRSPRITE.PLH";atftp $1 --put -l inc/hgrsprite.plh -r $2/BLD/INC/HGRSPRITE.PLH#040000
echo "BLD/INC/HGRLIB.PLH"; atftp $1 --put -l inc/hgrlib.plh -r $2/BLD/INC/HGRLIB.PLH#040000
echo "BLD/INC/GRLIB.PLH"; atftp $1 --put -l inc/grlib.plh -r $2/BLD/INC/GRLIB.PLH#040000
echo "BLD/INC/DGRLIB.PLH"; atftp $1 --put -l inc/dgrlib.plh -r $2/BLD/INC/DGRLIB.PLH#040000
echo "BLD/INC/FIBER.PLH"; atftp $1 --put -l inc/fiber.plh -r $2/BLD/INC/FIBER.PLH#040000
echo "BLD/INC/FILEIO.PLH"; atftp $1 --put -l inc/fileio.plh -r $2/BLD/INC/FILEIO.PLH#040000
echo "BLD/INC/INT32.PLH"; atftp $1 --put -l inc/int32.plh -r $2/BLD/INC/INT32.PLH#040000
echo "BLD/INC/FPSTR.PLH"; atftp $1 --put -l inc/fpstr.plh -r $2/BLD/INC/FPSTR.PLH#040000
echo "BLD/INC/FPU.PLH"; atftp $1 --put -l inc/fpu.plh -r $2/BLD/INC/FPU.PLH#040000
echo "BLD/INC/GRAFIX.PLH"; atftp $1 --put -l inc/grafix.plh -r $2/BLD/INC/GRAFIX.PLH#040000
echo "BLD/INC/INET.PLH"; atftp $1 --put -l inc/inet.plh -r $2/BLD/INC/INET.PLH#040000
echo "BLD/INC/JOYBUZZ.PLH"; atftp $1 --put -l inc/joybuzz.plh -r $2/BLD/INC/JOYBUZZ.PLH#040000
echo "BLD/INC/LONGJUMP.PLH"; atftp $1 --put -l inc/longjmp.plh -r $2/BLD/INC/LONGJUMP.PLH#040000
echo "BLD/INC/LZ4.PLH"; atftp $1 --put -l inc/lz4.plh -r $2/BLD/INC/LZ4.PLH#040000
echo "BLD/INC/MEMMGR.PLH"; atftp $1 --put -l inc/memmgr.plh -r $2/BLD/INC/MEMMGR.PLH#040000
echo "BLD/INC/MOUSE.PLH"; atftp $1 --put -l inc/mouse.plh -r $2/BLD/INC/MOUSE.PLH#040000
echo "BLD/INC/PORTIO.PLH"; atftp $1 --put -l inc/portio.plh -r $2/BLD/INC/PORTIO.PLH#040000
echo "BLD/INC/SANE.PLH"; atftp $1 --put -l inc/sane.plh -r $2/BLD/INC/SANE.PLH#040000
echo "BLD/INC/SDFAT.PLH"; atftp $1 --put -l inc/sdfat.plh -r $2/BLD/INC/SDFAT.PLH#040000
echo "BLD/INC/SNDSEQ.PLH"; atftp $1 --put -l inc/sndseq.plh -r $2/BLD/INC/SNDSEQ.PLH#040000
echo "BLD/INC/SPIPORT.PLH"; atftp $1 --put -l inc/spiport.plh -r $2/BLD/INC/SPIPORT.PLH#040000
echo "BLD/INC/TESTLIB.PLH"; atftp $1 --put -l inc/testlib.plh -r $2/BLD/INC/TESTLIB.PLH#040000
# Sample sources
echo "BLD/SAMPLES/HELLO.PLA"; atftp $1 --put -l samplesrc/hello.pla -r $2/BLD/SAMPLES/HELLO.PLA#040000
echo "BLD/SAMPLES/TESTLIB.PLA"; atftp $1 --put -l samplesrc/testlib.pla -r $2/BLD/SAMPLES/TESTLIB.PLA#040000
echo "BLD/SAMPLES/TEST.PLA"; atftp $1 --put -l samplesrc/test.pla -r $2/BLD/SAMPLES/TEST.PLA#040000
echo "BLD/SAMPLES/FIBERTEST.PLA"; atftp $1 --put -l samplesrc/fibertest.pla -r $2/BLD/SAMPLES/FIBERTEST.PLA#040000
echo "BLD/SAMPLES/MOUSETEST.PLA"; atftp $1 --put -l samplesrc/mousetest.pla -r $2/BLD/SAMPLES/MOUSETEST.PLA#040000
echo "BLD/SAMPLES/ROD.PLA"; atftp $1 --put -l samplesrc/rod.pla -r $2/BLD/SAMPLES/ROD.PLA#040000
echo "BLD/SAMPLES/INT32TEST.PLA"; atftp $1 --put -l samplesrc/int32test.pla -r $2/BLD/SAMPLES/INT32TEST.PLA#040000
echo "BLD/SAMPLES/HGRTEST.PLA"; atftp $1 --put -l samplesrc/hgrtest.pla -r $2/BLD/SAMPLES/HGRTEST.PLA#040000
echo "BLD/SAMPLES/GRTEST.PLA"; atftp $1 --put -l samplesrc/grtest.pla -r $2/BLD/SAMPLES/GRTEST.PLA#040000
echo "BLD/SAMPLES/DGRTEST.PLA"; atftp $1 --put -l samplesrc/dgrtest.pla -r $2/BLD/SAMPLES/DGRTEST.PLA#040000
echo "BLD/SAMPLES/HGRTEST.PLA"; atftp $1 --put -l samplesrc/hgrtest.pla -r $2/BLD/SAMPLES/HGRTEST.PLA#040000
echo "BLD/SAMPLES/PLAYSEQ.PLA"; atftp $1 --put -l samplesrc/playseq.pla -r $2/BLD/SAMPLES/PLAYSEQ.PLA#040000
echo "BLD/SAMPLES/RPNCALC.PLA"; atftp $1 --put -l samplesrc/rpncalc.pla -r $2/BLD/SAMPLES/RPNCALC.PLA#040000
echo "BLD/SAMPLES/SIEVE.PLA"; atftp $1 --put -l samplesrc/sieve.pla -r $2/BLD/SAMPLES/SIEVE.PLA#040000
echo "BLD/SAMPLES/MON.PLA"; atftp $1 --put -l utilsrc/apple/mon.pla -r $2/BLD/SAMPLES/MON.PLA#040000
echo "BLD/SAMPLES/MEMTEST.PLA"; atftp $1 --put -l samplesrc/memtest.pla -r $2/BLD/SAMPLES/MEMTEST.PLA#040000
echo "BLD/SAMPLES/FATCAT.PLA"; atftp $1 --put -l samplesrc/fatcat.pla -r $2/BLD/SAMPLES/FATCAT.PLA#040000
echo "BLD/SAMPLES/GFXDEMO.PLA"; atftp $1 --put -l samplesrc/gfxdemo.pla -r $2/BLD/SAMPLES/GFXDEMO.PLA#040000
echo "BLD/SAMPLES/LZ4CAT.PLA"; atftp $1 --put -l samplesrc/lz4cat.pla -r $2/BLD/SAMPLES/LZ4CAT.PLA#040000
# Examples from video series
echo "BLD/EXAMPLES/EX.1.PLA"; atftp $1 --put -l samplesrc/examples/ex.1.pla -r $2/BLD/EXAMPLES/EX.1.PLA#040000
echo "BLD/EXAMPLES/EX.2.PLA"; atftp $1 --put -l samplesrc/examples/ex.2.pla -r $2/BLD/EXAMPLES/EX.2.PLA#040000
echo "BLD/EXAMPLES/EX.3.PLA"; atftp $1 --put -l samplesrc/examples/ex.3.pla -r $2/BLD/EXAMPLES/EX.3.PLA#040000
echo "BLD/EXAMPLES/EX.4.PLA"; atftp $1 --put -l samplesrc/examples/ex.4.pla -r $2/BLD/EXAMPLES/EX.4.PLA#040000
echo "BLD/EXAMPLES/EX.5.PLA"; atftp $1 --put -l samplesrc/examples/ex.5.pla -r $2/BLD/EXAMPLES/EX.5.PLA#040000
echo "BLD/EXAMPLES/EX.6.PLA"; atftp $1 --put -l samplesrc/examples/ex.6.pla -r $2/BLD/EXAMPLES/EX.6.PLA#040000
echo "BLD/EXAMPLES/EX.7.PLA"; atftp $1 --put -l samplesrc/examples/ex.7.pla -r $2/BLD/EXAMPLES/EX.7.PLA#040000
echo "BLD/EXAMPLES/EX.8.PLA"; atftp $1 --put -l samplesrc/examples/ex.8.pla -r $2/BLD/EXAMPLES/EX.8.PLA#040000
echo "BLD/EXAMPLES/EX.9.PLA"; atftp $1 --put -l samplesrc/examples/ex.9.pla -r $2/BLD/EXAMPLES/EX.9.PLA#040000
echo "BLD/EXAMPLES/EX.10.PLA"; atftp $1 --put -l samplesrc/examples/ex.10.pla -r $2/BLD/EXAMPLES/EX.10.PLA#040000
echo "BLD/EXAMPLES/EX.11.PLA"; atftp $1 --put -l samplesrc/examples/ex.11.pla -r $2/BLD/EXAMPLES/EX.11.PLA#040000
echo "BLD/EXAMPLES/EX.12.PLA"; atftp $1 --put -l samplesrc/examples/ex.12.pla -r $2/BLD/EXAMPLES/EX.12.PLA#040000
echo "BLD/EXAMPLES/EX.13.PLA"; atftp $1 --put -l samplesrc/examples/ex.13.pla -r $2/BLD/EXAMPLES/EX.13.PLA#040000
echo "BLD/EXAMPLES/EX.14.PLA"; atftp $1 --put -l samplesrc/examples/ex.14.pla -r $2/BLD/EXAMPLES/EX.14.PLA#040000
echo "BLD/EXAMPLES/EX.15.PLA"; atftp $1 --put -l samplesrc/examples/ex.15.pla -r $2/BLD/EXAMPLES/EX.15.PLA#040000
echo "BLD/EXAMPLES/EX.16.PLA"; atftp $1 --put -l samplesrc/examples/ex.16.pla -r $2/BLD/EXAMPLES/EX.16.PLA#040000
echo "BLD/EXAMPLES/EX.17.PLA"; atftp $1 --put -l samplesrc/examples/ex.17.pla -r $2/BLD/EXAMPLES/EX.17.PLA#040000

35
src/tftpdemos Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# Demos
echo "DEMOS/RPNCALC"; atftp $1 --put -l rel/RPNCALC#FE1000 -r $2/DEMOS/RPNCALC#FE1000
echo "DEMOS/LZ4CAT"; atftp $1 --put -l rel/LZ4CAT#FE1000 -r $2/DEMOS/LZ4CAT#FE1000
echo "DEMOS/SIEVE"; atftp $1 --put -l rel/SIEVE#FE1000 -r $2/DEMOS/SIEVE#FE1000
echo "DEMOS/ROD"; atftp $1 --put -l rel/apple/ROD#FE1000 -r $2/DEMOS/ROD#FE1000
echo "DEMOS/HGRTEST"; atftp $1 --put -l rel/apple/HGRTEST#FE1000 -r $2/DEMOS/HGRTEST#FE1000
echo "DEMOS/GRTEST"; atftp $1 --put -l rel/apple/GRTEST#FE1000 -r $2/DEMOS/GRTEST#FE1000
echo "DEMOS/INT32TEST"; atftp $1 --put -l rel/INT32TEST#FE1000 -r $2/DEMOS/INT32TEST#FE1000
echo "DEMOS/DGRTEST"; atftp $1 --put -l rel/apple/DGRTEST#FE1000 -r $2/DEMOS/DGRTEST#FE1000
# Music demo
echo "DEMOS/MUSIC/PLAYSEQ"; atftp $1 --put -l rel/apple/PLAYSEQ#FE1000 -r $2/DEMOS/MUSIC/PLAYSEQ#FE1000
atftp $1 --put -l mockingboard/ultima3.seq -r $2/DEMOS/MUSIC/ULTIMA3.SEQ#060000
atftp $1 --put -l mockingboard/startrek.seq -r $2/DEMOS/MUSIC/STARTREK.SEQ#060000
# Rogue demo
echo "DEMOS/ROGUE/ROGUE"; atftp $1 --put -l rel/ROGUE#FE1000 -r $2/DEMOS/ROGUE/ROGUE#FE1000
echo "DEMOS/ROGUE/ROGUEMAP"; atftp $1 --put -l rel/ROGUEMAP#FE1000 -r $2/DEMOS/ROGUE/ROGUEMAP#FE1000
echo "DEMOS/ROGUE/ROGUECOMBAT"; atftp $1 --put -l rel/ROGUECOMBAT#FE1000 -r $2/DEMOS/ROGUE/ROGUECOMBAT#FE1000
atftp $1 --put -l samplesrc/LEVEL0#040000 -r $2/DEMOS/ROGUE/LEVEL0#040000
atftp $1 --put -l samplesrc/LEVEL1#040000 -r $2/DEMOS/ROGUE/LEVEL1#040000
# Arduino+SD card demos
echo "DEMOS/SDUTILS/SPIPORT"; atftp $1 --put -l rel/apple/SPIPORT#FE1000 -r $2/DEMOS/SDUTILS/SPIPORT#FE1000
echo "DEMOS/SDUTILS/SDFAT"; atftp $1 --put -l rel/apple/SDFAT#FE1000 -r $2/DEMOS/SDUTILS/SDFAT#FE1000
echo "DEMOS/SDUTILS/FATCAT"; atftp $1 --put -l rel/apple/FATCAT#FE1000 -r $2/DEMOS/SDUTILS/FATCAT#FE1000
echo "DEMOS/SDUTILS/FATGET"; atftp $1 --put -l rel/apple/FATGET#FE1000 -r $2/DEMOS/SDUTILS/FATGET#FE1000
echo "DEMOS/SDUTILS/FATPUT"; atftp $1 --put -l rel/apple/FATPUT#FE1000 -r $2/DEMOS/SDUTILS/FATPUT#FE1000
echo "DEMOS/SDUTILS/FATREADDSK"; atftp $1 --put -l rel/apple/FATREADDSK#FE1000 -r $2/DEMOS/SDUTILS/FATREADDSK#FE1000
echo "DEMOS/SDUTILS/FATWRITEDSK"; atftp $1 --put -l rel/apple/FATWRITEDSK#FE1000 -r $2/DEMOS/SDUTILS/FATWRITEDSK#FE1000
# Net demos
echo "DEMOS/NET/HTTPD"; atftp $1 --put -l rel/HTTPD#FE1000 -r $2/DEMOS/NET/HTTPD#FE1000
atftp $1 --put -l samplesrc/index.html -r $2/DEMOS/NET/INDEX.HTML#040000

7
src/tftprel Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
./tftpsys $1 $2
./tftputil $1 $2
./tftpsane $1 $2
./tftpbld $1 $2
./tftpdemos $1 $2

8
src/tftpsane Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
# SANE libraries
echo "SYS/SANE"; atftp $1 --put -l rel/SANE#FE1000 -r $2/SYS/SANE#FE1000
echo "SYS/FPSTR"; atftp $1 --put -l rel/FPSTR#FE1000 -r $2/SYS/FPSTR#FE1000
echo "SYS/FPU"; atftp $1 --put -l rel/FPU#FE1000 -r $2/SYS/FPU#FE1000
echo "SYS/FP6502.CODE"; atftp $1 --put -l ../sysfiles/FP6502.CODE#060000 -r $2/SYS/FP6502.CODE#060000
echo "SYS/ELEMS.CODE"; atftp $1 --put -l ../sysfiles/ELEMS.CODE#060000 -r $2/SYS/ELEMS.CODE#060000

35
src/tftpsys Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# Core VM, CMDSYS, JITC files
echo "PLASMA.SYSTEM"; atftp $1 --put -l rel/apple/PLASMA.SYSTEM#FF2000 -r $2/PLASMA.SYSTEM#FF2000
echo "PLVM.128"; atftp $1 --put -l rel/apple/PLVM.128#FF2000 -r $2/PLVM.128#FF2000
echo "PLVM16"; atftp $1 --put -l rel/apple/PLVM16#FF2000 -r $2/PLVM16#FF2000
echo "CMD"; atftp $1 --put -l rel/apple/CMD#061000 -r $2/CMD#061000
echo "CMD128"; atftp $1 --put -l rel/apple/CMD128#061000 -r $2/CMD128#061000
echo "SYS/JIT"; atftp $1 --put -l rel/apple/JIT#FE1000 -r $2/SYS/JIT#FE1000
echo "SYS/JIT16"; atftp $1 --put -l rel/apple/JIT16#FE1000 -r $2/SYS/JIT16#FE1000
echo "SYS/JITUNE"; atftp $1 --put -l rel/apple/JITUNE#FE1000 -r $2/SYS/JITUNE#FE1000
# Core libraries
echo "SYS/ARGS"; atftp $1 --put -l rel/ARGS#FE1000 -r $2/SYS/ARGS#FE1000
echo "SYS/INT32"; atftp $1 --put -l rel/INT32#FE1000 -r $2/SYS/INT32#FE1000
echo "SYS/DHCP"; atftp $1 --put -l rel/DHCP#FE1000 -r $2/SYS/DHCP#FE1000
echo "SYS/ETHERIP"; atftp $1 --put -l rel/ETHERIP#FE1000 -r $2/SYS/ETHERIP#FE1000
echo "SYS/MOUSE"; atftp $1 --put -l rel/apple/MOUSE#FE1000 -r $2/SYS/MOUSE#FE1000
echo "SYS/FIBER"; atftp $1 --put -l rel/FIBER#FE1000 -r $2/SYS/FIBER#FE1000
echo "SYS/INET"; atftp $1 --put -l rel/INET#FE1000 -r $2/SYS/INET#FE1000
echo "SYS/LONGJUMP"; atftp $1 --put -l rel/LONGJMP#FE1000 -r $2/SYS/LONGJMP#FE1000
echo "SYS/MEMMGR"; atftp $1 --put -l rel/MEMMGR#FE1000 -r $2/SYS/MEMMGR#FE1000
echo "SYS/LZ4"; atftp $1 --put -l rel/LZ4#FE1000 -r $2/SYS/LZ4#FE1000
echo "SYS/CONIO"; atftp $1 --put -l rel/apple/CONIO#FE1000 -r $2/SYS/CONIO#FE1000
echo "SYS/HGRSPRITE"; atftp $1 --put -l rel/apple/HGRSPRITE#FE1000 -r $2/SYS/HGRSPRITE#FE1000
echo "SYS/LINES"; atftp $1 --put -l rel/LINES#FE1000 -r $2/SYS/LINES#FE1000
echo "SYS/HGRLIB"; atftp $1 --put -l rel/apple/HGRLIB#FE1000 -r $2/SYS/HGRLIB#FE1000
echo "SYS/GRLIB"; atftp $1 --put -l rel/apple/GRLIB#FE1000 -r $2/SYS/GRLIB#FE1000
echo "SYS/DGRLIB"; atftp $1 --put -l rel/apple/DGRLIB#FE1000 -r $2/SYS/DGRLIB#FE1000
echo "SYS/FILEIO"; atftp $1 --put -l rel/apple/FILEIO#FE1000 -r $2/SYS/FILEIO#FE1000
echo "SYS/JOYBUZZ"; atftp $1 --put -l rel/apple/JOYBUZZ#FE1000 -r $2/SYS/JOYBUZZ#FE1000
echo "SYS/SNDSEQ"; atftp $1 --put -l rel/apple/SNDSEQ#FE1000 -r $2/SYS/SNDSEQ#FE1000
echo "SYS/PORTIO"; atftp $1 --put -l rel/apple/PORTIO#FE1000 -r $2/SYS/PORTIO#FE1000
echo "SYS/UTHERNET2";atftp $1 --put -l rel/apple/UTHERNET2#FE1000 -r $2/SYS/UTHERNET2#FE1000
echo "SYS/UTHERNET"; atftp $1 --put -l rel/apple/UTHERNET#FE1000 -r $2/SYS/UTHERNET#FE1000

13
src/tftputil Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
# Core utilities
echo "SYS/ED"; atftp $1 --put -l rel/ED#FE1000 -r $2/SYS/ED#FE1000
echo "SYS/TFTPD"; atftp $1 --put -l rel/TFTPD#FE1000 -r $2/SYS/TFTPD#FE1000
echo "SYS/COPY"; atftp $1 --put -l rel/apple/COPY#FE1000 -r $2/SYS/COPY#FE1000
echo "SYS/DEL"; atftp $1 --put -l rel/apple/DEL#FE1000 -r $2/SYS/DEL#FE1000
echo "SYS/REN"; atftp $1 --put -l rel/apple/REN#FE1000 -r $2/SYS/REN#FE1000
echo "SYS/CAT"; atftp $1 --put -l rel/apple/CAT#FE1000 -r $2/SYS/CAT#FE1000
echo "SYS/NEWDIR"; atftp $1 --put -l rel/apple/NEWDIR#FE1000 -r $2/SYS/NEWDIR#FE1000
echo "SYS/TYPE"; atftp $1 --put -l rel/apple/TYPE#FE1000 -r $2/SYS/TYPE#FE1000
echo "SYS/MON"; atftp $1 --put -l rel/apple/MON#FE1000 -r $2/SYS/MON#FE1000
echo "SYS/SOS"; atftp $1 --put -l rel/apple/SOS#FE1000 -r $2/SYS/SOS#FE1000

View File

@@ -89,6 +89,16 @@ int idconst_add(char *name, int len, int value)
printf("Constant count overflow\n");
return (0);
}
if (idconst_lookup(name, len) > 0)
{
parse_error("const/global name conflict\n");
return (0);
}
if (idglobal_lookup(name, len) > 0)
{
parse_error("global label already defined\n");
return (0);
}
name[len] = '\0';
emit_idconst(name, value);
name[len] = c;
@@ -382,12 +392,13 @@ void emit_header(void)
}
void emit_rld(void)
{
int i;
int i, j;
printf(";\n; RE-LOCATEABLE DICTIONARY\n;\n");
/*
* First emit the bytecode definition entrypoint information.
*/
/*
for (i = 0; i < globals; i++)
if (!(idglobal_type[i] & EXTERN_TYPE) && (idglobal_type[i] & DEF_TYPE))
{
@@ -395,6 +406,14 @@ void emit_rld(void)
printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]);
printf("\t%s\t$00\n", DB);
}
*/
j = outflags & INIT ? defs - 1 : defs;
for (i = 0; i < j; i++)
{
printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB);
printf("\t%s\t_C%03d\t\t\n", DW, i);
printf("\t%s\t$00\n", DB);
}
/*
* Now emit the fixup table.
*/
@@ -600,8 +619,10 @@ void emit_codetag(int tag)
void emit_const(int cval)
{
emit_pending_seq();
if (cval == 0x0000)
printf("\t%s\t$00\t\t\t; ZERO\n", DB);
if ((cval & 0xFFFF) == 0xFFFF)
printf("\t%s\t$20\t\t\t; MINUS ONE\n", DB);
else if ((cval & 0xFFF0) == 0x0000)
printf("\t%s\t$%02X\t\t\t; CN\t%d\n", DB, cval*2, cval);
else if ((cval & 0xFF00) == 0x0000)
printf("\t%s\t$2A,$%02X\t\t\t; CB\t%d\n", DB, cval, cval);
else if ((cval & 0xFF00) == 0xFF00)
@@ -614,6 +635,26 @@ void emit_conststr(long conststr)
printf("\t%s\t$2E\t\t\t; CS\n", DB);
emit_data(0, STRING_TYPE, conststr, 0);
}
void emit_addi(int cval)
{
emit_pending_seq();
printf("\t%s\t$38,$%02X\t\t\t; ADDI\t%d\n", DB, cval, cval);
}
void emit_subi(int cval)
{
emit_pending_seq();
printf("\t%s\t$3A,$%02X\t\t\t; SUBI\t%d\n", DB, cval, cval);
}
void emit_andi(int cval)
{
emit_pending_seq();
printf("\t%s\t$3C,$%02X\t\t\t; ANDI\t%d\n", DB, cval, cval);
}
void emit_ori(int cval)
{
emit_pending_seq();
printf("\t%s\t$3E,$%02X\t\t\t; ORI\t%d\n", DB, cval, cval);
}
void emit_lb(void)
{
printf("\t%s\t$60\t\t\t; LB\n", DB);
@@ -630,6 +671,22 @@ void emit_llw(int index)
{
printf("\t%s\t$66,$%02X\t\t\t; LLW\t[%d]\n", DB, index, index);
}
void emit_addlb(int index)
{
printf("\t%s\t$B0,$%02X\t\t\t; ADDLB\t[%d]\n", DB, index, index);
}
void emit_addlw(int index)
{
printf("\t%s\t$B2,$%02X\t\t\t; ADDLW\t[%d]\n", DB, index, index);
}
void emit_idxlb(int index)
{
printf("\t%s\t$B8,$%02X\t\t\t; IDXLB\t[%d]\n", DB, index, index);
}
void emit_idxlw(int index)
{
printf("\t%s\t$BA,$%02X\t\t\t; IDXLW\t[%d]\n", DB, index, index);
}
void emit_lab(int tag, int offset, int type)
{
if (type)
@@ -658,6 +715,62 @@ void emit_law(int tag, int offset, int type)
printf("\t%s\t$6A,$%02X,$%02X\t\t; LAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
}
}
void emit_addab(int tag, int offset, int type)
{
if (type)
{
int fixup = fixup_new(tag, type, FIXUP_WORD);
char *taglbl = tag_string(tag, type);
printf("\t%s\t$B4\t\t\t; ADDAB\t%s+%d\n", DB, taglbl, offset);
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
}
else
{
printf("\t%s\t$B4,$%02X,$%02X\t\t; ADDAB\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
}
}
void emit_addaw(int tag, int offset, int type)
{
if (type)
{
int fixup = fixup_new(tag, type, FIXUP_WORD);
char *taglbl = tag_string(tag, type);
printf("\t%s\t$B6\t\t\t; ADDAW\t%s+%d\n", DB, taglbl, offset);
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
}
else
{
printf("\t%s\t$B6,$%02X,$%02X\t\t; ADDAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
}
}
void emit_idxab(int tag, int offset, int type)
{
if (type)
{
int fixup = fixup_new(tag, type, FIXUP_WORD);
char *taglbl = tag_string(tag, type);
printf("\t%s\t$BC\t\t\t; IDXAB\t%s+%d\n", DB, taglbl, offset);
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
}
else
{
printf("\t%s\t$BC,$%02X,$%02X\t\t; IDXAB\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
}
}
void emit_idxaw(int tag, int offset, int type)
{
if (type)
{
int fixup = fixup_new(tag, type, FIXUP_WORD);
char *taglbl = tag_string(tag, type);
printf("\t%s\t$BE\t\t\t; IDXAW\t%s+%d\n", DB, taglbl, offset);
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
}
else
{
printf("\t%s\t$BE,$%02X,$%02X\t\t; IDXAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
}
}
void emit_sb(void)
{
printf("\t%s\t$70\t\t\t; SB\n", DB);
@@ -747,11 +860,41 @@ void emit_globaladdr(int tag, int offset, int type)
}
void emit_indexbyte(void)
{
printf("\t%s\t$02\t\t\t; IDXB\n", DB);
printf("\t%s\t$82\t\t\t; IDXB\n", DB);
}
void emit_indexword(void)
{
printf("\t%s\t$1E\t\t\t; IDXW\n", DB);
printf("\t%s\t$9E\t\t\t; IDXW\n", DB);
}
void emit_select(int tag)
{
emit_pending_seq();
printf("\t%s\t$52\t\t\t; SEL\n", DB);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_caseblock(int casecnt, int *caseof, int *casetag)
{
int i;
if (casecnt < 1 || casecnt > 256)
parse_error("Switch count under/overflow\n");
emit_pending_seq();
printf("\t%s\t$%02lX\t\t\t; CASEBLOCK\n", DB, casecnt & 0xFF);
for (i = 0; i < casecnt; i++)
{
printf("\t%s\t$%04lX\n", DW, caseof[i] & 0xFFFF);
printf("\t%s\t_B%03d-*\n", DW, casetag[i]);
}
}
void emit_breq(int tag)
{
printf("\t%s\t$22\t\t\t; BREQ\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_brne(int tag)
{
printf("\t%s\t$24\t\t\t; BRNE\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_brfls(int tag)
{
@@ -769,28 +912,52 @@ void emit_brnch(int tag)
printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_breq(int tag)
void emit_brand(int tag)
{
emit_pending_seq();
printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag);
printf("\t%s\t$AC\t\t\t; BRAND\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_brne(int tag)
void emit_bror(int tag)
{
emit_pending_seq();
printf("\t%s\t$3E\t\t\t; BRNE\t_B%03d\n", DB, tag);
printf("\t%s\t$AE\t\t\t; BROR\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_brgt(int tag)
{
emit_pending_seq();
printf("\t%s\t$38\t\t\t; BRGT\t_B%03d\n", DB, tag);
printf("\t%s\t$A0\t\t\t; BRGT\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_brlt(int tag)
{
emit_pending_seq();
printf("\t%s\t$3A\t\t\t; BRLT\t_B%03d\n", DB, tag);
printf("\t%s\t$A2\t\t\t; BRLT\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_incbrle(int tag)
{
emit_pending_seq();
printf("\t%s\t$A4\t\t\t; INCBRLE\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_addbrle(int tag)
{
emit_pending_seq();
printf("\t%s\t$A6\t\t\t; ADDBRLE\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_decbrge(int tag)
{
emit_pending_seq();
printf("\t%s\t$A8\t\t\t; DECBRGE\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_subbrge(int tag)
{
emit_pending_seq();
printf("\t%s\t$AA\t\t\t; SUBBRGE\t_B%03d\n", DB, tag);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_call(int tag, int type)
@@ -839,11 +1006,17 @@ void emit_start(void)
void emit_drop(void)
{
emit_pending_seq();
printf("\t%s\t$30\t\t\t; DROP\n", DB);
printf("\t%s\t$30\t\t\t; DROP \n", DB);
}
void emit_drop2(void)
{
emit_pending_seq();
printf("\t%s\t$32\t\t\t; DROP2\n", DB);
}
void emit_dup(void)
{
printf("\t%s\t$32\t\t\t; DUP\n", DB);
emit_pending_seq();
printf("\t%s\t$34\t\t\t; DUP\n", DB);
}
int emit_unaryop(t_token op)
{
@@ -851,19 +1024,19 @@ int emit_unaryop(t_token op)
switch (op)
{
case NEG_TOKEN:
printf("\t%s\t$10\t\t\t; NEG\n", DB);
printf("\t%s\t$90\t\t\t; NEG\n", DB);
break;
case COMP_TOKEN:
printf("\t%s\t$12\t\t\t; COMP\n", DB);
printf("\t%s\t$92\t\t\t; COMP\n", DB);
break;
case LOGIC_NOT_TOKEN:
printf("\t%s\t$20\t\t\t; NOT\n", DB);
printf("\t%s\t$80\t\t\t; NOT\n", DB);
break;
case INC_TOKEN:
printf("\t%s\t$0C\t\t\t; INCR\n", DB);
printf("\t%s\t$8C\t\t\t; INCR\n", DB);
break;
case DEC_TOKEN:
printf("\t%s\t$0E\t\t\t; DECR\n", DB);
printf("\t%s\t$8E\t\t\t; DECR\n", DB);
break;
case BPTR_TOKEN:
emit_lb();
@@ -883,34 +1056,34 @@ int emit_op(t_token op)
switch (op)
{
case MUL_TOKEN:
printf("\t%s\t$06\t\t\t; MUL\n", DB);
printf("\t%s\t$86\t\t\t; MUL\n", DB);
break;
case DIV_TOKEN:
printf("\t%s\t$08\t\t\t; DIV\n", DB);
printf("\t%s\t$88\t\t\t; DIV\n", DB);
break;
case MOD_TOKEN:
printf("\t%s\t$0A\t\t\t; MOD\n", DB);
printf("\t%s\t$8A\t\t\t; MOD\n", DB);
break;
case ADD_TOKEN:
printf("\t%s\t$02\t\t\t; ADD\n", DB);
printf("\t%s\t$82\t\t\t; ADD \n", DB);
break;
case SUB_TOKEN:
printf("\t%s\t$04\t\t\t; SUB\n", DB);
printf("\t%s\t$84\t\t\t; SUB \n", DB);
break;
case SHL_TOKEN:
printf("\t%s\t$1A\t\t\t; SHL\n", DB);
printf("\t%s\t$9A\t\t\t; SHL\n", DB);
break;
case SHR_TOKEN:
printf("\t%s\t$1C\t\t\t; SHR\n", DB);
printf("\t%s\t$9C\t\t\t; SHR\n", DB);
break;
case AND_TOKEN:
printf("\t%s\t$14\t\t\t; AND\n", DB);
printf("\t%s\t$94\t\t\t; AND \n", DB);
break;
case OR_TOKEN:
printf("\t%s\t$16\t\t\t; IOR\n", DB);
printf("\t%s\t$96\t\t\t; OR \n", DB);
break;
case EOR_TOKEN:
printf("\t%s\t$18\t\t\t; XOR\n", DB);
printf("\t%s\t$98\t\t\t; XOR\n", DB);
break;
case EQ_TOKEN:
printf("\t%s\t$40\t\t\t; ISEQ\n", DB);
@@ -930,12 +1103,6 @@ int emit_op(t_token op)
case LE_TOKEN:
printf("\t%s\t$4A\t\t\t; ISLE\n", DB);
break;
case LOGIC_OR_TOKEN:
printf("\t%s\t$22\t\t\t; LOR\n", DB);
break;
case LOGIC_AND_TOKEN:
printf("\t%s\t$24\t\t\t; LAND\n", DB);
break;
case COMMA_TOKEN:
break;
default:
@@ -1067,7 +1234,11 @@ int crunch_seq(t_opseq **seq, int pass)
{
op->code = DUP_CODE;
opnext->code = BINARY_CODE(ADD_TOKEN);
crunched = 1;
break;
}
if (opnext->code == BINARY_CODE(MUL_TOKEN) || opnext->code == BINARY_CODE(DIV_TOKEN))
{
freeops = -2;
break;
}
}
@@ -1127,6 +1298,22 @@ int crunch_seq(t_opseq **seq, int pass)
freeops = 1;
}
break;
case BRGT_CODE:
if (opprev && (opprev->code == CONST_CODE) && (op->val <= opprev->val))
freeops = 1;
break;
case BRLT_CODE:
if (opprev && (opprev->code == CONST_CODE) && (op->val >= opprev->val))
freeops = 1;
break;
case BROR_CODE:
if (!op->val)
freeops = -2; // Remove zero constant
break;
case BRAND_CODE:
if (op->val)
freeops = -2; // Remove non-zero constant
break;
case NE_CODE:
if (!op->val)
freeops = -2; // Remove ZERO:ISNE
@@ -1207,32 +1394,96 @@ int crunch_seq(t_opseq **seq, int pass)
op->val = op->val <= opnext->val ? 1 : 0;
freeops = 2;
break;
case BINARY_CODE(LOGIC_OR_TOKEN):
op->val = op->val || opnext->val ? 1 : 0;
freeops = 2;
break;
case BINARY_CODE(LOGIC_AND_TOKEN):
op->val = op->val && opnext->val ? 1 : 0;
freeops = 2;
break;
}
// End of collapse constant operation
if ((pass > 0) && (freeops == 0) && (op->val != 0))
crunched = try_dupify(op);
break; // CONST_CODE
case BINARY_CODE(MUL_TOKEN):
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
case BINARY_CODE(ADD_TOKEN):
if (op->val == 0)
{
if (op->val == (1 << shiftcnt))
freeops = -2;
}
else if (op->val > 0 && op->val <= 255)
{
op->code = ADDI_CODE;
freeops = 1;
}
else if (op->val >= -255 && op->val < 0)
{
op->code = SUBI_CODE;
op->val = -op->val;
freeops = 1;
}
break;
case BINARY_CODE(SUB_TOKEN):
if (op->val == 0)
{
freeops = -2;
}
else if (op->val > 0 && op->val <= 255)
{
op->code = SUBI_CODE;
freeops = 1;
}
else if (op->val >= -255 && op->val < 0)
{
op->code = ADDI_CODE;
op->val = -op->val;
freeops = 1;
}
break;
case BINARY_CODE(AND_TOKEN):
if (op->val >= 0 && op->val <= 255)
{
op->code = ANDI_CODE;
freeops = 1;
}
break;
case BINARY_CODE(OR_TOKEN):
if (op->val == 0)
{
freeops = -2;
}
else if (op->val > 0 && op->val <= 255)
{
op->code = ORI_CODE;
freeops = 1;
}
break;
case BINARY_CODE(MUL_TOKEN):
if (op->val == 0)
{
op->code = DROP_CODE;
opnext->code = CONST_CODE;
opnext->val = 0;
}
else if (op->val == 2)
{
op->code = DUP_CODE;
opnext->code = BINARY_CODE(ADD_TOKEN);
}
else
{
//
// Constants 0, 1 and 2 handled above
//
for (shiftcnt = 2; shiftcnt < 16; shiftcnt++)
{
op->val = shiftcnt;
opnext->code = BINARY_CODE(SHL_TOKEN);
break;
if (op->val == (1 << shiftcnt))
{
op->val = shiftcnt;
opnext->code = BINARY_CODE(SHL_TOKEN);
break;
}
}
}
break;
case BINARY_CODE(DIV_TOKEN):
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
//
// Constant 1 handled above
//
for (shiftcnt = 1; shiftcnt < 16; shiftcnt++)
{
if (op->val == (1 << shiftcnt))
{
@@ -1325,7 +1576,17 @@ int crunch_seq(t_opseq **seq, int pass)
crunched = try_dupify(op);
break; // GADDR_CODE
case LLB_CODE:
if (pass > 0)
if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE))
{
op->code = ADDLB_CODE;
freeops = 1;
}
else if (opnext->code == INDEXW_CODE)
{
op->code = IDXLB_CODE;
freeops = 1;
}
else if (pass > 0)
crunched = try_dupify(op);
break; // LLB_CODE
case LLW_CODE:
@@ -1343,11 +1604,31 @@ int crunch_seq(t_opseq **seq, int pass)
}
}
}
if ((pass > 0) && (freeops == 0))
else if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE))
{
op->code = ADDLW_CODE;
freeops = 1;
}
else if (opnext->code == INDEXW_CODE)
{
op->code = IDXLW_CODE;
freeops = 1;
}
else if (pass > 0)
crunched = try_dupify(op);
break; // LLW_CODE
case LAB_CODE:
if ((pass > 0) && (op->type || !is_hardware_address(op->offsz)))
if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE))
{
op->code = ADDAB_CODE;
freeops = 1;
}
else if (opnext->code == INDEXW_CODE)
{
op->code = IDXAB_CODE;
freeops = 1;
}
else if ((pass > 0) && (op->type || !is_hardware_address(op->offsz)))
crunched = try_dupify(op);
break; // LAB_CODE
case LAW_CODE:
@@ -1365,8 +1646,17 @@ int crunch_seq(t_opseq **seq, int pass)
}
}
}
if ((pass > 0) && (freeops == 0) &&
(op->type || !is_hardware_address(op->offsz)))
else if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE))
{
op->code = ADDAW_CODE;
freeops = 1;
}
else if (opnext->code == INDEXW_CODE)
{
op->code = IDXAW_CODE;
freeops = 1;
}
else if ((pass > 0) && (op->type || !is_hardware_address(op->offsz)))
crunched = try_dupify(op);
break; // LAW_CODE
case LOGIC_NOT_CODE:
@@ -1384,6 +1674,36 @@ int crunch_seq(t_opseq **seq, int pass)
break;
}
break; // LOGIC_NOT_CODE
case EQ_CODE:
switch (opnext->code)
{
case BRFALSE_CODE:
op->code = BRNE_CODE;
op->tag = opnext->tag;
freeops = 1;
break;
case BRTRUE_CODE:
op->code = BREQ_CODE;
op->tag = opnext->tag;
freeops = 1;
break;
}
break; // EQ_CODE
case NE_CODE:
switch (opnext->code)
{
case BRFALSE_CODE:
op->code = BREQ_CODE;
op->tag = opnext->tag;
freeops = 1;
break;
case BRTRUE_CODE:
op->code = BRNE_CODE;
op->tag = opnext->tag;
freeops = 1;
break;
}
break; // NE_CODE
case SLB_CODE:
if ((opnext->code == LLB_CODE) && (op->offsz == opnext->offsz))
{
@@ -1577,8 +1897,6 @@ int emit_pending_seq()
case LT_CODE:
case GT_CODE:
case LE_CODE:
case LOGIC_OR_CODE:
case LOGIC_AND_CODE:
emit_op(op->code);
break;
case CONST_CODE:
@@ -1587,6 +1905,18 @@ int emit_pending_seq()
case STR_CODE:
emit_conststr(op->val);
break;
case ADDI_CODE:
emit_addi(op->val);
break;
case SUBI_CODE:
emit_subi(op->val);
break;
case ANDI_CODE:
emit_andi(op->val);
break;
case ORI_CODE:
emit_ori(op->val);
break;
case LB_CODE:
emit_lb();
break;
@@ -1599,12 +1929,36 @@ int emit_pending_seq()
case LLW_CODE:
emit_llw(op->offsz);
break;
case ADDLB_CODE:
emit_addlb(op->offsz);
break;
case ADDLW_CODE:
emit_addlw(op->offsz);
break;
case IDXLB_CODE:
emit_idxlb(op->offsz);
break;
case IDXLW_CODE:
emit_idxlw(op->offsz);
break;
case LAB_CODE:
emit_lab(op->tag, op->offsz, op->type);
break;
case LAW_CODE:
emit_law(op->tag, op->offsz, op->type);
break;
case ADDAB_CODE:
emit_addab(op->tag, op->offsz, op->type);
break;
case ADDAW_CODE:
emit_addaw(op->tag, op->offsz, op->type);
break;
case IDXAB_CODE:
emit_idxab(op->tag, op->offsz, op->type);
break;
case IDXAW_CODE:
emit_idxaw(op->tag, op->offsz, op->type);
break;
case SB_CODE:
emit_sb();
break;
@@ -1662,12 +2016,30 @@ int emit_pending_seq()
case BRNCH_CODE:
emit_brnch(op->tag);
break;
case BRAND_CODE:
emit_brand(op->tag);
break;
case BROR_CODE:
emit_bror(op->tag);
break;
case BREQ_CODE:
emit_breq(op->tag);
break;
case BRNE_CODE:
emit_brne(op->tag);
break;
case BRFALSE_CODE:
emit_brfls(op->tag);
break;
case BRTRUE_CODE:
emit_brtru(op->tag);
break;
case BRGT_CODE:
emit_brgt(op->tag);
break;
case BRLT_CODE:
emit_brlt(op->tag);
break;
case CODETAG_CODE:
printf("_B%03d%c\n", op->tag, LBL);
break;

View File

@@ -31,8 +31,6 @@ typedef struct _opseq {
#define LT_CODE (0x0200|LT_TOKEN)
#define GT_CODE (0x0200|GT_TOKEN)
#define LE_CODE (0x0200|LE_TOKEN)
#define LOGIC_OR_CODE (0x0200|LOGIC_OR_TOKEN)
#define LOGIC_AND_CODE (0x0200|LOGIC_AND_TOKEN)
#define CONST_CODE 0x0300
#define STR_CODE 0x0301
#define LB_CODE 0x0302
@@ -59,11 +57,29 @@ typedef struct _opseq {
#define INDEXW_CODE 0x0317
#define DROP_CODE 0x0318
#define DUP_CODE 0x0319
#define BRNCH_CODE 0x031C
#define BRFALSE_CODE 0x031D
#define BRTRUE_CODE 0x031E
#define CODETAG_CODE 0x031F
#define NOP_CODE 0x0320
#define ADDI_CODE 0x031A
#define SUBI_CODE 0x031B
#define ANDI_CODE 0x031C
#define ORI_CODE 0x31D
#define BRNCH_CODE 0x0320
#define BRFALSE_CODE 0x0321
#define BRTRUE_CODE 0x0322
#define BREQ_CODE 0x0323
#define BRNE_CODE 0x0324
#define BRAND_CODE 0x0325
#define BROR_CODE 0x0326
#define BRLT_CODE 0x0327
#define BRGT_CODE 0x0328
#define CODETAG_CODE 0x0329
#define NOP_CODE 0x032A
#define ADDLB_CODE 0x0330
#define ADDLW_CODE 0x0331
#define ADDAB_CODE 0x0332
#define ADDAW_CODE 0x0333
#define IDXLB_CODE 0x0334
#define IDXLW_CODE 0x0335
#define IDXAB_CODE 0x0336
#define IDXAW_CODE 0x0337
#define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0)
#define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0)
@@ -79,6 +95,10 @@ typedef struct _opseq {
#define gen_sw(seq) gen_seq(seq,SW_CODE,0,0,0,0)
#define gen_icall(seq) gen_seq(seq,ICAL_CODE,0,0,0,0)
#define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0)
#define gen_brand(seq,tag) gen_seq(seq,BRAND_CODE,0,tag,0,0)
#define gen_bror(seq,tag) gen_seq(seq,BROR_CODE,0,tag,0,0)
#define gen_brgt(seq,tag) gen_seq(seq,BRGT_CODE,0,tag,0,0)
#define gen_brlt(seq,tag) gen_seq(seq,BRLT_CODE,0,tag,0,0)
#define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0)
#define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0)
#define gen_brnch(seq,tag) gen_seq(seq,BRNCH_CODE,0,tag,0,0)
@@ -102,6 +122,10 @@ int emit_data(int vartype, int consttype, long constval, int constsize);
void emit_codetag(int tag);
void emit_const(int cval);
void emit_conststr(long conststr);
void emit_addi(int cval);
void emit_subi(int cval);
void emit_andi(int cval);
void emit_ori(int cval);
void emit_lb(void);
void emit_lw(void);
void emit_llb(int index);
@@ -126,14 +150,23 @@ void emit_indexbyte(void);
void emit_indexword(void);
int emit_unaryop(t_token op);
int emit_op(t_token op);
void emit_select(int tag);
void emit_caseblock(int casecnt, int *caseof, int *casetag);
void emit_brand(int tag);
void emit_bror(int tag);
void emit_brtru(int tag);
void emit_brfls(int tag);
void emit_brgt(int tag);
void emit_brlt(int tag);
void emit_brne(int tag);
void emit_brnch(int tag);
void emit_brgt(int tag);
void emit_brlt(int tag);
void emit_addbrle(int tag);
void emit_incbrle(int tag);
void emit_subbrge(int tag);
void emit_decbrge(int tag);
void emit_empty(void);
void emit_drop(void);
void emit_drop2(void);
void emit_dup(void);
void emit_leave(void);
void emit_ret(void);

View File

@@ -132,8 +132,10 @@ def emit_codeseg#0
end
def emit_const(cval)#0
emit_pending_seq
if cval == $0000 // ZERO
emit_byte($00)
if cval == $FFFF // MINUS ONE
emit_byte($20)
elsif cval & $FFF0 == $0000 // Constant NYBBLE
emit_byte(cval*2)
elsif cval & $FF00 == $0000 // Constant BYTE
emit_byte($2A)
emit_byte(cval)
@@ -151,6 +153,26 @@ def emit_code(bval)#0
codeptr++
if codeptr - codebuff > codebufsz; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin
end
def emit_slb(offset)#0
emit_pending_seq
emit_byte($74)
emit_byte(offset)
end
def emit_slw(offset)#0
emit_pending_seq
emit_byte($76)
emit_byte(offset)
end
def emit_sab(tag, offset)#0
emit_pending_seq
emit_byte($78)
emit_addr(tag, offset)
end
def emit_saw(tag, offset)#0
emit_pending_seq
emit_byte($7A)
emit_addr(tag, offset)
end
def emit_dlb(offset)#0
emit_pending_seq
emit_byte($6C)
@@ -171,26 +193,67 @@ def emit_daw(tag, offset)#0
emit_byte($7E)
emit_addr(tag, offset)
end
def emit_brgt(tag)#0
def emit_select(tag)#0
emit_pending_seq
emit_byte($38)
emit_byte($52)
emit_reladdr(tag)
end
def emit_brlt(tag)#0
def emit_caseblock(cnt, oflist, taglist)#0
byte i
if not cnt or cnt > 256; exit_err(ERR_OVER|ERR_STATE); fin
emit_pending_seq
emit_byte($3A)
emit_reladdr(tag)
end
def emit_brne(tag)#0
emit_pending_seq
emit_byte($3E)
emit_reladdr(tag)
emit_byte(cnt)
for i = 0 to cnt-1
emit_word(oflist=>[i])
emit_reladdr(taglist=>[i])
next
end
def emit_branch(tag)#0
emit_pending_seq
emit_byte($50)
emit_reladdr(tag)
end
def emit_brgt(tag)#0
emit_pending_seq
emit_byte($A0)
emit_reladdr(tag)
end
def emit_brlt(tag)#0
emit_pending_seq
emit_byte($A2)
emit_reladdr(tag)
end
def emit_incbrle(tag)#0
emit_pending_seq
emit_byte($A4)
emit_reladdr(tag)
end
def emit_addbrle(tag)#0
emit_pending_seq
emit_byte($A6)
emit_reladdr(tag)
end
def emit_decbrge(tag)#0
emit_pending_seq
emit_byte($A8)
emit_reladdr(tag)
end
def emit_subbrge(tag)#0
emit_pending_seq
emit_byte($AA)
emit_reladdr(tag)
end
def emit_brand(tag)#0
emit_pending_seq
emit_byte($AC)
emit_reladdr(tag)
end
def emit_bror(tag)#0
emit_pending_seq
emit_byte($AE)
emit_reladdr(tag)
end
def emit_leave#0
emit_pending_seq
if framesize
@@ -266,8 +329,11 @@ def emit_pending_seq#0
//
is CONST_GROUP
if op->opcode == CONST_CODE
if op=>opval == $0000 // ZERO
^codeptr = $00
if op=>opval == $FFFF // MINUS 1
^codeptr = $20
codeptr++
elsif op=>opval & $FFF0 == $0000 // Constant NYBBLE
^codeptr = op->opval*2
codeptr++
elsif op=>opval & $FF00 == $0000 // Constant BYTE
*codeptr = $2A | (op->opval << 8)
@@ -280,6 +346,9 @@ def emit_pending_seq#0
codeptr=>1 = op=>opval
codeptr = codeptr + 3
fin
else
*codeptr = op->opcode | (op->opval << 8) // IMMEDIATE BYTE OP
codeptr = codeptr + 2
fin
break
//
@@ -382,9 +451,10 @@ def idmatch(nameptr, len, idptr, idcnt)
while idcnt
if len == idptr->idname
for i = 1 to len
if nameptr->[i - 1] <> idptr->idname.[i]; break; fin
next
i = 1; while i <= len and nameptr->[i - 1] == idptr->idname.[i]; i++; loop
//for i = 1 to len
// if nameptr->[i - 1] <> idptr->idname.[i]; break; fin
//next
if i > len; return idptr; fin
fin
idptr = idptr + idptr->idname + t_id
@@ -479,11 +549,13 @@ def init_idglobal#0
word op
word i
dfd_num = DFDNUM
tag_num = TAGNUM
fixup_num = FIXUPNUM
globalbufsz = IDGLOBALSZ
localbufsz = IDLOCALSZ
if isult(heapavail, $8000)
if isult(heapavail, $6000)
dfd_num = DFDNUM/2
tag_num = TAGNUM/2
fixup_num = FIXUPNUM/2
globalbufsz = IDGLOBALSZ
@@ -502,6 +574,7 @@ def init_idglobal#0
//
// Allocate remaining buffers
//
dfd_tag = heapalloc(dfd_num*2)
tag_addr = heapalloc(tag_num*2)
tag_type = heapalloc(tag_num)
fixup_tag = heapalloc(fixup_num*2)
@@ -512,7 +585,6 @@ def init_idglobal#0
codebuff = heapalloc(codebufsz)
codeptr = codebuff
lastglobal = idglobal_tbl
puts("Data+Code buffer size = "); puti(codebufsz); putln
end
def new_idlocal(nameptr, len, type, size)#0
if idmatch(nameptr, len, @idlocal_tbl, locals); exit_err(ERR_DUP|ERR_ID); fin
@@ -534,13 +606,15 @@ def save_idlocal#0
savelocals = locals
savesize = framesize
savelast = lastlocal
memcpy(heapmark, idlocal_tbl, lastlocal - idlocal_tbl)
savetbl = heapalloc(lastlocal - idlocal_tbl)
memcpy(savetbl, idlocal_tbl, lastlocal - idlocal_tbl)
end
def restore_idlocal#0
locals = savelocals
framesize = savesize
lastlocal = savelast
memcpy(idlocal_tbl, heapmark, lastlocal - idlocal_tbl)
memcpy(idlocal_tbl, savetbl, lastlocal - idlocal_tbl)
heaprelease(savetbl)
end
//
// Module dependency list
@@ -554,6 +628,14 @@ def new_moddep(nameptr, len)#0
if moddep_cnt > MODDEPNUM; parse_warn("Module dependency overflow"); fin
end
//
// DFD list
//
def new_dfd(tag)#0
if dfd_cnt >= dfd_num; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin
dfd_tag=>[dfd_cnt] = tag
dfd_cnt++
end
//
// Generate/add to a sequence of code
//
def gen_op(seq, code)
@@ -690,15 +772,15 @@ def gen_uop(seq, tkn)
fin
when tkn
is NEG_TKN
code = $10; break
code = $90; break
is COMP_TKN
code = $12; break
code = $92; break
is LOGIC_NOT_TKN
code = $20; break
code = $80; break
is INC_TKN
code = $0C; break
code = $8C; break
is DEC_TKN
code = $0E; break
code = $8E; break
is BPTR_TKN
code = $60; break
is WPTR_TKN
@@ -725,25 +807,25 @@ def gen_bop(seq, tkn)
fin
when tkn
is MUL_TKN
code = $06; break
code = $86; break
is DIV_TKN
code = $08; break
code = $88; break
is MOD_TKN
code = $0A; break
code = $8A; break
is ADD_TKN
code = $02; break
code = $82; break
is SUB_TKN
code = $04; break
code = $84; break
is SHL_TKN
code = $1A; break
code = $9A; break
is SHR_TKN
code = $1C; break
code = $9C; break
is AND_TKN
code = $14; break
code = $94; break
is OR_TKN
code = $16; break
code = $96; break
is EOR_TKN
code = $18; break
code = $98; break
is EQ_TKN
code = $40; break
is NE_TKN
@@ -756,10 +838,6 @@ def gen_bop(seq, tkn)
code = $44; break
is LE_TKN
code = $4A; break
is LOGIC_OR_TKN
code = $22; break
is LOGIC_AND_TKN
code = $24; break
otherwise
exit_err(ERR_INVAL|ERR_SYNTAX)
wend
@@ -824,30 +902,27 @@ end
// Write DeFinition Directory
//
def writeDFD(refnum, modfix)#0
word dfd, idptr, idcnt
word dfd, idptr, cnt
byte defdir[128]
dfd, idptr, idcnt = @defdir, idglobal_tbl, globals
while idcnt
if idptr=>idtype & (FUNC_TYPE|EXTERN_TYPE) == FUNC_TYPE
dfd->0 = $02
dfd=>1 = tag_addr=>[idptr=>idval] + modfix
dfd->3 = 0
dfd = dfd + 4
fin
idptr = idptr + idptr->idname + t_id
idcnt--
loop
dfd = @defdir
for cnt = 0 to dfd_cnt-1
dfd->0 = $02
dfd=>1 = tag_addr=>[dfd_tag=>[cnt]] + modfix
dfd->3 = 0
dfd = dfd + 4
next
fileio:write(refnum, @defdir, dfd - @defdir)
end
//
// Build External Symbol Directory on heap
//
def buildESD(modfix)#2
word modofst, esd, idptr, idcnt, len
word modofst, esdtbl, esd, idptr, idcnt, len
byte symnum
symnum, esd, idptr, idcnt = 0, heapmark, idglobal_tbl, globals
symnum, esdtbl, idptr, idcnt = 0, heapalloc(heapavail - 256), idglobal_tbl, globals
esd = esdtbl
while idcnt
if idptr=>idtype & EXPORT_TYPE
esd = esd + stodci(@idptr->idname, esd)
@@ -866,26 +941,27 @@ def buildESD(modfix)#2
idcnt--
loop
^esd = 0
len = esd - heapmark + 1
esd = heapalloc(len)
return esd, len
len = esd - esdtbl + 1
heaprelease(esdtbl + len)
return esdtbl, len
end
//
// Write ReLocation Directory
//
def writeRLD(refnum, modofst)#0
word rld, rldlen, fixups, updtptr, idptr, idcnt, tag
word rldtbl, rld, rldlen, fixups, updtptr, idptr, idcnt, tag
byte type
rld = heapmark
rldtbl = heapalloc(heapavail - 256)
rld = rldtbl
rldlen = 0
for fixups = fixup_cnt-1 downto 0
tag = fixup_tag=>[fixups]
type = tag_type->[tag]
if not (type & RELATIVE_FIXUP)
if rldlen == 64 // Write out blocks of entries
fileio:write(refnum, heapmark, rld - heapmark)
rld = heapmark
fileio:write(refnum, rldtbl, rld - rldtbl)
rld = rldtbl
rldlen = 0
fin
if type & EXTERN_FIXUP
@@ -907,7 +983,8 @@ def writeRLD(refnum, modofst)#0
fin
next
^rld = 0
fileio:write(refnum, heapmark, rld - heapmark + 1)
fileio:write(refnum, rldtbl, rld - rldtbl + 1)
heaprelease(rldtbl)
end
//
// Write Extended REL file

View File

@@ -83,7 +83,10 @@ def crunch_seq(seq, pass)
op->opcode = DUP_CODE
op->opgroup = STACK_GROUP
nextop->opcode = ADD_CODE
crunched = 1
break
fin
if nextop->opcode == MUL_CODE or nextop->opcode == DIV_CODE
freeops = -2
break
fin
fin
@@ -120,6 +123,26 @@ def crunch_seq(seq, pass)
freeops = 1
fin
break
is BRGT_CODE
if opprev and (opprev->opcode == CONST_CODE) and (op=>opval <= opprev=>opval)
freeops = 1
fin
break
is BRLT_CODE
if opprev and (opprev->opcode == CONST_CODE) and (op=>opval >= opprev=>opval)
freeops = 1
fin
break
is BROR_CODE
if not op=>opval
freeops = -2 // Remove zero constant
fin
break
is BRAND_CODE
if op=>opval
freeops = -2 // Remove non-zero constant
fin
break
is NE_CODE
if not op=>opval
freeops = -2 // Remove ZERO:ISNE
@@ -129,7 +152,7 @@ def crunch_seq(seq, pass)
if not op=>opval
op->opcode = LOGIC_NOT_CODE // Replace ZERO:ISEQ
op->opgroup = STACK_GROUP
freeops = 1
freeops = 1
fin
break
is CONST_CODE // Collapse constant operation
@@ -200,31 +223,73 @@ def crunch_seq(seq, pass)
op=>opval = op=>opval <= nextop=>opval
freeops = 2
break
is LOGIC_OR_CODE
op=>opval = op=>opval or nextop=>opval
freeops = 2
break
is LOGIC_AND_CODE
op=>opval = op=>opval and nextop=>opval
freeops = 2
break
wend // End of collapse constant operation
fin
if pass and not freeops and op=>opval
crunched = try_dupify(op)
fin
break // CONST_CODE
is ADD_CODE
if op=>opval == 0
freeops = -2
elsif op=>opval > 0 and op=>opval <= 255
op->opcode = ADDI_CODE
freeops = 1
elsif op=>opval >= -255 and op=>opval < 0
op->opcode = SUBI_CODE
op=>opval = -op=>opval
freeops = 1
fin
break
is SUB_CODE
if op=>opval == 0
freeops = -2
elsif op=>opval > 0 and op=>opval <= 255
op->opcode = SUBI_CODE
freeops = 1
elsif op=>opval >= -255 and op=>opval < 0
op->opcode = ADDI_CODE
op=>opval = -op=>opval
freeops = 1
fin
break
is AND_CODE
if op=>opval >= 0 and op=>opval <= 255
op->opcode = ANDI_CODE
freeops = 1
fin
break
is OR_CODE
if op=>opval == 0
freeops = -2
elsif op=>opval > 0 and op=>opval <= 255
op->opcode = ORI_CODE
freeops = 1
fin
break
is MUL_CODE
for shiftcnt = 0 to 15
if op=>opval == 1 << shiftcnt
op=>opval = shiftcnt
nextop->opcode = SHL_CODE
break
fin
next
if op=>opval == 0
op->opcode = DROP_CODE
op->opgroup = STACK_GROUP
nextop->opcode = CONST_CODE
nextop->opgroup = CONST_GROUP
nextop=>opval = 0
elsif op=>opval == 2
op->opcode = DUP_CODE
op->opgroup = STACK_GROUP
nextop->opcode = ADD_CODE
else
for shiftcnt = 2 to 15
if op=>opval == 1 << shiftcnt
op=>opval = shiftcnt
nextop->opcode = SHL_CODE
break
fin
next
fin
break
is DIV_CODE
for shiftcnt = 0 to 15
for shiftcnt = 1 to 15
if op=>opval == 1 << shiftcnt
op=>opval = shiftcnt
nextop->opcode = SHR_CODE
@@ -240,7 +305,7 @@ def crunch_seq(seq, pass)
if nextop=>opnext
nextopnext = nextop=>opnext
when nextopnext->opcode
is INDEXB_CODE // ADD_CODE
is ADD_CODE // INDEXB_CODE
op=>opoffset = op=>opoffset + nextop=>opval
freeops = 2
break
@@ -278,7 +343,7 @@ def crunch_seq(seq, pass)
if nextop=>opnext
nextopnext = nextop=>opnext
when nextopnext->opcode
is INDEXB_CODE // ADD_CODE
is ADD_CODE // INDEXB_CODE
op=>opoffset = op=>opoffset + nextop=>opval
freeops = 2
break
@@ -315,45 +380,85 @@ def crunch_seq(seq, pass)
fin
break // GADDR_CODE
is LLB_CODE
if pass
when nextop->opcode
is ADD_CODE // INDEXB_CODE
op->opcode = ADDLB_CODE
freeops = 1
break
is INDEXW_CODE
op->opcode = IDXLB_CODE
freeops = 1
break
wend
if pass and not freeops
crunched = try_dupify(op)
fin
break // LLB_CODE
is LLW_CODE
// LLW [n]:CB 8:SHR -> LLB [n+1]
if nextop->opcode == CONST_CODE and nextop=>opval == 8
if nextop=>opnext
nextopnext = nextop=>opnext
if nextopnext->opcode == SHR_CODE
op->opcode = LLB_CODE
op=>opoffset++
freeops = 2
break
when nextop->opcode
is ADD_CODE // INDEXB_CODE
op->opcode = ADDLW_CODE
freeops = 1
break
is INDEXW_CODE
op->opcode = IDXLW_CODE
freeops = 1
break
is CONST_CODE
// LLW [n]:CB 8:SHR -> LLB [n+1]
if nextop=>opval == 8 and nextop=>opnext
nextopnext = nextop=>opnext
if nextopnext->opcode == SHR_CODE
op->opcode = LLB_CODE
op=>opoffset++
freeops = 2
break
fin
fin
fin
fin
break
wend
if pass and not freeops
crunched = try_dupify(op)
fin
break // LLW_CODE
is LAB_CODE
if pass and not is_hardware_address(op=>opoffset)
when nextop->opcode
is ADD_CODE // INDEXB_CODE
op->opcode = ADDAB_CODE
freeops = 1
break
is INDEXW_CODE
op->opcode = IDXAB_CODE
freeops = 1
break
wend
if pass and not freeops and not is_hardware_address(op=>opoffset)
crunched = try_dupify(op)
fin
break // LAB_CODE
is LAW_CODE
// LAW x:CB 8:SHR -> LAB x+1
if nextop->opcode == CONST_CODE and nextop=>opval == 8
if nextop=>opnext
nextopnext = nextop=>opnext
if nextopnext->opcode == SHR_CODE
op->opcode = LAB_CODE
op=>opoffset++
freeops = 2
break
when nextop->opcode
is ADD_CODE // INDEXB_CODE
op->opcode = ADDAW_CODE
freeops = 1
break
is INDEXW_CODE
op->opcode = IDXAW_CODE
freeops = 1
break
is CONST_CODE
// LLW [n]:CB 8:SHR -> LLB [n+1]
if nextop=>opval == 8 and nextop=>opnext
nextopnext = nextop=>opnext
if nextopnext->opcode == SHR_CODE
op->opcode = LAB_CODE
op=>opoffset++
freeops = 2
break
fin
fin
fin
fin
break
wend
if pass and not freeops and not is_hardware_address(op=>opoffset)
crunched = try_dupify(op)
fin
@@ -374,6 +479,38 @@ def crunch_seq(seq, pass)
break
wend
break // LOGIC_NOT_CODE
is EQ_CODE
when nextop->opcode
is BRFALSE_CODE
op->opcode = BRNE_CODE
op->opgroup = RELATIVE_GROUP
op=>optag = nextop=>optag
freeops = 1
break
is BRTRUE_CODE
op->opcode = BREQ_CODE
op->opgroup = RELATIVE_GROUP
op=>optag = nextop=>optag
freeops = 1
break
wend
break // EQ_CODE
is NE_CODE
when nextop->opcode
is BRFALSE_CODE
op->opcode = BREQ_CODE
op->opgroup = RELATIVE_GROUP
op=>optag = nextop=>optag
freeops = 1
break
is BRTRUE_CODE
op->opcode = BRNE_CODE
op->opgroup = RELATIVE_GROUP
op=>optag = nextop=>optag
freeops = 1
break
wend
break // NE_CODE
is SLB_CODE
if nextop->opcode == LLB_CODE and op=>opoffset == nextop=>opoffset
op->opcode = DLB_CODE

View File

@@ -3,33 +3,36 @@
//
const CONST_GROUP = $00
const CONST_CODE = $2C
const ADDI_CODE = $38
const SUBI_CODE = $3A
const ANDI_CODE = $3C
const ORI_CODE = $3E
const CONSTR_GROUP = $01
const CONSTR_CODE = $2E
//
// Stack code group
//
const STACK_GROUP = $02
const INDEXB_CODE = $02
const ADD_CODE = $02
const SUB_CODE = $04
const MUL_CODE = $06
const DIV_CODE = $08
const MOD_CODE = $0A
const INC_CODE = $0C
const DEC_CODE = $0E
const NEG_CODE = $10
const COMP_CODE = $12
const AND_CODE = $14
const OR_CODE = $16
const EOR_CODE = $18
const SHL_CODE = $1A
const SHR_CODE = $1C
const INDEXW_CODE = $1E
const LOGIC_NOT_CODE = $20
const LOGIC_OR_CODE = $22
const LOGIC_AND_CODE = $24
const INDEXB_CODE = $82
const ADD_CODE = $82
const SUB_CODE = $84
const MUL_CODE = $86
const DIV_CODE = $88
const MOD_CODE = $8A
const INC_CODE = $8C
const DEC_CODE = $8E
const NEG_CODE = $90
const COMP_CODE = $92
const AND_CODE = $94
const OR_CODE = $96
const EOR_CODE = $98
const SHL_CODE = $9A
const SHR_CODE = $9C
const INDEXW_CODE = $9E
const LOGIC_NOT_CODE = $80
const DROP_CODE = $30
const DUP_CODE = $32
const DROP2_CODE = $32
const DUP_CODE = $34
const EQ_CODE = $40
const NE_CODE = $42
const GT_CODE = $44
@@ -55,6 +58,10 @@ const DLB_CODE = $6C
const DLW_CODE = $6E
const SLB_CODE = $74
const SLW_CODE = $76
const ADDLB_CODE = $B0
const ADDLW_CODE = $B2
const IDXLB_CODE = $B8
const IDXLW_CODE = $BA
//
// Global address code group
//
@@ -67,13 +74,23 @@ const SAB_CODE = $78
const SAW_CODE = $7A
const DAB_CODE = $7C
const DAW_CODE = $7E
const ADDAB_CODE = $B4
const ADDAW_CODE = $B6
const IDXAB_CODE = $BC
const IDXAW_CODE = $BE
//
// Relative address code group
//
const RELATIVE_GROUP = $05
const BREQ_CODE = $22
const BRNE_CODE = $24
const BRFALSE_CODE = $4C
const BRTRUE_CODE = $4E
const BRNCH_CODE = $50
const BRAND_CODE = $AC
const BROR_CODE = $AE
const BRGT_CODE = $A0
const BRLT_CODE = $A2
//
// Code tag address group
//

File diff suppressed because it is too large Load Diff

View File

@@ -50,7 +50,6 @@ t_token keywords[] = {
BYTE_TOKEN, 'R', 'E', 'S',
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
BYTE_TOKEN, 'C', 'H', 'A', 'R',
BYTE_TOKEN, 'R', 'E', 'S',
WORD_TOKEN, 'W', 'O', 'R', 'D',
WORD_TOKEN, 'V', 'A', 'R',
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',

View File

@@ -36,7 +36,9 @@
// loop
// chrptr = tknptr - 1
// while keywrds[keypos] == tknlen
// i = 1; while i <= tknlen and ^(chrptr + i) == keywrds[keypos + i]; i++; loop
// for i = 1 to tknlen
// if ^(chrptr + i) <> keywrds[keypos + i]; break; fin
// next
// if i > tknlen
// return keywrds[keypos + keywrds[keypos] + 1]
// fin
@@ -325,7 +327,7 @@ def nextln
scanptr++
scan
else
if token <> EOL_TKN and token <> EOF_TKN; puti(token&$7F); puts("Extraneous characters\n"); exit_err(0); fin
if token <> EOL_TKN and token <> EOF_TKN; putc(token&$7F); puts("Extraneous characters\n"); exit_err(0); fin
scanptr = inbuff
^instr = fileio:read(refnum, inbuff, 127)
if ^instr

View File

@@ -1,10 +1,13 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "plasm.h"
#define LVALUE 0
#define RVALUE 1
#define MAX_LAMBDA 64
int parse_mods(void);
int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0;
long infuncvals = 0;
t_token prevstmnt;
@@ -23,9 +26,7 @@ t_token binary_ops_table[] = {
EOR_TOKEN,
OR_TOKEN,
GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN,
EQ_TOKEN, NE_TOKEN,
LOGIC_AND_TOKEN,
LOGIC_OR_TOKEN
EQ_TOKEN, NE_TOKEN
/* Lowest precedence */
};
t_token binary_ops_precedence[] = {
@@ -37,9 +38,7 @@ t_token binary_ops_precedence[] = {
5,
6,
7, 7, 7, 7,
8, 8,
9,
10
8, 8
/* Lowest precedence */
};
@@ -652,9 +651,13 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
cfnparms = 0; cfnvals = 1;
type &= ~FUNC_TYPE;
}
else if (type & (BYTE_TYPE | BPTR_TYPE))
else if (type & (BPTR_TYPE)) // Prefer the pointer type.
valseq = gen_lb(valseq);
else if (type & (WORD_TYPE | WPTR_TYPE))
else if (type & (WPTR_TYPE))
valseq = gen_lw(valseq);
else if (type & (BYTE_TYPE))
valseq = gen_lb(valseq);
else if (type & (WORD_TYPE))
valseq = gen_lw(valseq);
else
parse_error("What are we dereferencing?");
@@ -729,14 +732,48 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth)
if (stackdepth)
(*stackdepth)--;
}
/*
* Look for ternary operator
*/
if (scantoken == TERNARY_TOKEN)
if (scantoken == LOGIC_AND_TOKEN)
{
int tag_and;
int stackdepth1;
/*
* Short-circuit AND
*/
if (*stackdepth != 1)
parse_error("AND must evaluate to single value");
tag_and = tag_new(BRANCH_TYPE);
codeseq = gen_brand(codeseq, tag_and);
codeseq = parse_expr(codeseq, &stackdepth1);
if (stackdepth1 != *stackdepth)
parse_error("Inconsistent AND value counts");
codeseq = gen_codetag(codeseq, tag_and);
}
else if (scantoken == LOGIC_OR_TOKEN)
{
int tag_or;
int stackdepth1;
/*
* Short-circuit OR
*/
if (*stackdepth != 1)
parse_error("OR must evaluate to single value");
tag_or = tag_new(BRANCH_TYPE);
codeseq = gen_bror(codeseq, tag_or);
codeseq = parse_expr(codeseq, &stackdepth1);
if (stackdepth1 != *stackdepth)
parse_error("Inconsistent AND value counts");
codeseq = gen_codetag(codeseq, tag_or);
}
else if (scantoken == TERNARY_TOKEN)
{
int tag_else, tag_endtri;
int stackdepth1;
/*
* Look for ternary operator
*/
if (*stackdepth != 1)
parse_error("Ternary op must evaluate to single value");
tag_else = tag_new(BRANCH_TYPE);
@@ -798,9 +835,11 @@ t_opseq *parse_set(t_opseq *codeseq)
int parse_stmnt(void)
{
int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of;
int type, addr, step, cfnvals;
int type, addr, step, cfnvals, constsize, casecnt, i;
int *caseval, *casetag;
long constval;
char *idptr;
t_opseq *seq;
t_opseq *seq, *fromseq, *toseq;
/*
* Optimization for last function LEAVE and OF clause.
@@ -859,9 +898,10 @@ int parse_stmnt(void)
tag_while = tag_new(BRANCH_TYPE);
tag_wend = tag_new(BRANCH_TYPE);
tag_prevcnt = cont_tag;
cont_tag = tag_while;
cont_tag = tag_new(BRANCH_TYPE);
tag_prevbrk = break_tag;
break_tag = tag_wend;
emit_brnch(cont_tag);
emit_codetag(tag_while);
if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad expression");
@@ -870,12 +910,12 @@ int parse_stmnt(void)
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
seq = gen_brfls(seq, tag_wend);
emit_seq(seq);
seq = gen_brtru(seq, tag_while);
while (parse_stmnt()) next_line();
if (scantoken != LOOP_TOKEN)
parse_error("Missing WHILE/END");
emit_brnch(tag_while);
emit_codetag(cont_tag);
emit_seq(seq);
emit_codetag(tag_wend);
break_tag = tag_prevbrk;
cont_tag = tag_prevcnt;
@@ -906,46 +946,38 @@ int parse_stmnt(void)
break_tag = tag_prevbrk;
break;
case FOR_TOKEN:
stack_loop++;
stack_loop += 2;
tag_prevbrk = break_tag;
break_tag = tag_new(BRANCH_TYPE);
tag_for = tag_new(BRANCH_TYPE);
tag_prevcnt = cont_tag;
cont_tag = tag_for;
cont_tag = tag_new(BRANCH_TYPE);
if (scan() != ID_TOKEN)
parse_error("Missing FOR variable");
type = id_type(tokenstr, tokenlen);
addr = id_tag(tokenstr, tokenlen);
if (scan() != SET_TOKEN)
parse_error("Missing FOR =");
if (!(seq = parse_expr(NULL, &cfnvals)))
if (!(fromseq = parse_expr(NULL, &cfnvals)))
parse_error("Bad FOR expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq);
emit_codetag(tag_for);
if (type & LOCAL_TYPE)
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
else
type & BYTE_TYPE ? emit_dab(addr, 0, type) : emit_daw(addr, 0, type);
if (scantoken == TO_TOKEN)
step = 1;
else if (scantoken == DOWNTO_TOKEN)
step = -1;
else
parse_error("Missing FOR TO");
if (!(seq = parse_expr(NULL, &cfnvals)))
if (!(toseq = parse_expr(NULL, &cfnvals)))
parse_error("Bad FOR TO expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq);
step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag);
if (scantoken == STEP_TOKEN)
{
if (!(seq = parse_expr(NULL, &cfnvals)))
@@ -955,27 +987,59 @@ int parse_stmnt(void)
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq);
emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN);
}
else
emit_unaryop(step > 0 ? INC_TOKEN : DEC_TOKEN);
{
seq = NULL;
}
toseq = cat_seq(toseq, fromseq);
emit_seq(step > 0 ? gen_brgt(toseq, break_tag) : gen_brlt(toseq, break_tag));
emit_codetag(tag_for);
if (type & LOCAL_TYPE)
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
else
type & BYTE_TYPE ? emit_dab(addr, 0, type) : emit_daw(addr, 0, type);
while (parse_stmnt()) next_line();
if (scantoken != NEXT_TOKEN)
parse_error("Missing FOR/NEXT");
emit_brnch(tag_for);
emit_codetag(cont_tag);
cont_tag = tag_prevcnt;
if (step > 0)
{
if (seq)
{
emit_seq(seq);
emit_addbrle(tag_for);
}
else
emit_incbrle(tag_for);
}
else
{
if (seq)
{
emit_seq(seq);
emit_subbrge(tag_for);
}
else
emit_decbrge(tag_for);
}
emit_codetag(break_tag);
if (type & LOCAL_TYPE)
type & BYTE_TYPE ? emit_slb(addr) : emit_slw(addr);
else
type & BYTE_TYPE ? emit_sab(addr, 0, type) : emit_saw(addr, 0, type);
emit_drop();
break_tag = tag_prevbrk;
stack_loop--;
break_tag = tag_prevbrk;
stack_loop -= 2;
break;
case CASE_TOKEN:
stack_loop++;
tag_prevbrk = break_tag;
break_tag = tag_new(BRANCH_TYPE);
tag_choice = tag_new(BRANCH_TYPE);
tag_of = tag_new(BRANCH_TYPE);
caseval = malloc(sizeof(int)*256);
casetag = malloc(sizeof(int)*256);
casecnt = 0;
if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad CASE expression");
if (cfnvals > 1)
@@ -984,33 +1048,48 @@ int parse_stmnt(void)
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq);
emit_select(tag_choice);
next_line();
while (scantoken != ENDCASE_TOKEN)
{
if (scantoken == OF_TOKEN)
{
if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad CASE OF expression");
if (cfnvals > 1)
tag_of = tag_new(BRANCH_TYPE);
constval = 0;
parse_constexpr(&constval, &constsize);
i = casecnt;
while ((i > 0) && (caseval[i-1] > constval))
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
//
// Move larger case consts up
//
caseval[i] = caseval[i-1];
casetag[i] = casetag[i-1];
i--;
}
emit_seq(seq);
emit_brne(tag_choice);
if ((i < casecnt) && (caseval[i] == constval))
parse_error("Duplicate CASE");
caseval[i] = constval;
casetag[i] = tag_of;
casecnt++;
emit_codetag(tag_of);
while (parse_stmnt()) next_line();
tag_of = tag_new(BRANCH_TYPE);
if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break
emit_brnch(tag_of);
emit_codetag(tag_choice);
tag_choice = tag_new(BRANCH_TYPE);
}
else if (scantoken == DEFAULT_TOKEN)
{
emit_codetag(tag_of);
tag_of = 0;
if (prevstmnt != BREAK_TOKEN) // Branch around caseblock if falling through
{
tag_of = tag_new(BRANCH_TYPE);
emit_brnch(tag_of);
}
else
tag_of = 0;
emit_codetag(tag_choice);
emit_caseblock(casecnt, caseval, casetag);
tag_choice = 0;
scan();
if (tag_of)
emit_codetag(tag_of);
while (parse_stmnt()) next_line();
if (scantoken != ENDCASE_TOKEN)
parse_error("Bad CASE DEFAULT clause");
@@ -1020,12 +1099,16 @@ int parse_stmnt(void)
else
parse_error("Bad CASE clause");
}
if (tag_of)
emit_codetag(tag_of);
if (tag_choice)
{
emit_brnch(break_tag);
emit_codetag(tag_choice);
emit_caseblock(casecnt, caseval, casetag);
}
free(caseval);
free(casetag);
emit_codetag(break_tag);
emit_drop();
break_tag = tag_prevbrk;
stack_loop--;
break;
case BREAK_TOKEN:
if (break_tag)
@@ -1040,12 +1123,19 @@ int parse_stmnt(void)
parse_error("CONTINUE without loop");
break;
case RETURN_TOKEN:
cfnvals = stack_loop;
while (cfnvals >= 2)
{
emit_drop2();
cfnvals -= 2;
}
if (cfnvals)
{
emit_drop();
cfnvals--;
}
if (infunc)
{
int i;
for (i = 0; i < stack_loop; i++)
emit_drop();
cfnvals = 0;
emit_seq(parse_list(NULL, &cfnvals));
if (cfnvals > infuncvals)
parse_error("Too many return values");
@@ -1243,7 +1333,7 @@ int parse_struc(void)
int parse_vars(int type)
{
long value;
int idlen, size, cfnparms;
int idlen, size, cfnparms, emit = 0;
long cfnvals;
char *idstr;
@@ -1306,6 +1396,7 @@ int parse_vars(int type)
if (type & WORD_TYPE)
cfnvals *= 2;
do parse_var(type, cfnvals); while (scantoken == COMMA_TOKEN);
emit = type == GLOBAL_TYPE;
break;
case PREDEF_TOKEN:
/*
@@ -1346,6 +1437,12 @@ int parse_vars(int type)
else
parse_error("Bad function pre-declaration");
} while (scantoken == COMMA_TOKEN);
break;
case IMPORT_TOKEN:
if (emit || type != GLOBAL_TYPE)
parse_error("IMPORT after emitting data");
parse_mods();
break;
case EOL_TOKEN:
break;
default:
@@ -1436,11 +1533,16 @@ int parse_defs(void)
char c, *idstr;
int idlen, func_tag, cfnparms, cfnvals, type = GLOBAL_TYPE, pretype;
static char bytecode = 0;
if (scantoken == EXPORT_TOKEN)
switch (scantoken)
{
if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN)
parse_error("Bad export definition");
type = EXPORT_TYPE;
case CONST_TOKEN:
case STRUC_TOKEN:
return parse_vars(GLOBAL_TYPE);
case EXPORT_TOKEN:
if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN)
parse_error("Bad export definition");
type = EXPORT_TYPE;
}
if (scantoken == DEF_TOKEN)
{
@@ -1520,8 +1622,9 @@ int parse_defs(void)
emit_const(0);
emit_leave();
}
while (lambda_cnt--)
emit_lambdafunc(lambda_tag[lambda_cnt], lambda_id[lambda_cnt], lambda_cparams[lambda_cnt], lambda_seq[lambda_cnt]);
for (cfnvals = 0; cfnvals < lambda_cnt; cfnvals++)
emit_lambdafunc(lambda_tag[cfnvals], lambda_id[cfnvals], lambda_cparams[cfnvals], lambda_seq[cfnvals]);
lambda_cnt = 0;
return (1);
}
else if (scantoken == ASM_TOKEN)
@@ -1589,6 +1692,7 @@ int parse_defs(void)
next_line();
} while (scantoken != END_TOKEN);
scan();
infunc = 0;
return (1);
}
return (scantoken == EOL_TOKEN);
@@ -1601,21 +1705,21 @@ int parse_module(void)
while (parse_mods()) next_line();
while (parse_vars(GLOBAL_TYPE)) next_line();
while (parse_defs()) next_line();
emit_bytecode_seg();
emit_start();
idlocal_reset();
emit_idfunc(0, 0, NULL, 1);
prevstmnt = 0;
if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN)
{
emit_bytecode_seg();
emit_start();
idlocal_reset();
emit_idfunc(0, 0, NULL, 1);
prevstmnt = 0;
while (parse_stmnt()) next_line();
if (scantoken != DONE_TOKEN)
parse_error("Missing DONE");
if (prevstmnt != RETURN_TOKEN)
{
emit_const(0);
emit_ret();
}
}
if (prevstmnt != RETURN_TOKEN)
{
emit_const(0);
emit_ret();
}
}
emit_trailer();

View File

@@ -80,8 +80,6 @@ def calc_binaryop(op)#0
push_val(val1, size1, type1)
end
def parse_constterm
word val
byte size, type
when scan
is OPEN_PAREN_TKN
@@ -463,9 +461,13 @@ def parse_value(codeseq, r_val)#2
valseq = gen_op(valseq, ICAL_CODE)
stackdepth = stackdepth + cfnvals - 1
type = type & ~FUNC_TYPE
elsif type & (BYTE_TYPE | BPTR_TYPE)
elsif type & (BPTR_TYPE) // Prefer the pointer type.
valseq = gen_op(valseq, LB_CODE)
elsif type & (WORD_TYPE | WPTR_TYPE)
elsif type & (WPTR_TYPE)
valseq = gen_op(valseq, LW_CODE)
elsif type & (BYTE_TYPE)
valseq = gen_op(valseq, LB_CODE)
elsif type & (WORD_TYPE)
valseq = gen_op(valseq, LW_CODE)
else
exit_err(ERR_INVAL|ERR_CODE)
@@ -494,7 +496,7 @@ end
def parse_expr(codeseq)#2
byte stackdepth, matchdepth, stkdepth1, prevmatch, matchop, i
word optos
word tag_else, tag_endtri
word tag_else, tag_endop
stackdepth = 0
matchop = 0
@@ -524,21 +526,32 @@ def parse_expr(codeseq)#2
codeseq = gen_bop(codeseq, pop_op)
stackdepth--
loop
//
// Look for ternary operator
//
if token == TERNARY_TKN
if token == LOGIC_AND_TKN
if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin
tag_endop = new_tag(RELATIVE_FIXUP)
codeseq = gen_oprel(codeseq, BRAND_CODE, tag_endop)
codeseq, stkdepth1 = parse_expr(codeseq)
if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin
codeseq = gen_ctag(codeseq, tag_endop)
elsif token == LOGIC_OR_TKN
if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin
tag_endop = new_tag(RELATIVE_FIXUP)
codeseq = gen_oprel(codeseq, BROR_CODE, tag_endop)
codeseq, stkdepth1 = parse_expr(codeseq)
if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin
codeseq = gen_ctag(codeseq, tag_endop)
elsif token == TERNARY_TKN
if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin
tag_else = new_tag(RELATIVE_FIXUP)
tag_endtri = new_tag(RELATIVE_FIXUP)
tag_endop = new_tag(RELATIVE_FIXUP)
codeseq = gen_oprel(codeseq, BRFALSE_CODE, tag_else)
codeseq, stkdepth1 = parse_expr(codeseq)
if token <> TRIELSE_TKN; exit_err(ERR_MISS|ERR_SYNTAX); fin
codeseq = gen_oprel(codeseq, BRNCH_CODE, tag_endtri)
codeseq = gen_oprel(codeseq, BRNCH_CODE, tag_endop)
codeseq = gen_ctag(codeseq, tag_else)
codeseq, stackdepth = parse_expr(codeseq)
if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin
codeseq = gen_ctag(codeseq, tag_endtri)
codeseq = gen_ctag(codeseq, tag_endop)
fin
return codeseq, stackdepth
end
@@ -587,9 +600,10 @@ def parse_set(codeseq)
return codeseq
end
def parse_stmnt
byte type, elem_type, elem_size, i, cfnvals
word seq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend
byte type, elem_type, elem_size, cfnvals
word seq, fromseq, toseq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend
word tag_repeat, tag_for, tag_choice, tag_of, idptr, addr, stepdir
word caseconst, casecnt, caseval, casetag, i
if token <> END_TKN and token <> DONE_TKN and token <> OF_TKN and token <> DEFAULT_TKN
prevstmnt = token
@@ -643,9 +657,10 @@ def parse_stmnt
tag_while = new_tag(RELATIVE_FIXUP)
tag_wend = new_tag(RELATIVE_FIXUP)
tag_prevcnt = cont_tag
cont_tag = tag_while
cont_tag = new_tag(RELATIVE_FIXUP)
tag_prevbrk = break_tag
break_tag = tag_wend
emit_branch(cont_tag)
emit_tag(tag_while)
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
@@ -653,13 +668,13 @@ def parse_stmnt
parse_warn("Expression value overflow")
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
seq = gen_oprel(seq, BRFALSE_CODE, tag_wend)
emit_seq(seq)
seq = gen_oprel(seq, BRTRUE_CODE, tag_while)
while parse_stmnt
nextln
loop
if token <> LOOP_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
emit_branch(tag_while)
emit_tag(cont_tag)
emit_seq(seq)
emit_tag(tag_wend)
break_tag = tag_prevbrk
cont_tag = tag_prevcnt
@@ -690,10 +705,10 @@ def parse_stmnt
break_tag = tag_prevbrk
break
is FOR_TKN
stack_loop++
stack_loop = stack_loop + 2
tag_for = new_tag(RELATIVE_FIXUP)
tag_prevcnt = cont_tag
cont_tag = tag_for
cont_tag = new_tag(RELATIVE_FIXUP)
tag_prevbrk = break_tag
break_tag = new_tag(RELATIVE_FIXUP)
if scan <> ID_TKN; exit_err(ERR_MISS|ERR_ID); fin
@@ -705,19 +720,12 @@ def parse_stmnt
exit_err(ERR_INVAL|ERR_ID)
fin
if scan <> SET_TKN; exit_err(ERR_INVAL|ERR_STATE); fin
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
fromseq, cfnvals = parse_expr(NULL)
if !fromseq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
parse_warn("Expression value overflow")
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_seq(seq)
emit_tag(tag_for)
if type & LOCAL_TYPE
if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin
else
if type & BYTE_TYPE; emit_dab(addr, 0); else; emit_daw(addr, 0); fin
fin
if token == TO_TKN
stepdir = 1
elsif token == DOWNTO_TKN
@@ -725,14 +733,12 @@ def parse_stmnt
else
exit_err(ERR_INVAL|ERR_STATE)
fin
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
toseq, cfnvals = parse_expr(NULL)
if !toseq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
parse_warn("Expression value overflow")
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_seq(seq)
if stepdir > 0; emit_brgt(break_tag); else; emit_brlt(break_tag); fin
if token == STEP_TKN
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
@@ -740,28 +746,54 @@ def parse_stmnt
parse_warn("Expression value overflow")
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_seq(seq)
emit_code(stepdir > 0 ?? ADD_CODE :: SUB_CODE)
else
emit_code(stepdir > 0 ?? INC_CODE :: DEC_CODE)
seq = NULL
fin
emit_seq(gen_oprel(cat_seq(toseq, fromseq), stepdir > 0 ?? BRGT_CODE :: BRLT_CODE, break_tag))
emit_tag(tag_for)
if type & LOCAL_TYPE
if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin
else
if type & BYTE_TYPE; emit_dab(addr, 0); else; emit_daw(addr, 0); fin
fin
while parse_stmnt
nextln
loop
if token <> NEXT_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
emit_branch(tag_for)
emit_tag(cont_tag)
cont_tag = tag_prevcnt
if stepdir > 0
if seq
emit_seq(seq)
emit_addbrle(tag_for)
else
emit_incbrle(tag_for)
fin
else
if seq
emit_seq(seq)
emit_subbrge(tag_for)
else
emit_decbrge(tag_for)
fin
fin
emit_tag(break_tag)
if type & LOCAL_TYPE
if type & BYTE_TYPE; emit_slb(addr); else; emit_slw(addr); fin
else
if type & BYTE_TYPE; emit_sab(addr, 0); else; emit_saw(addr, 0); fin
fin
emit_code(DROP_CODE)
break_tag = tag_prevbrk
stack_loop--
break_tag = tag_prevbrk
stack_loop = stack_loop - 2
break
is CASE_TKN
stack_loop++
tag_prevbrk = break_tag
break_tag = new_tag(RELATIVE_FIXUP)
tag_choice = new_tag(RELATIVE_FIXUP)
tag_of = new_tag(RELATIVE_FIXUP)
caseval = heapalloc(CASENUM)
casetag = heapalloc(CASENUM)
casecnt = 0
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
@@ -769,32 +801,44 @@ def parse_stmnt
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_seq(seq)
emit_select(tag_choice)
nextln
while token <> ENDCASE_TKN
when token
is OF_TKN
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
parse_warn("Expression value overflow")
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_seq(seq)
emit_brne(tag_choice)
if casecnt == CASENUM; exit_err(ERR_OVER|ERR_TABLE); fin
caseconst, drop, drop = parse_constexpr
tag_of = new_tag(RELATIVE_FIXUP)
i = casecnt
while i > 0 and caseval=>[i-1] > caseconst
//
// Move larger case consts up
//
caseval=>[i] = caseval=>[i-1]
casetag=>[i] = casetag=>[i-1]
i--
loop
if i < casecnt and caseval=>[i] == caseconst; exit_err(ERR_DUP|ERR_STATE); fin
caseval=>[i] = caseconst
casetag=>[i] = tag_of
casecnt++
emit_tag(tag_of)
while parse_stmnt
nextln
loop
tag_of = new_tag(RELATIVE_FIXUP)
if prevstmnt <> BREAK_TKN // Fall through to next OF if no break
break
is DEFAULT_TKN
tag_of = 0
if prevstmnt <> BREAK_TKN // Branch around caseblock if falling through
tag_of = new_tag(RELATIVE_FIXUP)
emit_branch(tag_of)
fin
emit_tag(tag_choice)
tag_choice = new_tag(RELATIVE_FIXUP)
break
is DEFAULT_TKN
emit_tag(tag_of)
tag_of = 0
emit_caseblock(casecnt, caseval, casetag)
tag_choice = 0
if tag_of
emit_tag(tag_of)
fin
scan
while parse_stmnt
nextln
@@ -808,13 +852,14 @@ def parse_stmnt
exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE)
wend
loop
if (tag_of)
emit_tag(tag_of)
if tag_choice
emit_branch(break_tag)
emit_tag(tag_choice)
emit_caseblock(casecnt, caseval, casetag)
fin
heaprelease(caseval)
emit_tag(break_tag)
emit_code(DROP_CODE)
break_tag = tag_prevbrk
stack_loop--
break
is BREAK_TKN
if break_tag
@@ -831,10 +876,15 @@ def parse_stmnt
fin
break
is RETURN_TKN
i = stack_loop
while i >= 2
emit_code(DROP2_CODE)
i = i - 2
loop
if i
emit_code(DROP_CODE)
fin
if infunc
for i = 1 to stack_loop
emit_code(DROP_CODE)
next
seq, cfnvals = parse_list
emit_seq(seq)
if cfnvals > infuncvals
@@ -1076,6 +1126,10 @@ def parse_vars(type)
fin
until token <> COMMA_TKN
break
is IMPORT_TKN
if codeptr <> codebuff or type <> GLOBAL_TYPE; exit_err(ERR_INVAL|ERR_INIT); fin
parse_mods
break
is EOL_TKN
break
otherwise
@@ -1157,81 +1211,95 @@ def parse_lambda
return func_tag
end
def parse_defs
byte idlen, cfnparms, cfnvals
word type, idstr, func_tag, idptr
byte idlen, cfnparms, cfnvals, defstr[17]
word type, idstr, func_tag, idptr, defcodeptr
type = FUNC_TYPE
if token == EXPORT_TKN
if scan <> DEF_TKN; exit_err(ERR_INVAL|ERR_STATE); fin
type = type | EXPORT_TYPE
fin
if token == DEF_TKN
if scan <> ID_TKN; exit_err(ERR_INVAL|ERR_ID); fin
lambda_cnt = 0
cfnparms = 0
infuncvals = 1
infunc = TRUE
idstr = tknptr
idlen = tknlen
init_idlocal
if scan == OPEN_PAREN_TKN
repeat
if scan == ID_TKN
cfnparms++
new_idlocal(tknptr, tknlen, WORD_TYPE, 2)
scan
fin
until token <> COMMA_TKN
if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
when token
is CONST_TKN
is STRUC_TKN
return parse_vars(GLOBAL_TYPE)
is EXPORT_TKN
if scan <> DEF_TKN; exit_err(ERR_INVAL|ERR_STATE); fin
type = type | EXPORT_TYPE
is DEF_TKN
if scan <> ID_TKN; exit_err(ERR_INVAL|ERR_ID); fin
lambda_cnt = 0
cfnparms = 0
infuncvals = 1
infunc = TRUE
idstr = tknptr
idlen = tknlen
init_idlocal
if scan == OPEN_PAREN_TKN
repeat
if scan == ID_TKN
cfnparms++
new_idlocal(tknptr, tknlen, WORD_TYPE, 2)
scan
fin
until token <> COMMA_TKN
if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
scan
fin
if token == POUND_TKN
if not parse_const(@infuncvals); exit_err(ERR_INVAL|ERR_CONST); fin
scan
fin
idptr = lookup_idglobal(idstr, idlen)
if idptr
if not idptr=>idtype & PREDEF_TYPE; exit_err(ERR_DUP|ERR_ID); fin
if idptr->funcparms <> cfnparms or idptr->funcvals <> infuncvals; exit_err(ERR_DUP|ERR_CODE|ERR_ID); fin
func_tag = idptr=>idval
idptr=>idtype = idptr=>idtype | type
else
func_tag = new_tag(WORD_FIXUP)
new_idfunc(idstr, idlen, type, func_tag, cfnparms, infuncvals)
fin
//
// Print def name
//
nametostr(idstr, idlen > 16 ?? 16 :: idlen, @defstr); puts(@defstr); putc(':')
defcodeptr = codeptr
emit_tag(func_tag)
new_dfd(func_tag)
while parse_vars(LOCAL_TYPE); nextln; loop
emit_enter(cfnparms)
prevstmnt = 0
while parse_stmnt; nextln; loop
infunc = FALSE
if token <> END_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
scan
fin
if token == POUND_TKN
if not parse_const(@infuncvals); exit_err(ERR_INVAL|ERR_CONST); fin
scan
fin
idptr = lookup_idglobal(idstr, idlen)
if idptr
if not idptr=>idtype & PREDEF_TYPE; exit_err(ERR_DUP|ERR_ID); fin
if idptr->funcparms <> cfnparms or idptr->funcvals <> infuncvals; exit_err(ERR_DUP|ERR_CODE|ERR_ID); fin
func_tag = idptr=>idval
idptr=>idtype = idptr=>idtype | type
else
func_tag = new_tag(WORD_FIXUP)
new_idfunc(idstr, idlen, type, func_tag, cfnparms, infuncvals)
fin
emit_tag(func_tag)
while parse_vars(LOCAL_TYPE); nextln; loop
emit_enter(cfnparms)
prevstmnt = 0
while parse_stmnt; nextln; loop
infunc = FALSE
if token <> END_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
scan
if prevstmnt <> RETURN_TKN
if infuncvals; parse_warn("No return values"); fin
for cfnvals = infuncvals - 1 downto 0
emit_const(0)
if prevstmnt <> RETURN_TKN
if infuncvals; parse_warn("No return values"); fin
for cfnvals = infuncvals - 1 downto 0
emit_const(0)
next
emit_leave
fin
for cfnvals = 0 to lambda_cnt-1
emit_lambdafunc(lambda_tag[cfnvals], lambda_cparms[cfnvals], lambda_seq[cfnvals])
new_dfd(lambda_tag[cfnvals])
next
emit_leave
fin
while lambda_cnt
lambda_cnt--
emit_lambdafunc(lambda_tag[lambda_cnt], lambda_cparms[lambda_cnt], lambda_seq[lambda_cnt])
loop
fin
puti(codeptr - defcodeptr); puts(@bytesln)
wend
return token == EOL_TKN ?? TRUE :: FALSE
end
def parse_module#0
init_idglobal
init_idlocal
puts("Data+Code buffer size = "); puti(codebufsz); putln
if nextln
//
// Compile module
//
puts("\nDATA:");
while parse_mods; nextln; loop
while parse_vars(GLOBAL_TYPE); nextln; loop
emit_codeseg
puti(codeptr - codebuff); puts(@bytesln)
while parse_defs; nextln; loop
puts("INIT:")
entrypoint = codeptr
prevstmnt = 0
init_idlocal
@@ -1243,6 +1311,8 @@ def parse_module#0
emit_const(0)
emit_leave
fin
puti(codeptr - entrypoint); puts(@bytesln)
puts("\nTotal bytes compiled: "); puti(codeptr - codebuff); putln
if token <> DONE_TKN; parse_warn("Missing DONE\n"); fin
//dumpsym(idglobal_tbl, globals)
fin

21
src/toolsrc/plasm.pla Normal file → Executable file
View File

@@ -152,7 +152,6 @@ byte = "AND", LOGIC_AND_TKN
byte = "NOT", LOGIC_NOT_TKN
byte = "RES", BYTE_TKN
byte = "VAR", WORD_TKN
byte = "RES", BYTE_TKN
byte = "WORD", WORD_TKN
byte = "CHAR", BYTE_TKN
byte = "BYTE", BYTE_TKN
@@ -194,8 +193,6 @@ byte = EOR_TKN
byte = OR_TKN
byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN
byte = EQ_TKN, NE_TKN
byte = LOGIC_AND_TKN
byte = LOGIC_OR_TKN
// Lowest precedence
byte[] bops_prec // Highest precedence
byte = 1, 1, 1
@@ -206,8 +203,6 @@ byte = 5
byte = 6
byte = 7, 7, 7, 7
byte = 8, 8
byte = 9
byte = 10
// Lowest precedence
byte[16] opstack
byte[16] precstack
@@ -236,24 +231,28 @@ end
// Generated code buffers
//
const OPSEQNUM = 256
const DFDNUM = 128
const TAGNUM = 1024
const FIXUPNUM = 2048
const MODDEPNUM = 8
const IDGLOBALSZ = 4096
const IDLOCALSZ = 512
const CASENUM = 64
word fixup_cnt, tag_cnt = -1
word dfd_tag, dfd_cnt
word fixup_tag, fixup_addr
word tag_addr, tag_type
word idglobal_tbl, idlocal_tbl
word pending_seq
word globals, lastglobal, lastglobalsize, lastlocal, savelast
word tag_num, fixup_num, globalbufsz, localbufsz, codebufsz
word globals, lastglobal, lastglobalsize, lastlocal, savelast, savetbl
word dfd_num, tag_num, fixup_num, globalbufsz, localbufsz, codebufsz
word datasize, framesize, savesize
byte locals, savelocals
word codebuff, codeptr, entrypoint
word modsysflags
byte[16] moddep_tbl[MODDEPNUM]
byte moddep_cnt, def_cnt = 1
predef parse_mods
predef emit_pending_seq#0
//
// Module relocation base address
@@ -308,6 +307,7 @@ byte lambda_cnt, lambda_num
byte[LAMBDANUM] lambda_cparms
word[LAMBDANUM] lambda_seq, lambda_tag
predef parse_constexpr#3, parse_expr(codeseq)#2, parse_lambda
byte bytesln = " bytes\n"
//
// Arg pointer
//
@@ -445,10 +445,6 @@ end
//
// Handy functions
//
def puth(hex)#0
putc('$')
call($F941, hex >> 8, hex, 0, 0)
end
def nametostr(namestr, len, strptr)#0
^strptr = len
memcpy(strptr + 1, namestr, len)
@@ -511,7 +507,7 @@ include "toolsrc/parse.pla"
//
// Look at command line arguments and compile module
//
puts("PLASMA Compiler, Version 1.1\n")
puts("PLASMA Compiler, Version 2.0 DP2\n")
arg = argNext(argFirst)
if ^arg and ^(arg + 1) == '-'
opt = arg + 2
@@ -584,7 +580,6 @@ if srcfile and relfile
//
parse_module
fileio:close(srcref)
puts("\nBytes compiled: "); puti(codeptr - codebuff); putln
//
// Write REL file
//

172
src/utilsrc/apple/cat.pla Normal file
View File

@@ -0,0 +1,172 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
include "inc/int32.plh"
var arg, refnum, dirbuf
var page, firstblk, entrylen, entriesblk, i, entry, filecnt
char[64] path, filename
res[t_fileinfo] fileinfo
res[t_fileentry] fileentry
//
// Convert byte to two hex chars
//
def putb(b)#0
char h
h = ((b >> 4) & $0F) + '0'
if h > '9'
h = h + 7
fin
putc(h)
h = (b & $0F) + '0'
if h > '9'
h = h + 7
fin
putc(h)
end
def strupper(strptr)#0
byte i, chr
if ^strptr
for i = 1 to ^strptr
chr = strptr->[i]
if chr >= 'a' and chr <= 'z'
strptr->[i] = chr - 'a' + 'A'
fin
next
fin
end
def filefrompath(filestr, pathstr)#0
byte i
for i = ^pathstr downto 1
if pathstr->[i] == '/'
break
fin
next
^filestr = ^pathstr - i
memcpy(filestr + 1, pathstr + 1 + i, ^filestr)
end
//
// Print out a directory entry
//
def printentry(entryptr)#0
char type, pad, eofstr[12]
puts(entryptr)
when entryptr->entry_type
is $0F // Is it a directory?
type = '/'
break
is $FF // SYSTEM file
type = '-'
break
is $FE // REL file
type = '+'
break
otherwise
type = ' '
wend
putc(type)
for pad = ^entryptr to 14
putc(' ')
next
putc('$'); putb(entryptr->entry_type)
puts(" $"); puth(entryptr=>entry_aux)
entryptr->entry_EOFH.1 = 0
i32tos(entryptr+entry_EOFL, @eofstr)
for pad = eofstr to 9
putc(' ')
next
puts(@eofstr)
putln
end
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@path, arg)
strupper(@path)
else
fileio:getpfx(@path)
fin
//
// Check if file exists
//
if fileio:getfileinfo(@path, @fileinfo) == FILE_ERR_OK
puts("=NAME==========TYPE===AUX====LENGTH=\n")
//
// Check if cataloging a directory
//
if fileinfo.file_type == $0F
fileio:iobufalloc(2) // Reserve two I/O buffers
if path[path] <> '/' // Make sure path ends with a '/'
path++
path[path] = '/'
fin
page = 21
filecnt = 0
firstblk = 1
dirbuf = heapallocalign(512, 8, 0)
refnum = fileio:open(@path)
repeat
if fileio:read(refnum, dirbuf, 512) == 512
//
// Skip block pointers
//
entry = dirbuf + 4
if firstblk
//
// Pull out revelant details from the first block
//
entrylen = dirbuf->$23
entriesblk = dirbuf->$24
filecnt = dirbuf=>$25
entry = entry + entrylen
fin
for i = firstblk to entriesblk
//
// Print directory entry details
//
^entry = ^entry & $0F
if ^entry
printentry(entry)
filecnt--
//
// Pause display every screenfull
//
if not page
getc
page = 22
else
page--
fin
fin
entry = entry + entrylen
next
firstblk = 0
fin
until filecnt == 0
else
//
// Create file entry from file info
//
filefrompath(@fileentry, @path)
fileentry.entry_access = fileinfo.file_access
fileentry.entry_type = fileinfo.file_type
fileentry:entry_create:0 = fileinfo:create_date
fileentry:entry_create:2 = fileinfo:create_time
fileentry:entry_aux = fileinfo:aux_type
fileentry:entry_mod:0 = fileinfo:mod_date
fileentry:entry_mod:2 = fileinfo:mod_time
refnum = fileio:open(@path)
fileentry:entry_EOFL, fileentry.entry_EOFH = fileio:geteof(refnum)#2
printentry(@fileentry)
fin
fileio:close(0)
else
puts("Unable to open: "); puts(@path); putln
fin
done

146
src/utilsrc/apple/copy.pla Normal file
View File

@@ -0,0 +1,146 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
const MAXBUFSIZE = 16384
var arg, srcref, dstref, copybuff, copysize, copyxfer
char[64] srcfilename, dstfilename
res[t_fileinfo] srcfileinfo, dstfileinfo
//
// Handy string functions
//
def filefrompath(filestr, pathstr)#0
byte i
for i = ^pathstr + 1 downto 1
if pathstr->[i] == '/'
break
fin
next
^filestr = ^pathstr - i
memcpy(filestr + 1, pathstr + 1 + i, ^filestr)
end
//
// Check destination filename
//
def checkdst
char[17] basefile
//
// Check if destination exists
//
if fileio:getfileinfo(@dstfilename, @dstfileinfo) == FILE_ERR_OK
//
// Check if copying into a directory
//
if dstfileinfo.file_type == $0F
if dstfilename[dstfilename] <> '/'
//
// Add path seperator
//
dstfilename++
dstfilename[dstfilename] = '/'
fin
filefrompath(@basefile, @srcfilename)
strcat(@dstfilename, @basefile)
if fileio:getfileinfo(@dstfilename, @dstfileinfo) == FILE_ERR_OK
//
// Check if *that* is a directory
//
if dstfileinfo.file_type == $0F
puts("Destination is a directory filename\n")
return FALSE
fin
else
return TRUE
fin
fin
//
// Remove existing file
//
fileio:destroy(@dstfilename)
fin
return TRUE
end
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@srcfilename, arg)
fileio:iobufalloc(2) // Reserve two I/O buffers
if fileio:getfileinfo(@srcfilename, @srcfileinfo) == FILE_ERR_OK
//
// Check that source isn't a directory - can't handle that yet
//
if srcfileinfo.file_type == $0F
puts("Can't copy directories (yet)\n")
return
fin
else
//
// File not found
//
puts("File not found: "); puts(@srcfilename); putln
return
fin
srcref = fileio:open(@srcfilename)
if srcref
arg = argNext(arg)
if ^arg
strcpy(@dstfilename, arg)
if checkdst()
//
// Create the destination file and open for writing
//
if fileio:create(@dstfilename, srcfileinfo.file_type, srcfileinfo:aux_type) == FILE_ERR_OK
dstref = fileio:open(@dstfilename)
if dstref
//
// Let the copying begin
//
copysize = MAXBUFSIZE
while isult(heapavail, copysize + 512)
copysize = copysize / 2
loop
copybuff = heapalloc(copysize)
if copybuff
//
// Round buffer to page boundary for faster transfers
//
copybuff = (copybuff + $FF) & $FF00
copyxfer = fileio:read(srcref, copybuff, copysize)
while copyxfer
if fileio:write(dstref, copybuff, copyxfer) <> copyxfer
puts("Error writing: "); puts(@dstfilename); putln
break
fin
copyxfer = fileio:read(srcref, copybuff, copysize)
loop
else
puts("No memory available!\n")
fin
else
puts("Unable to open: "); puts(@dstfilename); putln
fin
else
puts("Unable to create: "); puts(@dstfilename); putln
fin
fin
fileio:close(0)
return
fin
else
//
// Unable to open source
//
puts("Unable to open: "); puts(@srcfilename); putln
return
fin
//
// Close all files
//
fileio:close(0)
return
fin
puts("Usage: +COPY SRCFILE DEST\n")
done

62
src/utilsrc/apple/del.pla Normal file
View File

@@ -0,0 +1,62 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
char[64] filename
var arg
//
// Check filename
//
def checkfile
var refnum, dirbuf
res[t_fileinfo] fileinfo
//
// Check if file exists
//
if fileio:getfileinfo(@filename, @fileinfo) == FILE_ERR_OK
//
// Check if deleting a directory
//
if fileinfo.file_type == $0F
refnum = fileio:open(@filename)
if refnum
//
// Check for files inside directory
//
dirbuf = heapalloc(512)
if fileio:read(refnum, dirbuf, 512) == 512
fileio:close(refnum)
if dirbuf=>$25 // File count in directory
puts("Directory not empty: "); puts(@filename); putln
return FALSE
fin
fin
fin
fin
return TRUE
fin
puts("File not found: "); puts(@filename); putln
return FALSE
end
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@filename, arg)
if checkfile()
//
// Remove existing file
//
fileio:destroy(@filename)
fin
//
// Close all files
//
fileio:close(0)
return
fin
puts("Usage: +DEL FILE\n")
done

View File

@@ -0,0 +1,45 @@
//
// PLASMA JIT bytecode compiler tuner
//
include "inc/cmdsys.plh"
include "inc/args.plh"
var arg, val
def atoi(strptr)
var num, len
num = 0
len = ^strptr
strptr++
while len and ^strptr >= '0' and ^strptr <= '9'
num = num * 10 + ^strptr - '0'
strptr++
len--
loop
return num
end
arg = argNext(argFirst)
if ^arg
if arg->1 >= '0' and arg->1 <= '9'
val = atoi(arg)
if val > 255
val = 255
fin
cmdsys.jitcount = val
arg = argNext(arg)
if ^arg
val = atoi(arg)
if val > 255
val = 255
fin
cmdsys.jitsize = val
fin
else
puts("Usage: JITUNE WARMUP [CALLCOUNT [MAXSIZE]]\n")
fin
fin
puts("JIT Call Count: "); puti(cmdsys.jitcount); putln
puts("JIT Max Size: "); puti(cmdsys.jitsize); putln
done

View File

@@ -0,0 +1,24 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
var arg
char[64] filename
res[t_fileinfo] fileinfo
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@filename, arg)
if fileio:getfileinfo(@filename, @fileinfo) == FILE_ERR_OK
puts("File exists: "); puts(@filename); putln
else
if fileio:create(@filename, $0F, $0000) <> FILE_ERR_OK
puts("Unable to create directory: "); puts(@filename); putln
fin
fin
return
fin
puts("Usage: +NEWDIR PATH\n")
done

34
src/utilsrc/apple/ren.pla Normal file
View File

@@ -0,0 +1,34 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
var arg
char[64] oldfilename, newfilename
res[t_fileinfo] fileinfo
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@oldfilename, arg)
if fileio:getfileinfo(@oldfilename, @fileinfo) <> FILE_ERR_OK
//
// File not found
//
puts("File not found: "); puts(@oldfilename); putln
return
fin
arg = argNext(arg)
if ^arg
strcpy(@newfilename, arg)
//
// Rename file
//
if fileio:rename(@oldfilename, @newfilename) <> FILE_ERR_OK
puts("Unable to rename: "); puts(@oldfilename); puts(" --> "); puts(@newfilename); putln
fin
return
fin
fin
puts("Usage: +REN OLDNAME NEWNAME\n")
done

View File

@@ -35,10 +35,10 @@ asm sosexec(addr)#0
STA SRCL
BCC +
INC SRCH
+ LDA DSTL
CMP SRCL
LDA DSTH
SBC SRCH
+; LDA SRCL
CMP DSTL
LDA SRCH
SBC DSTH
BCC REVCPY
;
; FORWARD COPY

View File

@@ -0,0 +1,98 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
char[64] filename
res[t_fileinfo] fileinfo
var arg, type, aux
//
// Convert byte to two hex chars
//
def putb(b)#0
char h
h = ((b >> 4) & $0F) + '0'
if h > '9'
h = h + 7
fin
putc(h)
h = (b & $0F) + '0'
if h > '9'
h = h + 7
fin
putc(h)
end
def htoi(hexptr)
var val, i, n
val = 0
for i = 1 to ^hexptr
n = toupper(^(hexptr + i)) - '0'
if n > 9
n = n - 7
fin
if n > 15 or n < 0
return val
fin
val = (val << 4) + n
next
return val
end
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@filename, arg)
//
// Check if file exists
//
if fileio:getfileinfo(@filename, @fileinfo) == FILE_ERR_OK
//
// Check if re-typing a directory
//
if fileinfo.file_type <> $0F
//
// Check for optional overrides
//
arg = argNext(arg)
if ^arg
type = htoi(arg)
if type > 255
puts("TYPE value out of range\n")
return
fin
//
// Can't change something into directory
//
if type <> $0F
fileinfo.file_type = type
arg = argNext(arg)
if ^arg
aux = htoi(arg)
fileinfo:aux_type = aux
fin
//
// Update file type and aux values
//
if fileio:setfileinfo(@filename, @fileinfo) == FILE_ERR_OK
if fileio:getfileinfo(@filename, @fileinfo) <> FILE_ERR_OK
puts("Unable to reload file info: "); puts(@filename)
fin
else
puts("Unable to change TYPE & AUX values: "); puts(@filename)
return
fin
fin
fin
else
puts("Unable to get file info: "); puts(@filename); putln
fin
fin
puts(@filename); putc(':')
putc('$'); putb(fileinfo.file_type); putc(' ')
putc('$'); puth(fileinfo:aux_type); putln
return
fin
puts("Usage: +TYPE FILE [HEXTYPE [HEXAUX]]\n")
done

532
src/utilsrc/tftpd.pla Normal file
View File

@@ -0,0 +1,532 @@
//
// TFTP Daemon
//
include "inc/cmdsys.plh"
include "inc/inet.plh"
include "inc/fileio.plh"
include "inc/conio.plh"
//
// TFTP values
//
const TFTP_PORT = 69
const TID_INC = $0010
const RRQ = $0100
const WRQ = $0200
const DATAPKT = $0300
const ACKPKT = $0400
const ERRPKT = $0500
struc t_errPkt
word errOp
word errCode
byte errStr[]
byte errStrNull
end
struc t_ackPkt
word ackOp
word ackBlock
end
struc t_datPkt
word datOp
word datBlock
byte datBytes[]
end
res[t_errPkt] tftpError = $00, $05, $00, $00, $00
res[t_ackPkt] tftpAck = $00, $04, $00, $00
//
// Current file operations
//
byte ref, type, , netscii, filename[256]
word aux, block
word buff, TID = $1001
word portTFTP, portTID
//
// Swap bytes in word
//
asm swab(val)
!SOURCE "vmsrc/plvmzp.inc"
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
STY ESTKL,X
RTS
end
//
// Translate 'in' value to 'out' value
//
asm xlat(in, out, buf, len)#0
INX
INX
INX
INX
LDA ESTKL-4,X
ORA ESTKH-4,X
BEQ XLATEX
LDA ESTKL-3,X
STA SRCL
LDA ESTKH-3,X
STA SRCH
LDA ESTKL-1,X
LDY ESTKL-4,X
BEQ XLATLP
INC ESTKH-4,X
LDY #$00
XLATLP CMP (SRC),Y
BNE +
LDA ESTKL-2,X
STA (SRC),Y
LDA ESTKL-1,X
+ INY
BNE +
INC DSTH
INC SRCH
+ DEC ESTKL-4,X
BNE XLATLP
DEC ESTKH-4,X
BNE XLATLP
XLATEX RTS
end
//
// Convert byte to two hex chars
//
def btoh(cptr, b)#0
byte h
h = ((b >> 4) & $0F) + '0'
if h > '9'
h = h + 7
fin
^cptr = h
cptr++
h = (b & $0F) + '0'
if h > '9'
h = h + 7
fin
^cptr = h
end
def hexByte(hexChars)
byte lo, hi
lo = toupper(^(hexChars + 1)) - '0'
if lo > 9
lo = lo - 7
fin
hi = toupper(^hexChars) - '0'
if hi > 9
hi = hi - 7
fin
return (hi << 4) | lo
end
def hexWord(hexChars)
return (hexByte(hexChars) << 8) | hexByte(hexChars + 2)
end
def mkProName(netName, proName)#3
byte n, l, ascii, proType
word proAux
proType = $02 // default to BIN
proAux = $0000 // default to 0
//
// Check for CiderPress style extension
//
for l = 0 to 255
if netName->[l] == 0; break; fin
next
ascii = toupper(netName->[l + 1]) == 'N' // Netscii mode
if l > 7 and ^(netName + l - 7) == '#'
proType = hexByte(netName + l - 6)
proAux = hexWord(netName + l - 4)
l = l - 7
fin
memcpy(proName + 1, netName, l)
^proName = l
return ascii, proType, proAux
end
def mkNetName(proName, netName)
word l, n
byte fileinfo[t_fileinfo]
if !fileio:getfileinfo(proName, @fileinfo)
//
// Scan backward looking for dir seperator
//
l = ^proName
for n = l downto 1
if ^(proName + n) == '/'
break
fin
next
memcpy(netName + 1, proName + 1 + n, l - n)
^netName = l - n + 7
//
// Build CiderPress style extension
//
n = netName + ^netName - 6
^n = '#'
btoh(n + 1, fileinfo.file_type)
btoh(n + 3, fileinfo.aux_type.1)
btoh(n + 5, fileinfo.aux_type)
else
//
// Error getting info on file
//
puts("Error reading "); puts(proName); putln
return -1
fin
return 0
end
def readUDP(ipsrc, portsrc, data, len, param)
word err
err = 0
when *data
is $0500 // Error
err = *data
is $0400 // Ack
if swab(data=>ackBlock) <> block
puts("RRQ: Out-of-sequence block\n")
err = $0800 // Out-of-sequence block
break
fin
if param == 512 // Size of initial read
param = fileio:read(ref, buff+datBytes, 512)
if type == $04 // TXT type
xlat($0D, $0A, buff+datBytes, param)
fin
block++
buff=>datBlock = swab(block)
iNet:sendUDP(portTID, ipsrc, portsrc, buff, t_datPkt + param)
fin
if err
tftpError:errCode = err
iNet:sendUDP(portTID, ipsrc, portsrc, @tftpError, t_errPkt)
fin
if param < 512 or err
//
// All done
//
iNet:closeUDP(portTID)
fileio:close(ref)
ref = 0
fin
break
otherwise
puts("TFTP: RRQ Unexpected packet opcode: $"); puth(*data); putln
wend
return 0
end
def writeUDP(ipsrc, portsrc, data, len, param)
word err
err = 0
when *data
is $0300 // Data packet
if swab(data=>datBlock) <> block
puts("WRQ: Out-of-sequence block\n")
err = $0800 // Out-of-sequence block
break
fin
len = len - t_datPkt
if type == $04 // TXT type
xlat($0A, $0D, data+datBytes, len)
fin
if fileio:write(ref, data+datBytes, len) <> len
puts("WRQ: File write error\n")
tftpError:errCode = $0300 // Disk full error
break
fin
if not err
tftpAck:ackBlock = swab(block)
block++
iNet:sendUDP(portTID, ipsrc, portsrc, @tftpAck, t_ackPkt)
else
tftpError:errCode = err
iNet:sendUDP(portTID, ipsrc, portsrc, @tftpError, t_errPkt)
fin
if len < 512 or err
//
// All done
//
iNet:closeUDP(portTID)
fileio:close(ref)
ref = 0
fin
break
otherwise
puts("WRQ: Unexpected packet opcode: $"); puth(*data); putln
wend
return 0
end
def servUDP(ipsrc, portsrc, data, len, param)
byte info[24]
byte l, prefix[48]
when *data
is RRQ // Read request
//
// Initiate file read
//
if ref
//
// File already open and active
//
tftpError:errCode = $0300 // Allocation exceeded
iNet:sendUDP(portTFTP, ipsrc, portsrc, @tftpError, t_errPkt)
return 0
fin
//
// Extract filename
//
netscii, type, aux = mkProName(data + 2, @filename)
ref = fileio:open(@filename)
if not ref
puts("Error opening file: "); puts(@filename)
puts(", Error: "); putb(perr); putln
tftpError:errCode = $0100 // File not found
iNet:sendUDP(portTFTP, ipsrc, portsrc, @tftpError, t_errPkt)
return 0
fin
info.0 = $0A
info:1 = @filename
syscall($C4, @info)
type = info.4
puts("Reading file: "); puts(@filename); putln
TID = (TID + TID_INC) | $1000
block = 1
buff=>datBlock = swab(block)
len = fileio:read(ref, buff+datBytes, 512)
if type == $04 // TXT type
xlat($0D, $0A, buff+datBytes, 512)
fin
portTID = iNet:openUDP(TID, @readUDP, len)
iNet:sendUDP(portTID, ipsrc, portsrc, buff, t_datPkt + len)
break
is WRQ // Write request
//
// Initiate file write
//
if ref
//
// File already open and active
//
tftpError:errCode = $0300 // Allocation exceeded
iNet:sendUDP(portTFTP, ipsrc, portsrc, @tftpError, t_errPkt)
return 0
fin
//
// Extract filename
//
netscii, type, aux = mkProName(data + 2, @filename)
//
// Scan filename prefix and create
//
prefix[1] = filename[1]
for l = 2 to filename[0]
if filename[l] == '/'
prefix[0] = l-1
fileio:create(@prefix, $0F, $0000)
fin
prefix[l] = filename[l]
next
fileio:destroy(@filename)
if fileio:create(@filename, type, aux)
puts("Create file error: "); putb(perr); putln
fin
ref = fileio:open(@filename)
if not ref
puts("Error opening file: "); puts(@filename)
puts(", Error: "); putb(perr); putln
tftpError:errCode = $0200 // Access violation
iNet:sendUDP(portTFTP, ipsrc, portsrc, @tftpError, t_errPkt)
return 0
fin
puts("Writing file: "); puts(@filename); putln
TID = (TID + TID_INC) | $1000
block = 1
tftpAck:ackBlock = 0
portTID = iNet:openUDP(TID, @writeUDP, 0)
iNet:sendUDP(portTID, ipsrc, portsrc, @tftpAck, t_ackPkt)
break
otherwise
puts("TFTP: Server Unexpected packet opcode: $"); puth(*data); putln
wend
return 0
end
def volumes#0
word strbuf
byte i
strbuf = heapmark()
fileio:online(0, strbuf)
for i = 0 to 15
^strbuf = ^strbuf & $0F
if ^strbuf
putc('/'); puts(strbuf); putln()
fin
strbuf = strbuf + 16
next
end
puts("TFTP Server Version 2.0 Dev\n")
if !iNet:initIP()
return -1
fin
puts("Online volumes:\n"); volumes()
portTFTP = iNet:openUDP(TFTP_PORT, @servUDP, 0)
//
// Alloc aligned file/io buffers
//
buff = heapalloc(t_datPkt + 512)
buff=>datOp = $0300 // Data op
//
// Service IP
//
repeat
iNet:serviceIP()
until conio:keypressed()
getc // eat keypress
done
Experpts from: RFC 1350, TFTP Revision 2, July 1992
TFTP Formats
Type Op # Format without header
2 bytes string 1 byte string 1 byte
-----------------------------------------------
RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
WRQ -----------------------------------------------
2 bytes 2 bytes n bytes
---------------------------------
DATA | 03 | Block # | Data |
---------------------------------
2 bytes 2 bytes
-------------------
ACK | 04 | Block # |
--------------------
2 bytes 2 bytes string 1 byte
----------------------------------------
ERROR | 05 | ErrorCode | ErrMsg | 0 |
----------------------------------------
Initial Connection Protocol for reading a file
1. Host A sends a "RRQ" to host B with source= A's TID,
destination= 69.
2. Host B sends a "DATA" (with block number= 1) to host A with
source= B's TID, destination= A's TID.
Error Codes
Value Meaning
0 Not defined, see error message (if any).
1 File not found.
2 Access violation.
3 Disk full or allocation exceeded.
4 Illegal TFTP operation.
5 Unknown transfer ID.
6 File already exists.
7 No such user.
Internet User Datagram Header [2]
(This has been included only for convenience. TFTP need not be
implemented on top of the Internet User Datagram Protocol.)
Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Values of Fields
Source Port Picked by originator of packet.
Dest. Port Picked by destination machine (69 for RRQ or WRQ).
Length Number of bytes in UDP packet, including UDP header.
Checksum Reference 2 describes rules for computing checksum.
(The implementor of this should be sure that the
correct algorithm is used here.)
Field contains zero if unused.
Note: TFTP passes transfer identifiers (TID's) to the Internet User
Datagram protocol to be used as the source and destination ports.
A transfer is established by sending a request (WRQ to write onto a
foreign file system, or RRQ to read from it), and receiving a
positive reply, an acknowledgment packet for write, or the first data
packet for read. In general an acknowledgment packet will contain
the block number of the data packet being acknowledged. Each data
packet has associated with it a block number; block numbers are
consecutive and begin with one. Since the positive response to a
write request is an acknowledgment packet, in this special case the
block number will be zero. (Normally, since an acknowledgment packet
is acknowledging a data packet, the acknowledgment packet will
contain the block number of the data packet being acknowledged.) If
the reply is an error packet, then the request has been denied.
In order to create a connection, each end of the connection chooses a
TID for itself, to be used for the duration of that connection. The
TID's chosen for a connection should be randomly chosen, so that the
probability that the same number is chosen twice in immediate
succession is very low. Every packet has associated with it the two
TID's of the ends of the connection, the source TID and the
destination TID. These TID's are handed to the supporting UDP (or
other datagram protocol) as the source and destination ports. A
requesting host chooses its source TID as described above, and sends
its initial request to the known TID 69 decimal (105 octal) on the
serving host. The response to the request, under normal operation,
uses a TID chosen by the server as its source TID and the TID chosen
for the previous message by the requestor as its destination TID.
The two chosen TID's are then used for the remainder of the transfer.
As an example, the following shows the steps used to establish a
connection to write a file. Note that WRQ, ACK, and DATA are the
names of the write request, acknowledgment, and data types of packets
respectively. The appendix contains a similar example for reading a
file.
1. Host A sends a "WRQ" to host B with source= A's TID,
destination= 69.
2. Host B sends a "ACK" (with block number= 0) to host A with
source= B's TID, destination= A's TID.
At this point the connection has been established and the first data
packet can be sent by Host A with a sequence number of 1. In the
next step, and in all succeeding steps, the hosts should make sure
that the source TID matches the value that was agreed on in steps 1
and 2. If a source TID does not match, the packet should be
discarded as erroneously sent from somewhere else. An error packet
should be sent to the source of the incorrect packet, while not
disturbing the transfer. This can be done only if the TFTP in fact
receives a packet with an incorrect TID. If the supporting protocols
do not allow it, this particular error condition will not arise.
The following example demonstrates a correct operation of the
protocol in which the above situation can occur. Host A sends a
request to host B. Somewhere in the network, the request packet is
duplicated, and as a result two acknowledgments are returned to host
A, with different TID's chosen on host B in response to the two
requests. When the first response arrives, host A continues the
connection. When the second response to the request arrives, it
should be rejected, but there is no reason to terminate the first
connection. Therefore, if different TID's are chosen for the two
connections on host B and host A checks the source TID's of the
messages it receives, the first connection can be maintained while
the second is rejected by returning an error packet.

View File

@@ -40,7 +40,7 @@ predef sext(a)#1, divmod(a,b)#2, execmod(modfile)#1
//
// Exported CMDSYS table
//
word version = $0110 // 01.10
word version = $0200 // 02.00
word syspath
word syscmdln
word = @execmod
@@ -52,7 +52,7 @@ byte perr, refauto
// String pool.
//
byte autorun[] = "AUTORUN"
byte verstr[] = "\nPLASMA "
byte verstr[] = "\nPLASMA DP2"
byte freestr[] = "MEM FREE:$"
byte errorstr[] = "ERR:$"
byte prompt[] = "PLASMA"

View File

@@ -1,6 +1,5 @@
const MACHID = $BF98
const iobuffer = $0800
const databuff = $2000
const RELADDR = $1000
const symtbl = $0C00
const freemem = $0006
@@ -34,14 +33,17 @@ predef crout()#0, cout(c)#0, prstr(s)#0, prbyte(b)#0, prword(w)#0, print(i)#0, c
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, 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, sext(a)#1, divmod(a,b)#2
predef execmod(modfile)#1
predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buff, len)#1, write(refnum, buff, len)#1
//
// Exported CMDSYS table
//
word version = $0110 // 01.10
word version = $0200 // 02.00 Dev
word syspath
word syscmdln
word = @execmod
word = @execmod, @open, @close, @read, @write
byte perr
byte jitcount = 0
byte jitsize = 0
//
// Working input buffer overlayed with strings table
//
@@ -117,22 +119,13 @@ word sysmodsym = @exports
// System variable.
//
word systemflags = 0
byte perr
word heap
word xheap = $0800
word lastsym = symtbl
//
// Utility functions
//
//asm equates included from cmdstub.s
//
asm saveX#0
STX XREG+1
end
asm restoreX#0
XREG LDX #$00
RTS
end
// CALL PRODOS
// SYSCALL(CMD, PARAMS)
//
@@ -202,14 +195,6 @@ asm exec()#0
JMP $2000
end
//
// EXIT
//
asm reboot()#0
BIT ROMEN
DEC $03F4 ; INVALIDATE POWER-UP BYTE
JMP ($FFFC) ; RESET
end
//
// SET MEMORY TO VALUE
// MEMSET(ADDR, VALUE, SIZE)
// With optimizations from Peter Ferrie
@@ -323,36 +308,6 @@ REVCPYLP LDA (SRC),Y
BNE REVCPYLP
CPYMEX RTS
end
//
// COPY FROM MAIN MEM TO AUX MEM.
//
// MEMXCPY(DST, SRC, SIZE)
//
asm memxcpy(dst,src,size)#0
LDA ESTKL+1,X
STA $3C
CLC
ADC ESTKL,X
STA $3E
LDA ESTKH+1,X
STA $3D
ADC ESTKH,X
STA $3F
LDA ESTKL+2,X
STA $42
LDA ESTKH+2,X
STA $43
STX ESP
BIT ROMEN
SEC
JSR $C311
BIT LCRDEN+LCBNK2
LDX ESP
INX
INX
INX
RTS
end
asm crout()#0
LDA #$8D
BNE ++
@@ -898,6 +853,17 @@ def read(refnum, buff, len)#1
perr = syscall($CA, @params)
return params:6
end
def write(refnum, buf, len)#1
byte params[8]
params.0 = 4
params.1 = refnum
params:2 = buf
params:4 = len
params:6 = 0
perr = syscall($CB, @params)
return params:6
end
//
// Heap routines.
//
@@ -906,9 +872,10 @@ def availheap()#1
return @fp - heap
end
def allocheap(size)#1
word addr
addr = heap
heap = heap + size
word oldheap, addr
oldheap = heap
addr = heap
heap = heap + size
if systemflags & reshgr1
if uword_islt(addr, $4000) and uword_isgt(heap, $2000)
addr = $4000
@@ -922,6 +889,7 @@ def allocheap(size)#1
fin
fin
if uword_isge(heap, @addr)
heap = oldheap
return 0
fin
return addr
@@ -946,39 +914,6 @@ def releaseheap(newheap)#1
heap = newheap
return @newheap - heap
end
def allocxheap(size)#1
word xaddr
xaddr = xheap
xheap = xheap + size
if systemflags & restxt1
if uword_isle(xaddr, $0800) and uword_isgt(xheap, $0400)
xaddr = $0800
xheap = xaddr + size
fin
fin
if systemflags & restxt2
if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800)
xaddr = $0C00
xheap = xaddr + size
fin
fin
if systemflags & resxhgr1
if uword_isle(xaddr, $4000) and uword_isgt(xheap, $2000)
xaddr = $4000
xheap = xaddr + size
fin
fin
if systemflags & resxhgr2
if uword_isle(xaddr, $6000) and uword_isgt(xheap, $4000)
xaddr = $6000
xheap = xaddr + size
fin
fin
if uword_isge(xheap, $BF00)
return 0
fin
return xaddr
end
//
// Symbol table routines.
//
@@ -1024,35 +959,42 @@ def lookupextern(esd, index)#1
fin
return 0
end
def adddef(bank, addr, deflast)#1
def adddef(addr, deflast)#1
word defentry
defentry = *deflast
*deflast = defentry + 5
defentry->0 = $20
defentry=>1 = bank ?? $03DC :: $03D6 // JSR $03DC (AUX MEM INTERP) or $03D6 (MAIN MEM INTERP)
defentry=>1 = $03D6
defentry=>3 = addr
defentry->5 = 0 // NULL out next entry
return defentry
end
def loadmod(mod)#1
word rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup
word rdlen, modsize, bytecode, codefix, defofst, defcnt, init, initcode[], fixup
word addr, defaddr, modaddr, modfix, modofst, modend
word deftbl, deflast
word moddep, rld, esd, sym
byte refnum, defbank, str[16], filename[64]
byte refnum, filename[64], str[]
byte header[128]
//
// Read the RELocatable module header (first 128 bytes)
//
dcitos(mod, @filename)
refnum = open(@filename)
if !refnum
if !refnum and filename < 16
//
// Try system path
//
refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
fin
if refnum
header.0 = $0A
header:1 = @filename
if not syscall($C4, @header) and header.4 <> $FE // Make sure it's a REL module
close(refnum)
perr = $4A // Incompatible type
return -perr
fin
rdlen = read(refnum, @header, 128)
modsize = header:0
moddep = @header.1
@@ -1129,17 +1071,7 @@ def loadmod(mod)#1
esd = esd + 4
loop
esd = esd + 1
//
// Locate bytecode defs in appropriate bank.
//
if ^MACHID & $30 == $30
defbank = 1
defaddr = allocxheap(rld - bytecode)
modend = bytecode
else
defbank = 0
defaddr = bytecode
fin
defaddr = bytecode
codefix = defaddr - bytecode
defofst = defaddr - defofst
//
@@ -1149,7 +1081,7 @@ def loadmod(mod)#1
//
// This is a bytcode def entry - add it to the def directory.
//
adddef(defbank, rld=>1 + defofst, @deflast)
adddef(rld=>1 + defofst, @deflast)
rld = rld + 4
loop
//
@@ -1161,31 +1093,6 @@ def loadmod(mod)#1
*addr = ^rld & $10 ?? *addr + lookupextern(esd, rld->3) :: lookupdef(fixup + codefix, deftbl)
rld = rld + 4
fin
//addr = rld=>1 + modfix
//if uword_isge(addr, modaddr) // Skip fixups to header
// if type & $80 // WORD sized fixup.
// fixup = *addr
// else // BYTE sized fixup.
// fixup = ^addr
// fin
// if ^rld & $10 // EXTERN reference.
// fixup = fixup + lookupextern(esd, rld->3)
// else // INTERN fixup.
// fixup = fixup + modofst
// if uword_isge(fixup, bytecode)
// //
// // Bytecode address - replace with call def directory.
// //
// fixup = lookupdef(fixup + codefix, deftbl)
// fin
// fin
// if type & $80 // WORD sized fixup.
// *addr = fixup
// else // BYTE sized fixup.
// ^addr = fixup
// fin
//fin
//rld = rld + 4
loop
//
// Run through the External/Entry Symbol Directory.
@@ -1208,47 +1115,36 @@ def loadmod(mod)#1
fin
esd = esd + 3
loop
if defbank
//
// Move bytecode to AUX bank.
//
memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr))
fin
else
perr = $46
fin
if perr
return -perr
fin
//
// Free up rld+esd (and bytecode on 128K) in main memory.
// Free up rld+esd in main memory.
//
releaseheap(modend)
//
// Call init routine if it exists.
//
fixup = 0 // This is repurposed for the return code
initcode = 0
if init
init = init + defofst
fixup = adddef(defbank, init, @deflast)()
if fixup < modinitkeep
init = init + defofst
initcode = adddef(init, @deflast)()
if initcode < modinitkeep
//
// Free init routine unless initkeep
//
if defbank
xheap = init
else
//
// Free up init code in main memory.
//
releaseheap(init)
fin
if fixup < 0
perr = -fixup
releaseheap(init)
if initcode < 0
perr = -initcode
fin
else
fixup = fixup & ~modinitkeep
initcode = initcode & ~modinitkeep
fin
fin
return fixup
return initcode
end
//
// Command mode
@@ -1260,9 +1156,9 @@ def volumes()#0
params.0 = 2
params.1 = 0
params:2 = databuff
params:2 = heap
perr = syscall($C5, @params)
strbuf = databuff
strbuf = heap
for i = 0 to 15
^strbuf = ^strbuf & $0F
if ^strbuf
@@ -1287,19 +1183,17 @@ def catalog(path)#0
fin
firstblk = 1
repeat
if read(refnum, databuff, 512) == 512
entry = databuff + 4
if read(refnum, heap, 512) == 512
entry = heap + 4
if firstblk
entrylen = databuff.$23
entriesblk = databuff.$24
filecnt = databuff:$25
entrylen = heap->$23
entriesblk = heap->$24
filecnt = heap=>$25
entry = entry + entrylen
fin
for i = firstblk to entriesblk
type = ^entry
if type
len = type & $0F
^entry = len
if ^entry
^entry = ^entry & $0F
prstr(entry)
type = ' '
when entry->$10
@@ -1313,7 +1207,7 @@ def catalog(path)#0
type = '+'
wend
cout(type)
for len = 18 - len downto 0
for len = ^entry to 18
cout(' ')
next
filecnt--
@@ -1369,10 +1263,13 @@ def parsecmd(strptr)#1
return cmd
end
def resetmemfiles()#0
byte terr
terr = perr // Save perr
//
// Close all files
//
^$BFD8 = 0
^$BF94 = 0
close(0)
//
// Set memory bitmap
@@ -1380,6 +1277,7 @@ def resetmemfiles()#0
memset($BF58, 0, 24)
^$BF58 = $CF
^$BF6F = $01
perr = terr // Restore perr
end
def execsys(sysfile)#0
byte refnum
@@ -1390,7 +1288,7 @@ def execsys(sysfile)#0
striptrail(sysfile)
refnum = open(sysfile)
if refnum
len = read(refnum, databuff, $FFFF)
len = read(refnum, $2000, $FFFF)
resetmemfiles()
if len
strcpy(sysfile, $280)
@@ -1408,17 +1306,15 @@ def execsys(sysfile)#0
end
def execmod(modfile)#1
byte moddci[17]
word saveheap, savexheap, savesym, saveflags
word saveheap, savesym, saveflags
perr = 1
if stodci(modfile, @moddci)
saveheap = heap
savexheap = xheap
savesym = lastsym
saveflags = systemflags
if loadmod(@moddci) < modkeep
lastsym = savesym
xheap = savexheap
heap = saveheap
fin
^lastsym = 0
@@ -1427,13 +1323,67 @@ def execmod(modfile)#1
return -perr
end
//
// Command line processor
//
def docmds#0
strcpy(getlnbuf, @cmdln)
while 1
if ^getlnbuf
strcpy(@cmdln, getlnbuf)
when toupper(parsecmd(getlnbuf))
is 'C'
catalog(getlnbuf)
break
is 'P'
pfxop(getlnbuf, SET_PFX)
break
is '/'
repeat
prefix--
until prefix[prefix] == '/'
if prefix > 1
pfxop(@prefix, SET_PFX)
fin
break
is 'V'
volumes()
break
is '-'
execsys(getlnbuf)
break
is '+'
execmod(striptrail(getlnbuf))
//
// Clean up
//
resetmemfiles
break
otherwise
cout('?')
wend
if perr
prstr("ERR:$")
prbyte(perr)
crout()
fin
fin
prstr(pfxop(@prefix, GET_PFX))
rdstr($BA)
loop
end
//
// Dummy definition to get free heap
//
def lastdef#0
end
//
// Get heap start.
//
heap = *freemem
heap = @lastdef
//
// Print PLASMA version
//
prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
prstr("PLASMA 2.0 DP2 64K\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout
//
// Init symbol table.
//
@@ -1445,15 +1395,15 @@ loop
//
// Set system path
//
strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
strcat(strcpy(@sysmods, $300), "SYS/")) // This is the path to CMD
syspath = @sysmods // Update external interface table
syscmdln = @cmdln
//
// Try to load autorun.
//
autorun = open(@autorun)
if autorun > 0
cmdln = read(autorun, @autorun, 128)
if autorun
cmdln = read(autorun, @cmdln+1, 81)
close(0)
else
//
@@ -1461,55 +1411,6 @@ else
//
prstr("MEM FREE:$"); prword(availheap); crout
fin
perr = 0
while 1
if ^getlnbuf
when toupper(parsecmd(getlnbuf))
is 'Q'
reboot()
break
is 'C'
catalog(getlnbuf)
break
is 'P'
pfxop(getlnbuf, SET_PFX)
break
is '/'
repeat
prefix--
until prefix[prefix] == '/'
if prefix > 1
pfxop(@prefix, SET_PFX)
fin
break
is 'V'
volumes()
break
is '-'
execsys(getlnbuf)
break
is '+'
saveX
execmod(striptrail(getlnbuf))
//
// Clean up
//
restoreX
resetmemfiles
break
otherwise
cout('?')
wend
if perr
prstr("ERR:$")
prbyte(perr)
perr = 0
else
prstr("OK")
fin
crout()
fin
prstr(pfxop(@prefix, GET_PFX))
strcpy(@cmdln, rdstr($BA))
loop
pfxop(@prefix, GET_PFX)
docmds
done

1493
src/vmsrc/apple/cmdjit.pla Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
INTERP = $03D0
LCRDEN = $C080
LCWTEN = $C081
ROMEN = $C082
LCRWEN = $C083
LCBNK2 = $00
LCBNK1 = $08
JITCOMP = $03E2
JITCODE = $03E4
!SOURCE "vmsrc/plvmzp.inc"
JMP CMDMOVE
_CMDBEGIN = *
!PSEUDOPC $1000 {
!SOURCE "vmsrc/apple/cmdjit.a"
_CMDEND = *
}
;*
;* MOVE CMD DOWN TO $1000-$2000
;*
CMDMOVE LDA #<_CMDBEGIN
STA SRCL
LDA #>_CMDBEGIN
STA SRCH
LDY #$00
STY DSTL
LDX #$10
STX DSTH
INX
- LDA (SRC),Y
STA (DST),Y
INY
BNE -
INC SRCH
INC DSTH
DEX ; STOP WHEN DST=$2000 REACHED
BNE -
;
; INIT VM ENVIRONMENT STACK POINTERS
;
STY $01FF
STY PPL
STY IFPL ; INIT FRAME POINTER = $AF00 (4K FOR JIT CODE)
STY JITCODE
STY JITCOMP
STY JITCOMP+1
LDA #$AF
STA PPH
STA IFPH
STA JITCODE+1
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
TXS
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
JMP $1000

View File

@@ -1,48 +1,43 @@
INTERP = $03D0
LCRDEN = $C080
LCWTEN = $C081
ROMEN = $C082
LCRWEN = $C083
LCBNK2 = $00
LCBNK1 = $08
INTERP = $03D0
LCRDEN = $C080
LCWTEN = $C081
ROMEN = $C082
LCRWEN = $C083
LCBNK2 = $00
LCBNK1 = $08
!SOURCE "vmsrc/plvmzp.inc"
;*
;* MOVE CMD DOWN TO $1000-$2000
;*
LDA #<_CMDBEGIN
STA SRCL
LDA #>_CMDBEGIN
STA SRCH
LDY #$00
STY DSTL
LDX #$10
STX DSTH
- LDA (SRC),Y
STA (DST),Y
INY
BNE -
INC SRCH
INC DSTH
DEX ; STOP WHEN DST=$2000 REACHED
BNE -
LDA #<_CMDEND
STA SRCL
LDA #>_CMDEND
STA SRCH
LDA #<_CMDBEGIN
STA SRCL
LDA #>_CMDBEGIN
STA SRCH
LDY #$00
STY DSTL
LDX #$10
STX DSTH
- LDA (SRC),Y
STA (DST),Y
INY
BNE -
INC SRCH
INC DSTH
DEX ; STOP WHEN DST=$2000 REACHED
BNE -
;
; INIT VM ENVIRONMENT STACK POINTERS
;
STY PPL
STY IFPL ; INIT FRAME POINTER
LDA #$BF
STA PPH
STA IFPH
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
TXS
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
JMP $1000
STY $01FF
STY IFPL ; INIT FRAME POINTER = $BF00
LDA #$BF
STA IFPH
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
TXS
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
JMP $1000
_CMDBEGIN = *
!PSEUDOPC $1000 {
!SOURCE "vmsrc/apple/cmd.a"
!PSEUDOPC $1000 {
!SOURCE "vmsrc/apple/cmd.a"
_CMDEND = *
}

View File

@@ -33,7 +33,7 @@ INTERP PLA
PLA
ADC #$00
STA IPH
LDY #$00
LDY #$01
JMP FETCHOP
;*
;* ENTER INTO USER BYTECODE INTERPRETER
@@ -109,14 +109,19 @@ COMP LDA #$FF
;* OPCODE TABLE
;*
!ALIGN 255,0
OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
!WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E
!WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E
!WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
!WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
!WORD BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E
!WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
!WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E
OPTBL !WORD ZERO,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E
!WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E
!WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E
!WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E
!WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
!WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E
!WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
!WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E
!WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E
!WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E
!WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE
!WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE
!WORD NATV ; C0
;*
;* DIV TOS-1 BY TOS
;*
@@ -324,31 +329,6 @@ SHR STY IPY
+ LDY IPY
JMP DROP
;*
;* LOGICAL AND
;*
LAND LDA ESTKL+1,X
ORA ESTKH+1,X
BEQ ++
LDA ESTKL,X
ORA ESTKH,X
BEQ +
LDA #$FF
+ STA ESTKL+1,X
STA ESTKH+1,X
++ JMP DROP
;*
;* LOGICAL OR
;*
LOR LDA ESTKL,X
ORA ESTKH,X
ORA ESTKL+1,X
ORA ESTKH+1,X
BEQ +
LDA #$FF
STA ESTKL+1,X
STA ESTKH+1,X
+ JMP DROP
;*
;* DUPLICATE TOS
;*
DUP DEX
@@ -358,23 +338,73 @@ DUP DEX
STA ESTKH,X
JMP NEXTOP
;*
;* ADD IMMEDIATE TO TOS
;*
ADDI INY ;+INC_IP
LDA (IP),Y
CLC
ADC ESTKL,X
STA ESTKL,X
BCC +
INC ESTKH,X
+ JMP NEXTOP
;*
;* SUB IMMEDIATE FROM TOS
;*
SUBI INY ;+INC_IP
LDA ESTKL,X
SEC
SBC (IP),Y
STA ESTKL,X
BCS +
DEC ESTKH,X
+ JMP NEXTOP
;*
;* AND IMMEDIATE TO TOS
;*
ANDI INY ;+INC_IP
LDA (IP),Y
AND ESTKL,X
STA ESTKL,X
LDA #$00
STA ESTKH,X
JMP NEXTOP
;*
;* IOR IMMEDIATE TO TOS
;*
ORI INY ;+INC_IP
LDA (IP),Y
ORA ESTKL,X
STA ESTKL,X
JMP NEXTOP
;*
;* LOGICAL NOT
;*
LNOT LDA ESTKL,X
ORA ESTKH,X
BNE +
LDA #$FF
BEQ +
LDA #$00
STA ESTKL,X
STA ESTKH,X
JMP NEXTOP
;*
;* CONSTANT
;* CONSTANT -1, ZERO, NYBBLE, BYTE, $FF BYTE, WORD (BELOW)
;*
ZERO DEX
+ LDA #$00
MINUS1 DEX
+ LDA #$FF
STA ESTKL,X
STA ESTKH,X
JMP NEXTOP
ZERO DEX
STA ESTKL,X
STA ESTKH,X
JMP NEXTOP
CN DEX
LSR ; A = CONST * 2
STA ESTKL,X
LDA #$00
STA ESTKH,X
JMP NEXTOP
CFFB LDA #$FF
!BYTE $2C ; BIT $00A9 - effectively skips LDA #$00, no harm in reading this address
CB LDA #$00
@@ -476,7 +506,7 @@ LLA INY ;+INC_IP
;*
;* LOAD VALUE FROM LOCAL FRAME OFFSET
;*
LLB INY ;+INC_IP
_LLB INY ;+INC_IP
LDA (IP),Y
STY IPY
TAY
@@ -486,8 +516,8 @@ LLB INY ;+INC_IP
LDA #$00
STA ESTKH,X
LDY IPY
JMP NEXTOP
LLW INY ;+INC_IP
RTS
_LLW INY ;+INC_IP
LDA (IP),Y
STY IPY
TAY
@@ -498,11 +528,29 @@ LLW INY ;+INC_IP
LDA (IFP),Y
STA ESTKH,X
LDY IPY
RTS
LLB JSR _LLB
JMP NEXTOP
LLW JSR _LLW
JMP NEXTOP
;*
;* ADD VALUE FROM LOCAL FRAME OFFSET
;*
ADDLB JSR _LLB
JMP ADD
ADDLW JSR _LLW
JMP ADD
;*
;* INDEX VALUE FROM LOCAL FRAME OFFSET
;*
IDXLB JSR _LLB
JMP IDXW
IDXLW JSR _LLW
JMP IDXW
;*
;* LOAD VALUE FROM ABSOLUTE ADDRESS
;*
LAB INY ;+INC_IP
_LAB INY ;+INC_IP
LDA (IP),Y
STA ESTKH-2,X
INY ;+INC_IP
@@ -513,8 +561,8 @@ LAB INY ;+INC_IP
STA ESTKL,X
LDA #$00
STA ESTKH,X
JMP NEXTOP
LAW INY ;+INC_IP
RTS
_LAW INY ;+INC_IP
LDA (IP),Y
STA TMPL
INY ;+INC_IP
@@ -529,7 +577,25 @@ LAW INY ;+INC_IP
LDA (TMP),Y
STA ESTKH,X
LDY IPY
RTS
LAB JSR _LAB
JMP NEXTOP
LAW JSR _LAW
JMP NEXTOP
;*
;* ADD VALUE FROM ABSOLUTE ADDRESS
;*
ADDAB JSR _LAB
JMP ADD
ADDAW JSR _LAW
JMP ADD
;*
;* INDEX VALUE FROM ABSOLUTE ADDRESS
;*
IDXAB JSR _LAB
JMP IDXW
IDXAW JSR _LAW
JMP IDXW
;*
;* STORE VALUE TO ADDRESS
;*
@@ -551,7 +617,10 @@ SW LDA ESTKL,X
JMP DROP
+ INC ESTKH,X
STA (ESTKH-1,X)
INX
;*
;* DROP2
;*
DROP2 INX
JMP DROP
;*
;* STORE VALUE TO LOCAL FRAME OFFSET
@@ -594,6 +663,8 @@ DLB INY ;+INC_IP
TAY
LDA ESTKL,X
STA (IFP),Y
LDA #$00
STA ESTKH,X
LDY IPY
JMP NEXTOP
DLW INY ;+INC_IP
@@ -654,6 +725,8 @@ DAB INY ;+INC_IP
STA ESTKH-1,X
LDA ESTKL,X
STA (ESTKH-2,X)
LDA #$00
STA ESTKH,X
JMP NEXTOP
DAW INY ;+INC_IP
LDA (IP),Y
@@ -683,7 +756,6 @@ ISTRU LDA #$FF
STA ESTKL+1,X
STA ESTKH+1,X
JMP DROP
;
ISNE LDA ESTKL,X
CMP ESTKL+1,X
BNE ISTRU
@@ -694,7 +766,6 @@ ISFLS LDA #$00
STA ESTKL+1,X
STA ESTKH+1,X
JMP DROP
;
ISGE LDA ESTKL+1,X
CMP ESTKL,X
LDA ESTKH+1,X
@@ -702,9 +773,16 @@ ISGE LDA ESTKL+1,X
BVS +
BPL ISTRU
BMI ISFLS
+ BPL ISFLS
+
- BPL ISFLS
BMI ISTRU
;
ISLE LDA ESTKL,X
CMP ESTKL+1,X
LDA ESTKH,X
SBC ESTKH+1,X
BVS -
BPL ISTRU
BMI ISFLS
ISGT LDA ESTKL,X
CMP ESTKL+1,X
LDA ESTKH,X
@@ -712,31 +790,114 @@ ISGT LDA ESTKL,X
BVS +
BMI ISTRU
BPL ISFLS
+ BMI ISFLS
+
- BMI ISFLS
BPL ISTRU
;
ISLE LDA ESTKL,X
CMP ESTKL+1,X
LDA ESTKH,X
SBC ESTKH+1,X
BVS +
BPL ISTRU
BMI ISFLS
+ BPL ISFLS
BMI ISTRU
;
ISLT LDA ESTKL+1,X
CMP ESTKL,X
LDA ESTKH+1,X
SBC ESTKH,X
BVS +
BVS -
BMI ISTRU
BPL ISFLS
+ BMI ISFLS
BPL ISTRU
;*
;* BRANCHES
;*
SEL INX
TYA ; FLATTEN IP
SEC
ADC IPL
STA TMPL
LDA #$00
TAY
ADC IPH
STA TMPH ; ADD BRANCH OFFSET
LDA (TMP),Y
;CLC ; BETTER NOT CARRY OUT OF IP+Y
ADC TMPL
STA IPL
INY
LDA (TMP),Y
ADC TMPH
STA IPH
DEY
LDA (IP),Y
STA TMPL ; CASE COUNT
INC IPL
BNE CASELP
INC IPH
CASELP LDA ESTKL-1,X
CMP (IP),Y
BEQ +
LDA ESTKH-1,X
INY
SBC (IP),Y
BMI CASEEND
- INY
INY
DEC TMPL
BEQ FIXNEXT
INY
BNE CASELP
INC IPH
BNE CASELP
+ LDA ESTKH-1,X
INY
SBC (IP),Y
BEQ BRNCH
BPL -
CASEEND LDA #$00
STA TMPH
DEC TMPL
LDA TMPL
ASL ; SKIP REMAINING CASES
ROL TMPH
ASL
ROL TMPH
; CLC
ADC IPL
STA IPL
LDA TMPH
ADC IPH
STA IPH
INY
INY
FIXNEXT TYA
LDY #$00
SEC
ADC IPL
STA IPL
BCC +
INC IPH
+ JMP FETCHOP
BRAND LDA ESTKL,X
ORA ESTKH,X
BEQ BRNCH
INX ; DROP LEFT HALF OF AND
BNE NOBRNCH
BROR LDA ESTKL,X
ORA ESTKH,X
BNE BRNCH
INX ; DROP LEFT HALF OF OR
BNE NOBRNCH
BREQ INX
INX
LDA ESTKL-2,X
CMP ESTKL-1,X
BNE NOBRNCH
LDA ESTKH-2,X
CMP ESTKH-1,X
BEQ BRNCH
BNE NOBRNCH
BRNE INX
INX
LDA ESTKL-2,X
CMP ESTKL-1,X
BNE BRNCH
LDA ESTKH-2,X
CMP ESTKH-1,X
BNE BRNCH
BEQ NOBRNCH
BRTRU INX
LDA ESTKH-1,X
ORA ESTKL-1,X
@@ -745,14 +906,6 @@ NOBRNCH INY ;+INC_IP
INY ;+INC_IP
BMI FIXNEXT
JMP NEXTOP
FIXNEXT TYA
LDY #$00
CLC
ADC IPL
STA IPL
BCC +
INC IPH
+ JMP NEXTOP
BRFLS INX
LDA ESTKH-1,X
ORA ESTKL-1,X
@@ -775,58 +928,67 @@ BRNCH TYA ; FLATTEN IP
STA IPH
DEY
JMP FETCHOP
BREQ INX
LDA ESTKL-1,X
;*
;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK
;*
BRGT LDA ESTKL+1,X
CMP ESTKL,X
BNE NOBRNCH
LDA ESTKH-1,X
CMP ESTKH,X
BEQ BRNCH
BNE NOBRNCH
BRNE INX
LDA ESTKL-1,X
CMP ESTKL,X
BNE BRNCH
LDA ESTKH-1,X
CMP ESTKH,X
BEQ NOBRNCH
BNE BRNCH
BRGT INX
LDA ESTKL-1,X
CMP ESTKL,X
LDA ESTKH-1,X
LDA ESTKH+1,X
SBC ESTKH,X
BVS +
BPL NOBRNCH
BMI BRNCH
+ BPL BRNCH
BMI NOBRNCH
BRLT INX
LDA ESTKL,X
CMP ESTKL-1,X
BRLT LDA ESTKL,X
CMP ESTKL+1,X
LDA ESTKH,X
SBC ESTKH-1,X
SBC ESTKH+1,X
BVS +
BPL NOBRNCH
BMI BRNCH
+ BPL BRNCH
+ BMI NOBRNCH
BPL BRNCH
DECBRGE DEC ESTKL,X
LDA ESTKL,X
CMP #$FF
BNE +
DEC ESTKH,X
_BRGE LDA ESTKL,X
+ CMP ESTKL+1,X
LDA ESTKH,X
SBC ESTKH+1,X
BVS +
BPL BRNCH
BMI NOBRNCH
IBRNCH TYA ; FLATTEN IP
INCBRLE INC ESTKL,X
BNE _BRLE
INC ESTKH,X
_BRLE LDA ESTKL+1,X
CMP ESTKL,X
LDA ESTKH+1,X
SBC ESTKH,X
BVS +
BPL BRNCH
BMI NOBRNCH
+ BMI BRNCH
BPL NOBRNCH
SUBBRGE LDA ESTKL+1,X
SEC
SBC ESTKL,X
STA ESTKL+1,X
LDA ESTKH+1,X
SBC ESTKH,X
STA ESTKH+1,X
INX
BNE _BRGE
ADDBRLE LDA ESTKL,X
CLC
ADC IPL
STA TMPL
LDA #$00
TAY
ADC IPH
STA TMPH ; ADD BRANCH OFFSET
LDA TMPL
;CLC ; BETTER NOT CARRY OUT OF IP+Y
ADC ESTKL,X
STA IPL
LDA TMPH
ADC ESTKH,X
STA IPH
JMP DROP
ADC ESTKL+1,X
STA ESTKL+1,X
LDA ESTKH,X
ADC ESTKH+1,X
STA ESTKH+1,X
INX
BNE _BRLE
;*
;* INDIRECT CALL TO ADDRESS (NATIVE CODE)
;*
@@ -846,7 +1008,7 @@ CALL INY ;+INC_IP
LDA (IP),Y
STA TMPH
_CALL TYA
CLC
SEC
ADC IPL
PHA
LDA IPH
@@ -857,7 +1019,7 @@ _CALL TYA
STA IPH
PLA
STA IPL
LDY #$01
LDY #$00
JMP FETCHOP
;*
;* JUMP INDIRECT TRHOUGH TMP
@@ -901,6 +1063,17 @@ LEAVE INY ;+INC_IP
RTS
+ INC IFPH
RET RTS
;*
;* RETURN TO NATIVE CODE
;*
NATV TYA ; FLATTEN IP
SEC
ADC IPL
STA IPL
BCS +
JMP (IP)
+ INC IPH
JMP (IP)
A1CMD !SOURCE "vmsrc/apple/a1cmd.a"
SEGEND = *
VMINIT LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE
@@ -926,7 +1099,7 @@ PAGE0 = *
;*
INX ; DROP
INY ; NEXTOP
LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4
LDA $FFFF,Y ; FETCHOP @ $F1, IP MAPS OVER $FFFF @ $F2
STA OPIDX
JMP (OPTBL)
}

Some files were not shown because too many files have changed in this diff Show More